agent-configs 1.0.0

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 (85) hide show
  1. package/README.md +223 -0
  2. package/agents/architect.md +211 -0
  3. package/agents/code-reviewer.md +104 -0
  4. package/agents/planner.md +119 -0
  5. package/agents/refactor-cleaner.md +306 -0
  6. package/agents/security-reviewer.md +545 -0
  7. package/agents/tdd-guide.md +280 -0
  8. package/bundles/bk-chat-bundle/README.md +48 -0
  9. package/bundles/bk-chat-bundle/manifest.json +10 -0
  10. package/bundles/continuous-learning/.claude/commands/evolve.md +190 -0
  11. package/bundles/continuous-learning/.claude/commands/instinct-status.md +64 -0
  12. package/bundles/continuous-learning/.claude/commands/learn.md +83 -0
  13. package/bundles/continuous-learning/.claude/hooks/learning-end.js +85 -0
  14. package/bundles/continuous-learning/.claude/hooks/observe.js +131 -0
  15. package/bundles/continuous-learning/.claude/lib/learning.js +559 -0
  16. package/bundles/continuous-learning/.claude/lib/utils.js +312 -0
  17. package/bundles/continuous-learning/.claude/skills/continuous-learning/SKILL.md +200 -0
  18. package/bundles/continuous-learning/.cursor/hooks/learning-end.js +102 -0
  19. package/bundles/continuous-learning/.cursor/rules/continuous-learning.mdc +34 -0
  20. package/bundles/continuous-learning/.cursor/skills/continuous-learning/SKILL.md +77 -0
  21. package/bundles/continuous-learning/README.md +159 -0
  22. package/bundles/continuous-learning/manifest.json +51 -0
  23. package/bundles/planning-bundle/README.md +34 -0
  24. package/bundles/planning-bundle/manifest.json +10 -0
  25. package/bundles/review-bundle/README.md +43 -0
  26. package/bundles/review-bundle/manifest.json +11 -0
  27. package/bundles/shared-memory/.claude/commands/list-sessions.md +124 -0
  28. package/bundles/shared-memory/.claude/commands/load-session.md +169 -0
  29. package/bundles/shared-memory/.claude/commands/save-session.md +137 -0
  30. package/bundles/shared-memory/.claude/hooks/memory-compact.js +43 -0
  31. package/bundles/shared-memory/.claude/hooks/memory-end.js +42 -0
  32. package/bundles/shared-memory/.claude/hooks/memory-start.js +59 -0
  33. package/bundles/shared-memory/.claude/lib/memory.js +416 -0
  34. package/bundles/shared-memory/.claude/lib/utils.js +209 -0
  35. package/bundles/shared-memory/.claude/skills/shared-memory/SKILL.md +183 -0
  36. package/bundles/shared-memory/.cursor/hooks/memory-start.js +42 -0
  37. package/bundles/shared-memory/.cursor/rules/shared-memory.mdc +37 -0
  38. package/bundles/shared-memory/.cursor/skills/shared-memory/SKILL.md +183 -0
  39. package/bundles/tdd-bundle/README.md +33 -0
  40. package/bundles/tdd-bundle/manifest.json +10 -0
  41. package/cli.js +978 -0
  42. package/commands/build-fix.md +29 -0
  43. package/commands/code-review.md +40 -0
  44. package/commands/e2e.md +363 -0
  45. package/commands/learn.md +114 -0
  46. package/commands/plan.md +113 -0
  47. package/commands/refactor-clean.md +28 -0
  48. package/commands/tdd.md +326 -0
  49. package/commands/test-coverage.md +27 -0
  50. package/commands/update-codemaps.md +17 -0
  51. package/commands/update-docs.md +31 -0
  52. package/configs.json +158 -0
  53. package/hooks/hooks.json +101 -0
  54. package/package.json +58 -0
  55. package/rules/agents.md +49 -0
  56. package/rules/coding-style.md +70 -0
  57. package/rules/git-workflow.md +45 -0
  58. package/rules/hooks.md +46 -0
  59. package/rules/patterns.md +55 -0
  60. package/rules/performance.md +47 -0
  61. package/rules/security.md +36 -0
  62. package/rules/testing.md +30 -0
  63. package/skills/ai-config-architect/SKILL.md +59 -0
  64. package/skills/ai-config-architect/references/agents.md +77 -0
  65. package/skills/ai-config-architect/references/commands.md +66 -0
  66. package/skills/ai-config-architect/references/hooks.md +70 -0
  67. package/skills/ai-config-architect/references/patterns.md +66 -0
  68. package/skills/ai-config-architect/references/platforms.md +82 -0
  69. package/skills/ai-config-architect/references/rules.md +66 -0
  70. package/skills/ai-config-architect/references/skills.md +67 -0
  71. package/skills/bk-chat-helper/SKILL.md +398 -0
  72. package/skills/bk-chat-helper/references/api-reference.md +606 -0
  73. package/skills/bk-chat-helper/references/examples.md +789 -0
  74. package/skills/bk-chat-helper/references/integration-guide.md +583 -0
  75. package/skills/bk-chat-x/SKILL.md +400 -0
  76. package/skills/bk-chat-x/references/components-api.md +340 -0
  77. package/skills/bk-chat-x/references/examples.md +386 -0
  78. package/skills/bk-chat-x/references/shortcuts-guide.md +375 -0
  79. package/skills/coding-standards/SKILL.md +523 -0
  80. package/skills/security-review/SKILL.md +497 -0
  81. package/skills/security-review/references/cloud-infrastructure-security.md +361 -0
  82. package/skills/strategic-compact/SKILL.md +66 -0
  83. package/skills/strategic-compact/scripts/suggest-compact.sh +52 -0
  84. package/skills/tdd-workflow/SKILL.md +412 -0
  85. package/skills/verification-loop/SKILL.md +128 -0
@@ -0,0 +1,312 @@
1
+ /**
2
+ * Continuous Learning - 自包含工具函数库
3
+ *
4
+ * 这个文件包含所有需要的工具函数,不依赖任何外部模块。
5
+ * 可以直接复制整个 .claude 目录到任何项目使用。
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const os = require('os');
11
+ const { execSync } = require('child_process');
12
+
13
+ // ============== 平台检测 ==============
14
+
15
+ const isWindows = process.platform === 'win32';
16
+
17
+ // ============== 目录工具 ==============
18
+
19
+ /**
20
+ * 确保目录存在(递归创建)
21
+ */
22
+ function ensureDir(dirPath) {
23
+ if (!fs.existsSync(dirPath)) {
24
+ fs.mkdirSync(dirPath, { recursive: true });
25
+ }
26
+ return dirPath;
27
+ }
28
+
29
+ // ============== 日期时间工具 ==============
30
+
31
+ /**
32
+ * 获取当前日期 YYYY-MM-DD 格式
33
+ */
34
+ function getDateString() {
35
+ const now = new Date();
36
+ const year = now.getFullYear();
37
+ const month = String(now.getMonth() + 1).padStart(2, '0');
38
+ const day = String(now.getDate()).padStart(2, '0');
39
+ return `${year}-${month}-${day}`;
40
+ }
41
+
42
+ /**
43
+ * 获取当前时间 HH:MM:SS 格式
44
+ */
45
+ function getTimeString() {
46
+ const now = new Date();
47
+ const hours = String(now.getHours()).padStart(2, '0');
48
+ const minutes = String(now.getMinutes()).padStart(2, '0');
49
+ const seconds = String(now.getSeconds()).padStart(2, '0');
50
+ return `${hours}:${minutes}:${seconds}`;
51
+ }
52
+
53
+ /**
54
+ * 获取 ISO 时间戳
55
+ */
56
+ function getTimestamp() {
57
+ return new Date().toISOString();
58
+ }
59
+
60
+ /**
61
+ * 获取短会话 ID(从环境变量)
62
+ */
63
+ function getSessionIdShort(fallback = 'default') {
64
+ const sessionId = process.env.CLAUDE_SESSION_ID;
65
+ if (!sessionId || sessionId.length === 0) {
66
+ return fallback;
67
+ }
68
+ return sessionId.slice(-8);
69
+ }
70
+
71
+ // ============== 文件操作 ==============
72
+
73
+ /**
74
+ * 安全读取文件
75
+ */
76
+ function readFile(filePath) {
77
+ try {
78
+ return fs.readFileSync(filePath, 'utf8');
79
+ } catch {
80
+ return null;
81
+ }
82
+ }
83
+
84
+ /**
85
+ * 写入文件(自动创建目录)
86
+ */
87
+ function writeFile(filePath, content) {
88
+ ensureDir(path.dirname(filePath));
89
+ fs.writeFileSync(filePath, content, 'utf8');
90
+ }
91
+
92
+ /**
93
+ * 追加到文件
94
+ */
95
+ function appendFile(filePath, content) {
96
+ ensureDir(path.dirname(filePath));
97
+ fs.appendFileSync(filePath, content, 'utf8');
98
+ }
99
+
100
+ /**
101
+ * 追加 JSON 行到 jsonl 文件
102
+ */
103
+ function appendJsonl(filePath, data) {
104
+ ensureDir(path.dirname(filePath));
105
+ fs.appendFileSync(filePath, JSON.stringify(data) + '\n', 'utf8');
106
+ }
107
+
108
+ /**
109
+ * 读取 jsonl 文件
110
+ */
111
+ function readJsonl(filePath) {
112
+ const content = readFile(filePath);
113
+ if (!content) return [];
114
+
115
+ return content
116
+ .split('\n')
117
+ .filter(line => line.trim())
118
+ .map(line => {
119
+ try {
120
+ return JSON.parse(line);
121
+ } catch {
122
+ return null;
123
+ }
124
+ })
125
+ .filter(Boolean);
126
+ }
127
+
128
+ /**
129
+ * 获取文件大小 (MB)
130
+ */
131
+ function getFileSizeMB(filePath) {
132
+ try {
133
+ const stats = fs.statSync(filePath);
134
+ return stats.size / (1024 * 1024);
135
+ } catch {
136
+ return 0;
137
+ }
138
+ }
139
+
140
+ /**
141
+ * 查找匹配的文件
142
+ * @param {string} dir - 目录
143
+ * @param {string} pattern - 文件模式 (如 "*.md")
144
+ * @param {object} options - { maxAge: days }
145
+ */
146
+ function findFiles(dir, pattern, options = {}) {
147
+ const { maxAge = null } = options;
148
+ const results = [];
149
+
150
+ if (!fs.existsSync(dir)) {
151
+ return results;
152
+ }
153
+
154
+ const regexPattern = pattern
155
+ .replace(/\./g, '\\.')
156
+ .replace(/\*/g, '.*')
157
+ .replace(/\?/g, '.');
158
+ const regex = new RegExp(`^${regexPattern}$`);
159
+
160
+ try {
161
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
162
+
163
+ for (const entry of entries) {
164
+ const fullPath = path.join(dir, entry.name);
165
+
166
+ if (entry.isFile() && regex.test(entry.name)) {
167
+ const stats = fs.statSync(fullPath);
168
+
169
+ if (maxAge !== null) {
170
+ const ageInDays = (Date.now() - stats.mtimeMs) / (1000 * 60 * 60 * 24);
171
+ if (ageInDays <= maxAge) {
172
+ results.push({ path: fullPath, mtime: stats.mtimeMs });
173
+ }
174
+ } else {
175
+ results.push({ path: fullPath, mtime: stats.mtimeMs });
176
+ }
177
+ }
178
+ }
179
+ } catch {
180
+ // 忽略权限错误
181
+ }
182
+
183
+ // 按修改时间倒序排列
184
+ results.sort((a, b) => b.mtime - a.mtime);
185
+
186
+ return results;
187
+ }
188
+
189
+ // ============== 日志输出 ==============
190
+
191
+ /**
192
+ * 输出到 stdout(Hook 输出需要使用 stdout 才能被用户看到)
193
+ * stderr 只在 --debug 模式下可见
194
+ */
195
+ function log(message) {
196
+ console.log(message);
197
+ }
198
+
199
+ /**
200
+ * 输出到 stderr(调试信息)
201
+ */
202
+ function debug(message) {
203
+ console.error(message);
204
+ }
205
+
206
+ // ============== 工作区检测 ==============
207
+
208
+ /**
209
+ * 获取工作区根目录
210
+ */
211
+ function getWorkspaceRoot() {
212
+ // 优先使用 Claude Code 提供的项目目录
213
+ if (process.env.CLAUDE_PROJECT_DIR) {
214
+ return process.env.CLAUDE_PROJECT_DIR;
215
+ }
216
+
217
+ // 尝试 git 根目录
218
+ try {
219
+ const gitRoot = execSync('git rev-parse --show-toplevel', {
220
+ encoding: 'utf8',
221
+ stdio: ['pipe', 'pipe', 'pipe']
222
+ }).trim();
223
+ if (gitRoot) return gitRoot;
224
+ } catch {
225
+ // 不是 git 仓库
226
+ }
227
+
228
+ // 回退到 PWD 或 cwd
229
+ return process.env.PWD || process.cwd();
230
+ }
231
+
232
+ /**
233
+ * 获取当前项目名称
234
+ */
235
+ function getCurrentProject(workspace) {
236
+ const root = workspace || getWorkspaceRoot();
237
+ return path.basename(root);
238
+ }
239
+
240
+ /**
241
+ * 获取用户主目录
242
+ */
243
+ function getHomeDir() {
244
+ return os.homedir();
245
+ }
246
+
247
+ /**
248
+ * 展开路径中的 ~
249
+ */
250
+ function expandPath(p) {
251
+ if (p.startsWith('~')) {
252
+ return path.join(getHomeDir(), p.slice(1));
253
+ }
254
+ return p;
255
+ }
256
+
257
+ // ============== 字符串工具 ==============
258
+
259
+ /**
260
+ * 将字符串转换为安全的文件名
261
+ */
262
+ function toSafeFilename(str) {
263
+ return str
264
+ .toLowerCase()
265
+ .replace(/[^a-z0-9\u4e00-\u9fa5]+/g, '-')
266
+ .replace(/^-+|-+$/g, '');
267
+ }
268
+
269
+ /**
270
+ * 截断字符串
271
+ */
272
+ function truncate(str, maxLength) {
273
+ if (!str || str.length <= maxLength) return str;
274
+ return str.slice(0, maxLength) + '...';
275
+ }
276
+
277
+ module.exports = {
278
+ // 平台
279
+ isWindows,
280
+
281
+ // 目录
282
+ ensureDir,
283
+
284
+ // 日期时间
285
+ getDateString,
286
+ getTimeString,
287
+ getTimestamp,
288
+ getSessionIdShort,
289
+
290
+ // 文件
291
+ readFile,
292
+ writeFile,
293
+ appendFile,
294
+ appendJsonl,
295
+ readJsonl,
296
+ getFileSizeMB,
297
+ findFiles,
298
+
299
+ // 日志
300
+ log,
301
+ debug,
302
+
303
+ // 工作区
304
+ getWorkspaceRoot,
305
+ getCurrentProject,
306
+ getHomeDir,
307
+ expandPath,
308
+
309
+ // 字符串
310
+ toSafeFilename,
311
+ truncate
312
+ };
@@ -0,0 +1,200 @@
1
+ ---
2
+ name: continuous-learning
3
+ description: 持续学习能力 - 从会话中自动提取可复用的 patterns,保存为 skills 或 instincts,并支持进化为更高级结构。
4
+ version: 2.0.0
5
+ ---
6
+
7
+ # Continuous Learning - 持续学习
8
+
9
+ ## 这是什么
10
+
11
+ 这是一个让 AI 具备"学习意识"的能力。通过观察会话中的 patterns,将有价值的知识提取并保存,供未来会话使用。
12
+
13
+ 核心理念:**如果你不得不多次重复相同的提示,或者 Claude 遇到了同样的问题——这些 patterns 应该被保存下来。**
14
+
15
+ ## 架构概述
16
+
17
+ ```
18
+ 会话活动
19
+
20
+ │ Hooks 捕获提示 + 工具使用 (100% 可靠)
21
+
22
+ ┌─────────────────────────────────────────┐
23
+ │ observations.jsonl │
24
+ │ (提示、工具调用、结果) │
25
+ └─────────────────────────────────────────┘
26
+
27
+ │ 会话结束时评估 / 手动 /learn
28
+
29
+ ┌─────────────────────────────────────────┐
30
+ │ PATTERN 检测 │
31
+ │ • 用户纠正 → instinct/skill │
32
+ │ • 错误解决 → instinct/skill │
33
+ │ • 重复工作流 → instinct/skill │
34
+ └─────────────────────────────────────────┘
35
+
36
+ │ /evolve 聚合
37
+
38
+ ┌─────────────────────────────────────────┐
39
+ │ evolved/ │
40
+ │ • commands/new-feature.md │
41
+ │ • skills/testing-workflow.md │
42
+ │ • agents/refactor-specialist.md │
43
+ └─────────────────────────────────────────┘
44
+ ```
45
+
46
+ ## 两个版本
47
+
48
+ ### v1: 简单版 - Learned Skills
49
+
50
+ 使用 Stop hook 在会话结束时评估,直接提取为完整 skills。
51
+
52
+ **优点**: 简单直接,立即可用
53
+ **适合**: 希望快速开始的用户
54
+
55
+ ```
56
+ 会话结束 → 评估 patterns → 保存到 ~/.claude/skills/learned/
57
+ ```
58
+
59
+ ### v2: 高级版 - Instincts + Evolution
60
+
61
+ 使用 PreToolUse/PostToolUse hooks 实时观察,创建原子级 "instincts"(带置信度),支持进化。
62
+
63
+ **优点**: 更精细的学习,支持置信度衰减和进化
64
+ **适合**: 希望深度定制的高级用户
65
+
66
+ ```
67
+ 工具使用 → 观察记录 → 创建 instincts → 聚合进化 → skills/commands/agents
68
+ ```
69
+
70
+ ## Pattern 类型
71
+
72
+ | Pattern | 说明 |
73
+ |---------|------|
74
+ | `error_resolution` | 特定错误如何被解决 |
75
+ | `user_corrections` | 用户纠正的行为 |
76
+ | `workarounds` | 框架/库的变通方案 |
77
+ | `debugging_techniques` | 有效的调试方法 |
78
+ | `project_specific` | 项目特定的约定 |
79
+
80
+ ## Instinct 模型 (v2)
81
+
82
+ 一个 instinct 是一个小的、原子级的学习行为:
83
+
84
+ ```yaml
85
+ ---
86
+ id: prefer-functional-style
87
+ trigger: "when writing new functions"
88
+ confidence: 0.7
89
+ domain: "code-style"
90
+ source: "session-observation"
91
+ ---
92
+
93
+ # Prefer Functional Style
94
+
95
+ ## Action
96
+ Use functional patterns over classes when appropriate.
97
+
98
+ ## Evidence
99
+ - Observed 5 instances of functional pattern preference
100
+ - User corrected class-based approach to functional on 2026-01-15
101
+ ```
102
+
103
+ **特性**:
104
+ - **原子级** — 一个触发器,一个动作
105
+ - **置信度加权** — 0.3 = 尝试性, 0.9 = 近乎确定
106
+ - **Domain 标签** — code-style, testing, git, debugging, workflow 等
107
+ - **证据支持** — 记录创建它的观察
108
+
109
+ ## 置信度评分
110
+
111
+ | 分数 | 含义 | 行为 |
112
+ |------|------|------|
113
+ | 0.3 | 尝试性 | 建议但不强制 |
114
+ | 0.5 | 中等 | 在相关时应用 |
115
+ | 0.7 | 强 | 自动批准应用 |
116
+ | 0.9 | 近乎确定 | 核心行为 |
117
+
118
+ **置信度增加**当:
119
+ - Pattern 被重复观察
120
+ - 用户不纠正建议的行为
121
+ - 来自其他来源的类似 instincts 同意
122
+
123
+ **置信度降低**当:
124
+ - 用户明确纠正行为
125
+ - Pattern 长时间未观察到
126
+ - 出现矛盾证据
127
+
128
+ ## 命令
129
+
130
+ | 命令 | 说明 |
131
+ |------|------|
132
+ | `/learn` | 手动提取当前会话的 patterns |
133
+ | `/instinct-status` | 显示所有已学习的 instincts 及置信度 |
134
+ | `/evolve` | 将相关 instincts 聚合为 skills/commands/agents |
135
+ | `/instinct-export` | 导出 instincts 分享 |
136
+ | `/instinct-import <file>` | 导入他人的 instincts |
137
+
138
+ ## 文件结构
139
+
140
+ ```
141
+ ~/.claude/
142
+ ├── skills/
143
+ │ └── learned/ # v1: 直接学习的 skills
144
+ │ ├── error-fix-xyz.md
145
+ │ └── workaround-abc.md
146
+
147
+ └── homunculus/ # v2: instinct-based 学习
148
+ ├── identity.json # 你的档案、技术水平
149
+ ├── observations.jsonl # 当前会话观察
150
+ ├── observations.archive/ # 处理过的观察
151
+ ├── instincts/
152
+ │ ├── personal/ # 自动学习的 instincts
153
+ │ └── inherited/ # 从他人导入的
154
+ └── evolved/
155
+ ├── agents/ # 生成的专业 agents
156
+ ├── skills/ # 生成的 skills
157
+ └── commands/ # 生成的 commands
158
+ ```
159
+
160
+ ## 何时建议学习
161
+
162
+ 在以下情况,**主动建议**用户运行 `/learn`:
163
+
164
+ ### 触发场景
165
+
166
+ 1. **解决了复杂的 bug**
167
+ - 调试过程超过 3 步
168
+ - 发现了非显而易见的根因
169
+ - 解决方案可能对其他项目有用
170
+
171
+ 2. **做出了重要的变通**
172
+ - 绕过了库/API 的限制
173
+ - 找到了版本兼容问题的解决方案
174
+
175
+ 3. **用户进行了纠正**
176
+ - 用户纠正了你的方法
177
+ - 用户指出了更好的做法
178
+
179
+ 4. **重复的工作流**
180
+ - 同样的步骤序列执行了多次
181
+ - 可以抽象为可复用的流程
182
+
183
+ ### 提醒方式
184
+
185
+ ```
186
+ 💡 这个解决方案看起来可能对其他项目有用。
187
+ 想要保存为 skill 吗?运行 /learn
188
+ ```
189
+
190
+ ## 隐私
191
+
192
+ - 观察记录**仅保存在本地**
193
+ - 只有**instincts**(patterns)可以导出
194
+ - 不会分享实际代码或对话内容
195
+ - 你控制导出什么
196
+
197
+ ## 相关
198
+
199
+ - [The Longform Guide](https://github.com/affaan-m/everything-claude-code) - Continuous learning 章节
200
+ - [Homunculus](https://github.com/humanplane/homunculus) - v2 架构的灵感来源
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Continuous Learning - Session End Hook for Cursor
4
+ *
5
+ * Cursor 版本的会话结束 hook
6
+ * 功能与 Claude Code 版本相同,但路径引用适配 Cursor 结构
7
+ */
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+ const os = require('os');
12
+
13
+ // 简化的工具函数
14
+ function log(message) {
15
+ console.log(message);
16
+ }
17
+
18
+ function ensureDir(dirPath) {
19
+ if (!fs.existsSync(dirPath)) {
20
+ fs.mkdirSync(dirPath, { recursive: true });
21
+ }
22
+ }
23
+
24
+ function getDateString() {
25
+ const now = new Date();
26
+ return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
27
+ }
28
+
29
+ function expandPath(p) {
30
+ if (p.startsWith('~')) {
31
+ return path.join(os.homedir(), p.slice(1));
32
+ }
33
+ return p;
34
+ }
35
+
36
+ // 默认配置
37
+ const MIN_SESSION_LENGTH = 10;
38
+ const LEARNED_SKILLS_PATH = expandPath('~/.claude/skills/learned/');
39
+ const HOMUNCULUS_PATH = expandPath('~/.claude/homunculus/');
40
+
41
+ async function main() {
42
+ try {
43
+ // 确保目录存在
44
+ ensureDir(LEARNED_SKILLS_PATH);
45
+ ensureDir(HOMUNCULUS_PATH);
46
+
47
+ // 获取会话信息
48
+ const transcriptPath = process.env.CURSOR_TRANSCRIPT_PATH || process.env.CLAUDE_TRANSCRIPT_PATH || '';
49
+
50
+ if (!transcriptPath) {
51
+ process.exit(0);
52
+ }
53
+
54
+ // 尝试读取 transcript 获取消息数
55
+ let messageCount = 0;
56
+ try {
57
+ if (fs.existsSync(transcriptPath)) {
58
+ const content = fs.readFileSync(transcriptPath, 'utf8');
59
+ const userMessages = (content.match(/"type"\s*:\s*"user"/g) || []).length;
60
+ messageCount = userMessages;
61
+ }
62
+ } catch {
63
+ // 无法读取 transcript
64
+ }
65
+
66
+ // 检查是否应该评估
67
+ if (messageCount < MIN_SESSION_LENGTH) {
68
+ process.exit(0);
69
+ }
70
+
71
+ // 统计已学习的内容
72
+ let skillsCount = 0;
73
+ let instinctsCount = 0;
74
+
75
+ try {
76
+ if (fs.existsSync(LEARNED_SKILLS_PATH)) {
77
+ skillsCount = fs.readdirSync(LEARNED_SKILLS_PATH).filter(f => f.endsWith('.md')).length;
78
+ }
79
+ } catch {}
80
+
81
+ try {
82
+ const instinctsPath = path.join(HOMUNCULUS_PATH, 'instincts', 'personal');
83
+ if (fs.existsSync(instinctsPath)) {
84
+ instinctsCount = fs.readdirSync(instinctsPath).filter(f => f.endsWith('.md')).length;
85
+ }
86
+ } catch {}
87
+
88
+ // 输出提示信息
89
+ log(`[ContinuousLearning] 会话包含 ${messageCount} 条消息`);
90
+ log(`[ContinuousLearning] 当前已学习: ${skillsCount} 个 skills, ${instinctsCount} 个 instincts`);
91
+ log(`[ContinuousLearning] 如果本次会话有值得保存的 patterns,可以运行 /learn`);
92
+
93
+ } catch (err) {
94
+ // 静默处理错误
95
+ }
96
+
97
+ process.exit(0);
98
+ }
99
+
100
+ main().catch(() => {
101
+ process.exit(0);
102
+ });
@@ -0,0 +1,34 @@
1
+ # 持续学习意识
2
+
3
+ ## 会话结束时
4
+
5
+ 当检测到以下情况时,建议用户使用 `/learn` 保存 patterns:
6
+
7
+ - 解决了复杂的 bug(调试过程超过 3 步)
8
+ - 做出了重要的变通方案
9
+ - 用户进行了多次纠正
10
+ - 同样的工作流重复执行了多次
11
+
12
+ 使用 `/learn` 提取可复用的 patterns。
13
+
14
+ ## 相关命令
15
+
16
+ - `/learn` - 手动提取 patterns 为 skill
17
+ - `/instinct-status` - 查看已学习的 instincts
18
+ - `/evolve` - 将相关 instincts 进化为更高级结构
19
+
20
+ ## 学习系统说明
21
+
22
+ 本项目使用两层学习系统:
23
+
24
+ ### v1: Learned Skills
25
+ - 直接保存到 `~/.claude/skills/learned/`
26
+ - 完整的 pattern 描述
27
+ - 适合明确的、可重用的解决方案
28
+
29
+ ### v2: Instincts
30
+ - 保存到 `~/.claude/homunculus/instincts/`
31
+ - 原子级学习单元,带置信度
32
+ - 可进化为 skills/commands/agents
33
+
34
+ 建议在会话结束前,如果有值得保存的 patterns,主动提醒用户。