sumulige-claude 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/.claude/.kickoff-hint.txt +3 -2
  2. package/.claude/CLAUDE.md +138 -0
  3. package/.claude/README.md +234 -43
  4. package/.claude/boris-optimizations.md +167 -0
  5. package/.claude/commands/todos.md +6 -41
  6. package/.claude/hooks/code-formatter.cjs +2 -7
  7. package/.claude/hooks/conversation-logger.cjs +222 -0
  8. package/.claude/hooks/multi-session.cjs +3 -9
  9. package/.claude/hooks/project-kickoff.cjs +198 -20
  10. package/.claude/hooks/rag-skill-loader.cjs +0 -7
  11. package/.claude/hooks/session-restore.cjs +0 -0
  12. package/.claude/hooks/session-save.cjs +0 -0
  13. package/.claude/hooks/thinking-silent.cjs +3 -9
  14. package/.claude/hooks/todo-manager.cjs +142 -269
  15. package/.claude/hooks/verify-work.cjs +4 -10
  16. package/.claude/rag/skill-index.json +128 -8
  17. package/.claude/settings.json +115 -0
  18. package/.claude/skills/123-skill/SKILL.md +61 -0
  19. package/.claude/skills/123-skill/examples/basic.md +3 -0
  20. package/.claude/skills/123-skill/metadata.yaml +30 -0
  21. package/.claude/skills/123-skill/templates/default.md +3 -0
  22. package/.claude/skills/SKILLS.md +145 -0
  23. package/.claude/skills/code-reviewer-123/SKILL.md +61 -0
  24. package/.claude/skills/code-reviewer-123/examples/basic.md +3 -0
  25. package/.claude/skills/code-reviewer-123/metadata.yaml +30 -0
  26. package/.claude/skills/code-reviewer-123/templates/default.md +3 -0
  27. package/.claude/skills/examples/README.md +47 -0
  28. package/.claude/skills/examples/basic-task.md +67 -0
  29. package/.claude/skills/examples/bug-fix-workflow.md +92 -0
  30. package/.claude/skills/examples/feature-development.md +81 -0
  31. package/.claude/skills/manus-kickoff/SKILL.md +128 -0
  32. package/.claude/skills/manus-kickoff/examples/basic.md +84 -0
  33. package/.claude/skills/manus-kickoff/metadata.yaml +33 -0
  34. package/.claude/skills/manus-kickoff/templates/PROJECT_KICKOFF.md +89 -0
  35. package/.claude/skills/manus-kickoff/templates/PROJECT_PROPOSAL.md +227 -0
  36. package/.claude/skills/manus-kickoff/templates/TASK_PLAN.md +121 -0
  37. package/.claude/skills/my-skill/SKILL.md +61 -0
  38. package/.claude/skills/my-skill/examples/basic.md +3 -0
  39. package/.claude/skills/my-skill/metadata.yaml +30 -0
  40. package/.claude/skills/my-skill/templates/default.md +3 -0
  41. package/.claude/skills/template/metadata.yaml +30 -0
  42. package/.claude/skills/test-skill-name/SKILL.md +61 -0
  43. package/.claude/skills/test-skill-name/examples/basic.md +3 -0
  44. package/.claude/skills/test-skill-name/metadata.yaml +30 -0
  45. package/.claude/skills/test-skill-name/templates/default.md +3 -0
  46. package/.claude/templates/PROJECT_KICKOFF.md +89 -0
  47. package/.claude/templates/PROJECT_PROPOSAL.md +227 -0
  48. package/.claude/templates/TASK_PLAN.md +121 -0
  49. package/.claude-plugin/marketplace.json +2 -2
  50. package/AGENTS.md +30 -6
  51. package/CHANGELOG.md +18 -0
  52. package/CLAUDE-template.md +114 -0
  53. package/README.md +16 -1
  54. package/config/official-skills.json +2 -2
  55. package/jest.config.js +3 -1
  56. package/lib/commands.js +1626 -1207
  57. package/lib/marketplace.js +1 -0
  58. package/package.json +1 -1
  59. package/project-paradigm.md +313 -0
  60. package/prompts/how-to-find.md +163 -0
  61. package/tests/commands.test.js +940 -17
  62. package/tests/config-schema.test.js +425 -0
  63. package/tests/marketplace.test.js +330 -214
  64. package/tests/sync-external.test.js +214 -0
  65. package/tests/update-registry.test.js +251 -0
  66. package/tests/utils.test.js +12 -8
  67. package/tests/web-search.test.js +392 -0
  68. package/thinkinglens-silent.md +138 -0
@@ -1,106 +1,79 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * TODO Manager - AI 自动任务管理系统 (v2.0)
3
+ * TODO Manager - AI 自动任务管理系统
4
4
  *
5
5
  * 功能:
6
- * - 支持 Research → Develop → Test 生命周期
7
- * - 自动任务状态流转
8
- * - 智能任务创建建议
6
+ * - 自动追踪项目任务
7
+ * - 生成可点击的任务索引
9
8
  * - 维护任务状态流转
9
+ * - 静默运行,不打扰工作流
10
10
  *
11
- * 生命周期:
12
- * Research (研究) → Develop (开发) → Test (测试) → Done (完成)
11
+ * 目录结构:
12
+ * development/todos/
13
+ * ├── INDEX.md # 任务总览
14
+ * ├── active/ # 进行中的任务
15
+ * ├── completed/ # 已完成的任务
16
+ * ├── backlog/ # 待办任务
17
+ * └── archived/ # 已归档任务
13
18
  */
14
19
 
15
20
  const fs = require('fs');
16
21
  const path = require('path');
17
22
 
18
23
  const PROJECT_DIR = process.env.CLAUDE_PROJECT_DIR || process.cwd();
19
-
20
- // 如果不在 Claude Code 环境中运行,静默退出
21
- if (!process.env.CLAUDE_PROJECT_DIR) {
22
- process.exit(0);
23
- }
24
-
25
24
  const TODOS_DIR = path.join(PROJECT_DIR, 'development', 'todos');
26
25
  const INDEX_FILE = path.join(TODOS_DIR, 'INDEX.md');
27
26
  const STATE_FILE = path.join(TODOS_DIR, '.state.json');
28
27
 
29
- // 任务类型和状态
30
- const TASK_TYPES = {
31
- RESEARCH: 'research',
32
- DEVELOP: 'develop',
33
- TEST: 'test'
34
- };
35
-
36
- const TASK_STAGES = {
28
+ // 任务状态
29
+ const STATUS = {
37
30
  ACTIVE: 'active',
38
31
  COMPLETED: 'completed',
39
32
  BACKLOG: 'backlog',
40
33
  ARCHIVED: 'archived'
41
34
  };
42
35
 
43
- // 图标映射
44
- const ICONS = {
45
- research: '📊',
46
- develop: '💻',
47
- test: '🧪'
48
- };
49
-
50
36
  // 确保目录存在
51
37
  function ensureDirectories() {
52
- const dirs = [TODOS_DIR];
53
-
54
- // 为每个阶段创建类型子目录
55
- for (const stage of Object.values(TASK_STAGES)) {
56
- dirs.push(path.join(TODOS_DIR, stage));
57
- for (const type of Object.values(TASK_TYPES)) {
58
- dirs.push(path.join(TODOS_DIR, stage, type));
59
- }
60
- }
61
-
62
- dirs.forEach(dir => {
63
- try { fs.mkdirSync(dir, { recursive: true }); } catch (e) {}
38
+ [TODOS_DIR, STATUS.ACTIVE, STATUS.COMPLETED, STATUS.BACKLOG, STATUS.ARCHIVED].forEach(dir => {
39
+ const fullPath = dir.startsWith('/') ? dir : path.join(TODOS_DIR, dir);
40
+ try { fs.mkdirSync(fullPath, { recursive: true }); } catch (e) {}
64
41
  });
65
42
  }
66
43
 
67
44
  // 扫描任务文件
68
45
  function scanTasks() {
69
46
  const tasks = {
70
- active: { research: [], develop: [], test: [] },
71
- completed: { research: [], develop: [], test: [] },
72
- backlog: { research: [], develop: [], test: [] },
73
- archived: { research: [], develop: [], test: [] }
47
+ active: [],
48
+ completed: [],
49
+ backlog: [],
50
+ archived: []
74
51
  };
75
52
 
76
- for (const [stage, types] of Object.entries(tasks)) {
77
- for (const [type, _] of Object.entries(types)) {
78
- const dir = path.join(TODOS_DIR, stage, type);
79
- if (!fs.existsSync(dir)) continue;
80
-
81
- const files = fs.readdirSync(dir)
82
- .filter(f => f.endsWith('.md') && f !== '_README.md');
83
-
84
- tasks[stage][type] = files.map(f => {
85
- const filePath = path.join(dir, f);
86
- const content = fs.readFileSync(filePath, 'utf-8');
87
- const titleMatch = content.match(/^#\s+(.+)$/m);
88
- const statusMatch = content.match(/\*\*状态\*\*:\s*([✅🚧📋])/);
89
- const priorityMatch = content.match(/\*\*优先级\*\*:\s*(P[0-3])/);
90
- const typeMatch = content.match(/\*\*类型\*\*:\s*([📊💻🧪])\s*(\w+)/);
91
-
92
- return {
93
- file: f,
94
- title: titleMatch ? titleMatch[1] : path.basename(f, '.md'),
95
- status: statusMatch ? statusMatch[1] : '🚧',
96
- priority: priorityMatch ? priorityMatch[1] : 'P2',
97
- taskType: typeMatch ? typeMatch[1] : type,
98
- icon: typeMatch ? typeMatch[2] : ICONS[type] || '📄',
99
- path: `${stage}/${type}/${f}`,
100
- stage: stage
101
- };
102
- });
103
- }
53
+ for (const [key, dirName] of Object.entries(STATUS)) {
54
+ const dir = path.join(TODOS_DIR, dirName);
55
+ if (!fs.existsSync(dir)) continue;
56
+
57
+ const files = fs.readdirSync(dir)
58
+ .filter(f => f.endsWith('.md') && f !== '_README.md');
59
+
60
+ tasks[dirName] = files.map(f => {
61
+ const filePath = path.join(dir, f);
62
+ const content = fs.readFileSync(filePath, 'utf-8');
63
+ const titleMatch = content.match(/^#\s+(.+)$/m);
64
+ const statusMatch = content.match(/\*\*状态\*\*:\s*([\u{1F300}-\u{1F9FF}\s]+)/u);
65
+ const priorityMatch = content.match(/\*\*优先级\*\*:\s*(P[0-3])/);
66
+ const branchMatch = content.match(/\*\*分支\*\*:\s*`([^`]+)`/);
67
+
68
+ return {
69
+ file: f,
70
+ title: titleMatch ? titleMatch[1] : path.basename(f, '.md'),
71
+ status: statusMatch ? statusMatch[1].trim() : '🚧 进行中',
72
+ priority: priorityMatch ? priorityMatch[1] : 'P2',
73
+ branch: branchMatch ? branchMatch[1] : null,
74
+ path: `${dirName}/${f}`
75
+ };
76
+ });
104
77
  }
105
78
 
106
79
  return tasks;
@@ -110,211 +83,138 @@ function scanTasks() {
110
83
  function generateIndex(tasks) {
111
84
  const now = new Date().toISOString().split('T')[0];
112
85
 
113
- // 计算总数
114
- const activeCount = tasks.active.research.length + tasks.active.develop.length + tasks.active.test.length;
115
- const completedCount = tasks.completed.research.length + tasks.completed.develop.length + tasks.completed.test.length;
116
- const backlogCount = tasks.backlog.research.length + tasks.backlog.develop.length + tasks.backlog.test.length;
117
-
118
86
  let md = `# 项目任务追踪系统
119
87
 
120
- > **统一管理**: 研究 → 开发 → 测试
121
- > **最后更新**: ${now}
122
-
123
- @version: 2.0.0
124
-
125
- ---
88
+ > 本目录由 AI 自动维护,记录项目开发任务和进度
126
89
 
127
- ## 📊 项目进度
90
+ **最后更新**: ${now}
128
91
 
129
- | 阶段 | 进度 | 状态 |
130
- |------|------|------|
131
- | Phase 1: MVP 智能监控 | 80% | 🚧 进行中 |
132
- | Phase 2: V1.5 动态调整 | 0% | 📋 待规划 |
133
- | Phase 3: V2.0 AI 教练 | 0% | 📋 待规划 |
92
+ @version: 1.0.0
134
93
 
135
- ---
136
-
137
- ## 🔄 任务生命周期
138
-
139
- \`\`\`
140
- ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
141
- │ RESEARCH │ → │ DEVELOP │ → │ TEST │
142
- │ 📊 研究 │ │ 💻 开发 │ │ 🧪 测试 │
143
- └─────────────┘ └─────────────┘ └─────────────┘
144
- \`\`\`
145
-
146
- ---
147
-
148
- ## 📁 目录结构
94
+ ## 目录结构
149
95
 
150
96
  \`\`\`
151
97
  development/todos/
152
98
  ├── INDEX.md # 本文件 - 任务总览
153
- ├── _templates/ # 任务模板
154
- ├── active/ # 进行中的任务 (${activeCount})
155
- ├── research/ # 📊 研究中 (${tasks.active.research.length})
156
- │ ├── develop/ # 💻 开发中 (${tasks.active.develop.length})
157
- │ └── test/ # 🧪 测试中 (${tasks.active.test.length})
158
- ├── completed/ # 已完成的任务 (${completedCount})
159
- │ ├── research/
160
- │ ├── develop/
161
- │ └── test/
162
- ├── backlog/ # 待规划的任务 (${backlogCount})
163
- └── archived/ # 已归档的任务
99
+ ├── active/ # 进行中的任务 (${tasks.active.length})
100
+ ├── completed/ # 已完成的任务 (${tasks.completed.length})
101
+ ├── backlog/ # 待规划的任务 (${tasks.backlog.length})
102
+ └── archived/ # 已归档的任务 (${tasks.archived.length})
164
103
  \`\`\`
165
104
 
166
- ---
167
-
168
- ## 🚧 当前进行中的任务
105
+ ## 快速跳转
169
106
 
170
- ### 📊 研究任务
171
107
  `;
172
108
 
173
- // 研究任务
174
- if (tasks.active.research.length > 0) {
175
- tasks.active.research.forEach(t => {
176
- md += `- [${t.priority}] [${t.title}](./${t.path}) - ${t.status}\n`;
109
+ // 进行中的任务
110
+ md += `## 🚧 进行中的任务 (${tasks.active.length})\n\n`;
111
+ if (tasks.active.length > 0) {
112
+ tasks.active.forEach(t => {
113
+ md += `- [${t.priority}] [${t.title}](./${t.path}) - ${t.status}${t.branch ? ` \`branch: ${t.branch}\`` : ''}\n`;
177
114
  });
178
115
  } else {
179
- md += `暂无\n`;
116
+ md += `*暂无进行中的任务*\n`;
180
117
  }
181
- md += `\n### 💻 开发任务\n`;
182
-
183
- // 开发任务
184
- if (tasks.active.develop.length > 0) {
185
- tasks.active.develop.forEach(t => {
186
- md += `- [${t.priority}] [${t.title}](./${t.path}) - ${t.status}\n`;
187
- });
188
- } else {
189
- md += `暂无\n`;
190
- }
191
- md += `\n### 🧪 测试任务\n`;
192
-
193
- // 测试任务
194
- if (tasks.active.test.length > 0) {
195
- tasks.active.test.forEach(t => {
196
- md += `- [${t.priority}] [${t.title}](./${t.path}) - ${t.status}\n`;
197
- });
198
- } else {
199
- md += `暂无\n`;
200
- }
201
-
202
- md += `\n---\n\n## ✅ 最近完成的任务\n\n### 💻 开发任务\n`;
203
-
204
- // 最近完成的开发任务
205
- if (tasks.completed.develop.length > 0) {
206
- tasks.completed.develop.slice(0, 5).forEach(t => {
207
- md += `- [${t.title}](./${t.path}) ${t.status}\n`;
118
+ md += `\n`;
119
+
120
+ // 最近完成的任务(最多5个)
121
+ md += `## 最近完成的任务\n\n`;
122
+ const recentCompleted = tasks.completed.slice(0, 5);
123
+ if (recentCompleted.length > 0) {
124
+ recentCompleted.forEach(t => {
125
+ md += `- [${t.title}](./${t.path})\n`;
208
126
  });
127
+ if (tasks.completed.length > 5) {
128
+ md += `- ...还有 ${tasks.completed.length - 5} 个已完成任务\n`;
129
+ }
209
130
  } else {
210
- md += `暂无\n`;
131
+ md += `*暂无已完成的任务*\n`;
211
132
  }
133
+ md += `\n`;
212
134
 
213
- md += `\n### 🧪 测试任务\n`;
214
-
215
- // 最近完成的测试任务
216
- if (tasks.completed.test.length > 0) {
217
- tasks.completed.test.slice(0, 3).forEach(t => {
218
- md += `- [${t.title}](./${t.path}) ${t.status}\n`;
135
+ // 待办任务
136
+ md += `## 📋 待办任务 (${tasks.backlog.length})\n\n`;
137
+ if (tasks.backlog.length > 0) {
138
+ tasks.backlog.slice(0, 10).forEach(t => {
139
+ md += `- [${t.priority}] [${t.title}](./${t.path})\n`;
219
140
  });
141
+ if (tasks.backlog.length > 10) {
142
+ md += `- ...还有 ${tasks.backlog.length - 10} 个待办任务\n`;
143
+ }
220
144
  } else {
221
- md += `暂无\n`;
145
+ md += `*暂无待办任务*\n`;
222
146
  }
223
-
224
- md += `\n---\n\n## 📋 待办任务\n\n`;
225
- md += `暂无\n`;
226
-
227
- md += `\n---\n\n## 🎯 使用方式\n\n`;
228
- md += `### 查看任务\n\`\`\`bash\n`;
229
- md += `# 按类型查看\n`;
230
- md += `ls development/todos/active/research/ # 研究任务\n`;
231
- md += `ls development/todos/active/develop/ # 开发任务\n`;
232
- md += `ls development/todos/active/test/ # 测试任务\n`;
147
+ md += `\n`;
148
+
149
+ // 全部目录链接
150
+ md += `## 全部目录\n\n`;
151
+ md += `- [🚧 所有进行中的任务](./active/) - 当前开发重点\n`;
152
+ md += `- [✅ 所有已完成的任务](./completed/) - 完整历史\n`;
153
+ md += `- [📋 所有待办任务](./backlog/) - 待规划\n`;
154
+ md += `- [📦 所有已归档任务](./archived/) - 历史记录\n`;
155
+ md += `\n`;
156
+
157
+ // 使用说明
158
+ md += `## 使用方式\n\n`;
159
+ md += `### 查看任务\n`;
160
+ md += `点击上方链接跳转到对应目录,或使用:\n`;
161
+ md += `\`\`\`bash\n`;
162
+ md += `# 查看进行中的任务\n`;
163
+ md += `cat development/todos/active/*.md\n\n`;
164
+ md += `# 查看特定任务\n`;
165
+ md += `cat development/todos/active/feature-name.md\n`;
233
166
  md += `\`\`\`\n\n`;
234
-
235
167
  md += `### 创建新任务\n`;
236
- md += `在 Claude Code 中:\n\`\`\`\n`;
237
- md += `创建一个新任务:\n`;
238
- md += `- 类型:测试\n`;
239
- md += `- 标题:Dashboard 功能测试\n\`\`\`\n\n`;
240
-
241
- md += `### 更新任务状态\n\`\`\`\n`;
242
- md += `将 [任务名] 标记为完成\n\`\`\`\n\n`;
168
+ md += `在 Claude Code 中:\n`;
169
+ md += `\`\`\`\n`;
170
+ md += `创建一个新任务:实现用户登录功能\n`;
171
+ md += `\`\`\`\n\n`;
172
+ md += `AI 会自动在 \`active/\` 目录创建对应的任务文件。\n\n`;
173
+ md += `### 更新任务状态\n`;
174
+ md += `\`\`\`\n`;
175
+ md += `将 [任务名] 标记为完成\n`;
176
+ md += `\`\`\`\n\n`;
177
+ md += `AI 会自动将任务移动到 \`completed/\` 目录。\n\n`;
243
178
 
244
- md += `---\n\n> **维护说明**: 本系统由 AI 自动维护\n`;
179
+ md += `---\n\n`;
180
+ md += `> **维护说明**: 本系统由 AI 自动维护,请勿手动编辑(除非你知道自己在做什么)\n`;
245
181
 
246
182
  return md;
247
183
  }
248
184
 
249
- // 加载和保存状态
250
- function loadState() {
251
- if (fs.existsSync(STATE_FILE)) {
252
- try {
253
- return JSON.parse(fs.readFileSync(STATE_FILE, 'utf-8'));
254
- } catch (e) {
255
- return { tasks: {}, transitions: [] };
256
- }
257
- }
258
- return { tasks: {}, transitions: [] };
259
- }
260
-
261
- function saveState(state) {
262
- fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
263
- }
264
-
265
- // 检查是否需要自动流转
266
- function checkAutoTransition(tasks, state) {
267
- const suggestions = [];
268
-
269
- // 检查刚完成的开发任务,建议创建测试任务
270
- const completedDevelop = tasks.completed.develop.filter(t => {
271
- const key = `completed_develop_${t.file}`;
272
- return !state.tasks[key]; // 首次完成
273
- });
274
-
275
- completedDevelop.forEach(t => {
276
- const testTaskName = t.file.replace('.md', '-test.md');
277
- const testPath = path.join(TODOS_DIR, 'active', 'test', testTaskName);
278
-
279
- if (!fs.existsSync(testPath)) {
280
- suggestions.push({
281
- type: 'create_test',
282
- message: `💡 建议为 "${t.title}" 创建测试任务`,
283
- developTask: t,
284
- testTask: testTaskName,
285
- template: `_templates/test.md`
286
- });
287
- }
288
-
289
- // 标记已处理
290
- const key = `completed_develop_${t.file}`;
291
- state.tasks[key] = { completed: true, notified: true };
292
- });
293
-
294
- return { suggestions, state };
295
- }
296
-
297
185
  // 更新索引
298
186
  function updateIndex() {
299
187
  try {
300
188
  ensureDirectories();
301
189
  const tasks = scanTasks();
302
- const state = loadState();
303
-
304
- // 检查自动流转
305
- const { suggestions, state: newState } = checkAutoTransition(tasks, state);
306
-
307
- // 生成索引
308
190
  const index = generateIndex(tasks);
309
- fs.writeFileSync(INDEX_FILE, index);
310
191
 
311
- // 保存状态
312
- saveState(newState);
192
+ // 检查是否需要更新 - 比较任务总数
193
+ let needsUpdate = true;
194
+ if (fs.existsSync(INDEX_FILE)) {
195
+ const existing = fs.readFileSync(INDEX_FILE, 'utf-8');
196
+ // 从现有索引中提取任务数量
197
+ const activeMatch = existing.match(/## 🚧 进行中的任务 \((\d+)\)/);
198
+ const completedMatch = existing.match(/## ✅ 最近完成的任务/);
199
+ const existingActive = activeMatch ? parseInt(activeMatch[1], 10) : 0;
200
+ const newActive = tasks.active.length;
201
+
202
+ // 如果活跃任务数量相同且没有完成任务内容变化,则不更新
203
+ if (existingActive === newActive && tasks.completed.length === 0) {
204
+ // 检查现有索引是否已有完成任务
205
+ const hasCompletedInExisting = existing.includes('[completed/') || existing.includes('./completed/');
206
+ const hasCompletedNow = tasks.completed.length > 0;
207
+ needsUpdate = hasCompletedInExisting !== hasCompletedNow;
208
+ }
209
+ }
210
+
211
+ if (needsUpdate) {
212
+ fs.writeFileSync(INDEX_FILE, index);
213
+ }
313
214
 
314
- return { tasks, suggestions, updated: true };
215
+ return { tasks, updated: needsUpdate };
315
216
  } catch (e) {
316
- console.error('[TODO Manager] Error:', e.message);
317
- return { tasks: { active: { research: [], develop: [], test: [] }, completed: { research: [], develop: [], test: [] } }, suggestions: [], updated: false };
217
+ return { tasks: { active: [], completed: [], backlog: [], archived: [] }, updated: false };
318
218
  }
319
219
  }
320
220
 
@@ -322,28 +222,13 @@ function updateIndex() {
322
222
  function main() {
323
223
  const result = updateIndex();
324
224
 
325
- // 输出建议
326
- if (result.suggestions && result.suggestions.length > 0) {
327
- console.error('\n📋 [任务流转] 检测到 ' + result.suggestions.length + ' 个自动流转建议:\n');
328
- result.suggestions.forEach((s, i) => {
329
- console.error(` ${i + 1}. ${s.message}`);
330
- });
331
- console.error('');
332
- }
333
-
334
- // 在 AgentStop 时输出摘要
225
+ // 在 AgentStop 或特定事件时输出摘要
335
226
  const eventType = process.env.CLAUDE_EVENT_TYPE || '';
336
227
  if (eventType === 'AgentStop') {
337
- const active = result.tasks.active;
338
- const activeTotal = active.research.length + active.develop.length + active.test.length;
339
- const completed = result.tasks.completed;
340
- const completedTotal = completed.research.length + completed.develop.length + completed.test.length;
341
-
342
- if (activeTotal > 0 || completedTotal > 0) {
343
- console.error(`\n📋 [任务追踪]`);
344
- console.error(` 进行中: ${activeTotal} 个 (📊 ${active.research.length} | 💻 ${active.develop.length} | 🧪 ${active.test.length})`);
345
- console.error(` 已完成: ${completedTotal} 个`);
346
- console.error(` 查看: ${path.relative(PROJECT_DIR, INDEX_FILE)}\n`);
228
+ const { active, completed } = result.tasks;
229
+ if (active.length > 0) {
230
+ console.log(`\n📋 [任务追踪] ${active.length} 个进行中, ${completed.length} 个已完成`);
231
+ console.log(` 查看: development/todos/INDEX.md\n`);
347
232
  }
348
233
  }
349
234
 
@@ -354,19 +239,7 @@ function main() {
354
239
  if (require.main === module) {
355
240
  if (process.argv[2] === '--force') {
356
241
  updateIndex();
357
- console.error('✅ Task index updated');
358
- } else if (process.argv[2] === '--suggest') {
359
- const result = updateIndex();
360
- if (result.suggestions.length > 0) {
361
- console.error('\n💡 自动流转建议:\n');
362
- result.suggestions.forEach((s, i) => {
363
- console.error(`${i + 1}. ${s.message}`);
364
- console.error(` 开发任务: ${s.developTask.file}`);
365
- console.error(` 测试任务: ${s.testTask}`);
366
- });
367
- } else {
368
- console.error('✅ 无待处理的流转建议');
369
- }
242
+ console.log('✅ Task index updated');
370
243
  } else {
371
244
  main();
372
245
  }
@@ -14,12 +14,6 @@ const fs = require('fs');
14
14
  const path = require('path');
15
15
 
16
16
  const PROJECT_DIR = process.env.CLAUDE_PROJECT_DIR || process.cwd();
17
-
18
- // 如果不在 Claude Code 环境中运行,静默退出
19
- if (!process.env.CLAUDE_PROJECT_DIR) {
20
- process.exit(0);
21
- }
22
-
23
17
  const VERIFY_DIR = path.join(PROJECT_DIR, '.claude/verify');
24
18
  const VERIFY_PENDING_FILE = path.join(VERIFY_DIR, '.pending-verify.json');
25
19
  const VERIFY_LOG_FILE = path.join(VERIFY_DIR, 'verify-log.md');
@@ -116,8 +110,8 @@ function main() {
116
110
 
117
111
  // 输出验证提示(仅在非 PostToolUse 事件,避免重复)
118
112
  if (eventType !== 'PostToolUse') {
119
- console.error(`\n🔍 [验证提醒] ${hint}`);
120
- console.error(`使用 /verify-work 查看待验证任务列表\n`);
113
+ console.log(`\n🔍 [验证提醒] ${hint}`);
114
+ console.log(`使用 /verify-work 查看待验证任务列表\n`);
121
115
  }
122
116
  }
123
117
 
@@ -125,8 +119,8 @@ function main() {
125
119
  if (eventType === 'AgentStop') {
126
120
  const pending = getPendingVerifies();
127
121
  if (pending.length > 0) {
128
- console.error(`\n🔍 [待验证任务] 还有 ${pending.length} 个任务待验证`);
129
- console.error(`使用 /verify-work 查看详情并标记完成\n`);
122
+ console.log(`\n🔍 [待验证任务] 还有 ${pending.length} 个任务待验证`);
123
+ console.log(`使用 /verify-work 查看详情并标记完成\n`);
130
124
  }
131
125
  }
132
126