Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions plugins/serious-reading/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules/
!preload/node_modules/
dist/
.git/
*.log
.env*
137 changes: 137 additions & 0 deletions plugins/serious-reading/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# AGENTS.md

----

## 0. Non-negotiables

These rules override everything else in this file when in conflict:

1. **No flattery, no filler.** Skip openers like "Great question", "You're absolutely right", "Excellent idea", "I'd be happy to". Start with the answer or the action.
2. **Disagree when you disagree.** If the user's premise is wrong, say so before doing the work. Agreeing with false premises to be polite is the single worst failure mode in coding agents.
3. **Never fabricate.** Not file paths, not commit hashes, not API names, not test results, not library functions. If you don't know, read the file, run the command, or say "I don't know, let me check."
4. **Stop when confused.** If the task has two plausible interpretations, ask. Do not pick silently and proceed.
5. **Touch only what you must.** Every changed line must trace directly to the user's request. No drive-by refactors, reformatting, or "while I was in there" cleanups.

---

## 1. Before writing code

**Goal: understand the problem and the codebase before producing a diff.**

- State your plan in one or two sentences before editing. For anything non-trivial, produce a numbered list of steps with a verification check for each.
- Read the files you will touch. Read the files that call the files you will touch. Claude Code: use subagents for exploration so the main context stays clean.
- Match existing patterns in the codebase. If the project uses pattern X, use pattern X, even if you'd do it differently in a greenfield repo.
- Surface assumptions out loud: "I'm assuming you want X, Y, Z. If that's wrong, say so." Do not bury assumptions inside the implementation.
- If two approaches exist, present both with tradeoffs. Do not pick one silently. Exception: trivial tasks (typo, rename, log line) where the diff fits in one sentence.

---

## 2. Writing code: simplicity first

**Goal: the minimum code that solves the stated problem. Nothing speculative.**

- No features beyond what was asked.
- No abstractions for single-use code. No configurability, flexibility, or hooks that were not requested.
- No error handling for impossible scenarios. Handle the failures that can actually happen.
- If the solution runs 200 lines and could be 50, rewrite it before showing it.
- If you find yourself adding "for future extensibility", stop. Future extensibility is a future decision.
- Bias toward deleting code over adding code. Shipping less is almost always better.

The test: would a senior engineer reading the diff call this overcomplicated? If yes, simplify.

---

## 3. Surgical changes

**Goal: clean, reviewable diffs. Change only what the request requires.**

- Do not "improve" adjacent code, comments, formatting, or imports that are not part of the task.
- Do not refactor code that works just because you are in the file.
- Do not delete pre-existing dead code unless asked. If you notice it, mention it in the summary.
- Do clean up orphans created by your own changes (unused imports, variables, functions your edit made obsolete).
- Match the project's existing style exactly: indentation, quotes, naming, file layout.

The test: every changed line traces directly to the user's request. If a line fails that test, revert it.

---

## 4. Goal-driven execution

**Goal: define success as something you can verify, then loop until verified.**

Rewrite vague asks into verifiable goals before starting:

- "Add validation" becomes "Write tests for invalid inputs (empty, malformed, oversized), then make them pass."
- "Fix the bug" becomes "Write a failing test that reproduces the reported symptom, then make it pass."
- "Refactor X" becomes "Ensure the existing test suite passes before and after, and no public API changes."
- "Make it faster" becomes "Benchmark the current hot path, identify the bottleneck with profiling, change it, show the benchmark is faster."

For every task:

1. State the success criteria before writing code.
2. Write the verification (test, script, benchmark, screenshot diff) where practical.
3. Run the verification. Read the output. Do not claim success without checking.
4. If the verification fails, fix the cause, not the test.

---

## 5. Tool use and verification

- Prefer running the code to guessing about the code. If a test suite exists, run it. If a linter exists, run it. If a type checker exists, run it.
- Never report "done" based on a plausible-looking diff alone. Plausibility is not correctness.
- When debugging, address root causes, not symptoms. Suppressing the error is not fixing the error.
- For UI changes, verify visually: screenshot before, screenshot after, describe the diff.
- Use CLI tools (gh, aws, gcloud, kubectl) when they exist. They are more context-efficient than reading docs or hitting APIs unauthenticated.
- When reading logs, errors, or stack traces, read the whole thing. Half-read traces produce wrong fixes.

---

## 6. Session hygiene

- Context is the constraint. Long sessions with accumulated failed attempts perform worse than fresh sessions with a better prompt.
- After two failed corrections on the same issue, stop. Summarize what you learned and ask the user to reset the session with a sharper prompt.
- Use subagents (Claude Code: "use subagents to investigate X") for exploration tasks that would otherwise pollute the main context with dozens of file reads.
- When committing, write descriptive commit messages (subject under 72 chars, body explains the why). No "update file" or "fix bug" commits. No "Co-Authored-By: Claude" attribution unless the project explicitly wants it.

---

## 7. Communication style

- Direct, not diplomatic. "This won't scale because X" beats "That's an interesting approach, but have you considered...".
- Concise by default. Two or three short paragraphs unless the user asks for depth. No padding, no restating the question, no ceremonial closings.
- When a question has a clear answer, give it. When it does not, say so and give your best read on the tradeoffs.
- Celebrate only what matters: shipping, solving genuinely hard problems, metrics that moved. Not feature ideas, not scope creep, not "wouldn't it be cool if".
- No excessive bullet points, no unprompted headers, no emoji. Prose is usually clearer than structure for short answers.

---

## 8. When to ask, when to proceed

**Ask before proceeding when:**

- The request has two plausible interpretations and the choice materially affects the output.
- The change touches something you've been told is load-bearing, versioned, or has a migration path.
- You need a credential, a secret, or a production resource you don't have access to.
- The user's stated goal and the literal request appear to conflict.

**Proceed without asking when:**

- The task is trivial and reversible (typo, rename a local variable, add a log line).
- The ambiguity can be resolved by reading the code or running a command.
- The user has already answered the question once in this session.

---

## 9. Self-improvement loop

**This file is living. Keep it short by keeping it honest.**

After every session where the agent did something wrong:

1. Ask: was the mistake because this file lacks a rule, or because the agent ignored a rule?
2. If lacking: add the rule under "Project Learnings" below, written as concretely as possible ("Always use X for Y" not "be careful with Y").
3. If ignored: the rule may be too long, too vague, or buried. Tighten it or move it up.
4. Every few weeks, prune. For each line, ask: "Would removing this cause the agent to make a mistake?" If no, delete. Bloated AGENTS.md files get ignored wholesale.

Boris Cherny (creator of Claude Code) keeps his team's file around 100 lines. Under 300 is a good ceiling. Over 500 and you are fighting your own config.

52 changes: 52 additions & 0 deletions plugins/serious-reading/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Changelog

本文件记录严肃阅读的版本变更历史。

格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)。

## [1.1.0] - 2026-07-03

### 变更

- 插件名称从 "Serious Reading" 改为 "严肃阅读"(plugin.json title、UI 标题、README、index.html)

### 安全修复

- **XSS 漏洞修复** — EPUB 章节内容的 HTML 清洗从正则替换改为 DOMPurify,防止恶意 EPUB 通过 XSS 载荷读取本地文件 (`src/shared/parser.ts`)

### Bug 修复

- **EPUB 嵌套分页** — 高度测量分页算法改为递归展平嵌套块级元素,修复 EPUB 章节被 `<div>` 包裹时整章塞入一页导致内容截断的问题 (`src/reader/App.tsx`)
- **搜索定位跳转末章** — 搜索结果落在章节标题空隙时不再错误跳转到最后一章,改用下一章节的 charOffset 作为上界判断 (`src/main/components/SearchDialog.tsx`)
- **EPUB 冗余解析** — 打开 EPUB 文件时不再重复调用 `readEpub`,首次解析结果缓存后直接复用提取封面 (`src/main/App.tsx`)
- **preload 全局引用** — `preload/main.js` 和 `preload/reader.js` 中裸 `ztools` 引用改为 `window.ztools`,避免上下文隔离环境下 ReferenceError (`preload/main.js`, `preload/reader.js`)
- **EPUB 章节标题不一致** — 阅读窗 preload 的 `readEpub` 引入 NCX TOC 解析,与主窗 preload 保持一致,不再将所有章节标题硬编码为"第 X 章" (`preload/reader.js`)

## [1.0.0] - 2026-07-03

### 新增

- 字体选择下拉菜单,内置 11 种中英文字体
- 「清理空行」阅读选项,压缩 TXT 连续空行为单个段落间距
- `toggle_reader` 命令(切换阅读窗显隐)
- `reader_open` 文件打开命令,支持拖入 TXT/EPUB/PDF 直接阅读

### 变更

- Logo 由 `logo.png` 更换为 `logo.svg`
- 字体设置从文本输入框改为下拉菜单选择
- TXT 渲染逻辑重构:默认保留原文换行,「清理空行」模式压缩连续空行
- `keepFormat` 设置项重命名为 `cleanEmptyLines`

## [0.1.0] - 2026-06-30

### 新增

- TXT/EPUB/PDF 三格式支持(编码检测、章节解析、PDF canvas 渲染)
- 书架管理(网格书架、封面缩略图、进度展示、最近阅读历史)
- 章节跳转、全文搜索、百分比跳转
- 高度测量自动分页
- 透明留窗(Stealth)伪装模式、真隐藏、三功能触发器自定义
- 自动翻页、阅读窗拖拽/缩放、窗口位置记忆
- 明暗主题、阅读配色、全屏截图取色、排版控制
- React 18 + TypeScript + Vite 双入口架构
83 changes: 83 additions & 0 deletions plugins/serious-reading/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# 严肃阅读

> 一款对待摸鱼阅读很严肃的阅读插件
支持 TXT / EPUB / PDF 三种格式,专为「在工作间隙低调阅读」设计——悬浮透明阅读窗、老板键伪装隐藏、自动翻页、全屏取色配色,让你严肃地摸鱼。

## 快速开始



| 命令 | 说明 |
|------|------|
| `阅读` / `书架` / `serious` | 打开书架 |
| `继续阅读` | 继续上次阅读 |
| `显示阅读器` / `show` | 显示阅读窗 |
| `切换阅读器` / `toggle` | 切换阅读窗显隐 |
| 拖入 TXT/EPUB/PDF 文件 | 直接打开阅读 |

## 阅读体验

- **三格式支持** — TXT(自动编码检测,GBK/UTF-8/UTF-16 均可)、EPUB(自动解析章节和封面)、PDF(canvas 渲染)
- **书架管理** — 网格书架,EPUB 显示封面缩略图,TXT/PDF 显示书名色块;进度百分比一目了然,最近阅读历史快速回到上次的书
- **章节跳转** — 右键打开章节列表,支持标题搜索过滤,一键跳转
- **全文搜索** — TXT 全文搜索,关键字上下文高亮,点击结果直接跳转到对应位置
- **百分比跳转** — 阅读窗右下角输入百分比,精确跳转到全书对应位置
- **自动分页** — 按实际渲染高度自动分页,调整字号或窗口大小后自动重排
- **进度记忆** — 自动保存每本书的阅读位置,下次打开恢复到上次位置

## 摸鱼伪装

老板来了怎么办?三种隐藏方式,触发动作全部可自定义:

| 功能 | 默认触发 | 效果 |
|------|----------|------|
| 隐身 | Esc / 双击 / 鼠标离开窗口边缘 | 内容透明化,窗口保留,鼠标移回即恢复 |
| 显示 | 中键 | 恢复内容可见 |
| 真隐藏 | 右键 | 窗口彻底消失,需命令恢复 |

- 在设置面板中可为三个功能分别绑定触发动作(双击、中键、右键、Esc、鼠标离开/进入边缘),系统自动检测冲突
- 隐身状态下可配置自动暂停翻页,避免恢复时位置跑偏

## 阅读窗操作

- **拖拽移动** — 鼠标按住窗口中间区域拖动
- **缩放** — 四边和四角均有缩放把手
- **窗口记忆** — 自动保存阅读窗位置和尺寸
- **翻页方式** — 键盘 ←→ / 滚轮 / 点击左右两侧 / PageUp Down / 空格 / 触摸滑动,可任意组合开关
- **翻页动画** — 无动画 / 滑动两种模式

## 外观定制

- **明暗主题** — 跟随系统 / 手动明亮 / 手动暗黑
- **阅读配色** — 背景色、文字色自定义,支持**全屏截图取色**(截取屏幕任意区域的颜色作为背景或文字色)
- **排版控制** — 字号(8-32px)、行高(1.0-3.0)、字重(50-1000)、11 种中英文字体、透明度(10%-100%)、清理空行
- **实时生效** — 修改设置后自动推送到已打开的阅读窗,无需重新打开

## 开发

```bash
# 1. 安装前端依赖
npm install

# 2. 安装 preload 原生依赖(不编译,随源码提交)
cd preload && npm install && cd ..

# 3. 开发模式(Vite dev server :5173,ZTools 开发者工具以本目录为根加载)
npm run dev

# 4. 构建产物到 dist/
npm run build
```

## 打包发布

```bash
# 安装 ZTools 插件 CLI
npm install -g @ztools-center/plugin-cli

# 发布到 ZTools 插件中心
ztools publish
```
为什么做这个插件?

之前一直使用utools的插件摸鱼阅读,但是使用时一直感觉摸鱼阅读限制太多,不能随时移动和调整阅读框大小,于是用AI重新开发了这个插件,感谢摸鱼阅读的开发者。
13 changes: 13 additions & 0 deletions plugins/serious-reading/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>严肃阅读</title>
</head>
<body class="bg-background text-foreground">
<div id="root"></div>
<script type="module" src="/src/main/main.tsx"></script>
</body>
</html>
4 changes: 4 additions & 0 deletions plugins/serious-reading/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading