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,137 @@
1
+ ---
2
+ name: save-session
3
+ description: 保存当前会话的关键信息到记忆文件,便于下次继续。
4
+ argument-hint: "[name]"
5
+ ---
6
+
7
+ # Save Session Command
8
+
9
+ 保存当前会话状态到记忆文件,便于下次继续工作。
10
+
11
+ ## 用法
12
+
13
+ ```
14
+ /save-session [name]
15
+ ```
16
+
17
+ - **无参数**:使用默认名称 `session`,生成 `YYYY-MM-DD-session.md`
18
+ - **有参数**:使用指定名称,生成 `YYYY-MM-DD-<name>.md`
19
+
20
+ ## 执行步骤
21
+
22
+ 执行此命令时,请按以下步骤操作:
23
+
24
+ ### 1. 分析当前会话
25
+
26
+ 回顾本次对话历史,识别以下内容:
27
+
28
+ - 完成了哪些任务?
29
+ - 正在进行什么工作?
30
+ - 做出了哪些关键决策?为什么?
31
+ - 遇到了什么问题?如何解决的?
32
+ - 下次需要继续什么?
33
+ - 哪些文件是重要的上下文?
34
+
35
+ ### 2. 生成记忆文件
36
+
37
+ 使用以下模板生成内容:
38
+
39
+ ```markdown
40
+ # 会话: <简短描述>
41
+
42
+ **日期**: YYYY-MM-DD HH:MM
43
+ **项目**: <项目名称>
44
+ **路径**: .claude/memory/sessions/YYYY-MM-DD-<name>.md
45
+ **会话ID**: <当前会话短ID>
46
+
47
+ ## 已完成
48
+ - [具体完成的任务1]
49
+ - [具体完成的任务2]
50
+
51
+ ## 进行中
52
+ - [任务] - 当前状态: [描述当前进度]
53
+
54
+ ## 关键决策
55
+ - [决策1] - 原因: [为什么这样决定]
56
+ - [决策2] - 原因: [为什么这样决定]
57
+
58
+ ## 遇到的问题
59
+ - [问题1] - 解决方案: [如何解决的]
60
+
61
+ ## 下次继续
62
+ - [ ] 待办1
63
+ - [ ] 待办2
64
+
65
+ ## 需要加载的文件
66
+ - `path/to/important/file.ts` - [为什么需要这个文件]
67
+
68
+ ## 相关上下文
69
+ [任何额外的重要背景信息,比如特殊的项目约束、用户偏好等]
70
+ ```
71
+
72
+ ### 3. 保存文件
73
+
74
+ 将生成的内容保存到:
75
+
76
+ ```
77
+ .claude/memory/sessions/YYYY-MM-DD-<name>.md
78
+ ```
79
+
80
+ 如果目录不存在,先创建目录结构。
81
+
82
+ ### 4. 确认保存
83
+
84
+ 向用户确认保存成功,并提示如何引用:
85
+
86
+ ```
87
+ ✅ 会话已保存到:.claude/memory/sessions/2026-01-27-feature-auth.md
88
+
89
+ 下次可以通过以下方式恢复:
90
+ - `/load-session feature-auth`
91
+ - `/load-session 1` (如果是最近的)
92
+ - 直接 `@.claude/memory/sessions/2026-01-27-feature-auth.md`
93
+ ```
94
+
95
+ ## 示例
96
+
97
+ ### 用户调用
98
+
99
+ ```
100
+ /save-session feature-auth
101
+ ```
102
+
103
+ ### AI 执行
104
+
105
+ 1. 分析对话,发现本次会话:
106
+ - 实现了用户认证模块
107
+ - 选择了 JWT 方案而非 Session
108
+ - 遇到了 token 刷新问题并解决
109
+ - 还需要完成权限校验中间件
110
+
111
+ 2. 生成并保存文件
112
+
113
+ 3. 返回确认:
114
+
115
+ ```
116
+ ✅ 会话已保存到:.claude/memory/sessions/2026-01-27-feature-auth.md
117
+
118
+ 本次记录了:
119
+ - ✓ 完成用户认证模块实现
120
+ - ✓ JWT vs Session 的技术决策
121
+ - ✓ Token 刷新问题的解决方案
122
+ - → 下次继续:权限校验中间件
123
+
124
+ 下次可以用 `/load-session feature-auth` 或 `@.claude/memory/sessions/2026-01-27-feature-auth.md` 恢复上下文。
125
+ ```
126
+
127
+ ## 注意事项
128
+
129
+ 1. **内容要精炼**:只记录关键信息,不要复制大段代码
130
+ 2. **决策要说明原因**:不只记录"选了什么",还要记录"为什么选"
131
+ 3. **待办要具体**:不要写"继续开发",要写"实现权限校验中间件"
132
+ 4. **文件路径要准确**:确保引用的文件路径是正确的
133
+
134
+ ## 相关命令
135
+
136
+ - `/load-session` - 加载之前保存的会话
137
+ - `/list-sessions` - 列出所有可用的会话记忆
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Memory PreCompact Hook - 上下文压缩前提醒
4
+ *
5
+ * 触发时机:上下文即将压缩
6
+ * 功能:提醒用户保存重要信息
7
+ */
8
+
9
+ const path = require('path');
10
+
11
+ // 使用本地 lib(相对于 .claude 目录)
12
+ const libPath = path.join(__dirname, '..', 'lib');
13
+ const { getMemoryDir } = require(path.join(libPath, 'memory'));
14
+ const { log, appendFile, getWorkspaceRoot } = require(path.join(libPath, 'utils'));
15
+
16
+ async function main() {
17
+ try {
18
+ const workspace = getWorkspaceRoot();
19
+
20
+ // 记录压缩事件
21
+ const memoryDir = getMemoryDir(workspace);
22
+ const logFile = path.join(memoryDir, 'compaction-log.txt');
23
+ const timestamp = new Date().toISOString();
24
+
25
+ try {
26
+ appendFile(logFile, `[${timestamp}] Context compaction triggered\n`);
27
+ } catch {
28
+ // 忽略写入失败
29
+ }
30
+
31
+ // 提醒用户保存
32
+ log(`[Memory] 上下文即将压缩,建议先 /save-session 保存关键进展`);
33
+
34
+ } catch (err) {
35
+ // 静默处理错误
36
+ }
37
+
38
+ process.exit(0);
39
+ }
40
+
41
+ main().catch(() => {
42
+ process.exit(0);
43
+ });
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Memory SessionEnd Hook - 会话结束时提醒保存
4
+ *
5
+ * 触发时机:会话结束
6
+ * 功能:提醒用户保存重要进展
7
+ */
8
+
9
+ const path = require('path');
10
+
11
+ // 使用本地 lib(相对于 .claude 目录)
12
+ const libPath = path.join(__dirname, '..', 'lib');
13
+ const { getSessionsMemoryDir } = require(path.join(libPath, 'memory'));
14
+ const { log, findFiles, getDateString, getWorkspaceRoot } = require(path.join(libPath, 'utils'));
15
+
16
+ async function main() {
17
+ try {
18
+ const workspace = getWorkspaceRoot();
19
+ const sessionsDir = getSessionsMemoryDir(workspace);
20
+ const today = getDateString();
21
+
22
+ // 检查今天是否已经保存过记忆
23
+ const todayMemories = findFiles(sessionsDir, `${today}-*.md`);
24
+
25
+ if (todayMemories.length > 0) {
26
+ // 今天已保存 - 不需要提醒
27
+ process.exit(0);
28
+ }
29
+
30
+ // 今天没有保存 - 提醒用户
31
+ log(`[Memory] 会话结束。如有重要进展,建议运行 /save-session 保存`);
32
+
33
+ } catch (err) {
34
+ // 静默处理错误
35
+ }
36
+
37
+ process.exit(0);
38
+ }
39
+
40
+ main().catch(() => {
41
+ process.exit(0);
42
+ });
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Memory SessionStart Hook - 检查可用的会话记忆
4
+ *
5
+ * 触发时机:新会话开始
6
+ * 功能:检测并提示用户有可用的历史记忆
7
+ */
8
+
9
+ const path = require('path');
10
+
11
+ // 使用本地 lib(相对于 .claude 目录)
12
+ const libPath = path.join(__dirname, '..', 'lib');
13
+ const { checkMemoryStatus } = require(path.join(libPath, 'memory'));
14
+ const { log, getWorkspaceRoot } = require(path.join(libPath, 'utils'));
15
+
16
+ async function main() {
17
+ try {
18
+ const workspace = getWorkspaceRoot();
19
+ const status = checkMemoryStatus(workspace);
20
+
21
+ if (!status.exists) {
22
+ // 没有记忆目录 - 新项目正常情况
23
+ process.exit(0);
24
+ }
25
+
26
+ if (status.count === 0) {
27
+ // 有目录但没有最近的记忆
28
+ process.exit(0);
29
+ }
30
+
31
+ // 发现最近的记忆 - 通过 JSON 格式注入系统提示
32
+ let message = `📝 检测到 ${status.count} 个最近的会话记忆`;
33
+
34
+ if (status.latest) {
35
+ message += `\n 最近: ${status.latest.relativePath}`;
36
+ }
37
+
38
+ if (status.count === 1) {
39
+ message += `\n 💡 使用 /load-session 加载,或直接 @ 引用`;
40
+ } else {
41
+ message += `\n 💡 使用 /list-sessions 查看,/load-session 加载`;
42
+ }
43
+
44
+ // 输出 JSON 格式
45
+ // SessionStart 只支持 systemMessage 字段显示给用户
46
+ console.log(JSON.stringify({
47
+ systemMessage: message
48
+ }))
49
+
50
+ } catch (err) {
51
+ // 静默处理错误 - 记忆功能是可选的
52
+ }
53
+
54
+ process.exit(0);
55
+ }
56
+
57
+ main().catch(() => {
58
+ process.exit(0);
59
+ });
@@ -0,0 +1,416 @@
1
+ /**
2
+ * Shared Memory - 记忆管理核心模块
3
+ *
4
+ * 提供会话记忆的存储、检索、解析功能
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const {
10
+ ensureDir,
11
+ findFiles,
12
+ readFile,
13
+ writeFile,
14
+ getDateString,
15
+ getTimeString,
16
+ getSessionIdShort,
17
+ getWorkspaceRoot,
18
+ getCurrentProject
19
+ } = require('./utils');
20
+
21
+ // 默认配置
22
+ const DEFAULT_CONFIG = {
23
+ storage: {
24
+ base_path: '.claude/memory/',
25
+ sessions_dir: 'sessions/',
26
+ context_file: 'context.md',
27
+ max_session_age_days: 30,
28
+ max_sessions_to_show: 10
29
+ }
30
+ };
31
+
32
+ // ============== 路径管理 ==============
33
+
34
+ /**
35
+ * 获取记忆基础目录
36
+ */
37
+ function getMemoryDir(workspace) {
38
+ const root = workspace || getWorkspaceRoot();
39
+ return path.join(root, DEFAULT_CONFIG.storage.base_path);
40
+ }
41
+
42
+ /**
43
+ * 获取会话记忆目录
44
+ */
45
+ function getSessionsMemoryDir(workspace) {
46
+ return path.join(getMemoryDir(workspace), DEFAULT_CONFIG.storage.sessions_dir);
47
+ }
48
+
49
+ /**
50
+ * 获取项目上下文文件路径
51
+ */
52
+ function getContextFile(workspace) {
53
+ return path.join(getMemoryDir(workspace), DEFAULT_CONFIG.storage.context_file);
54
+ }
55
+
56
+ /**
57
+ * 确保记忆目录存在
58
+ */
59
+ function ensureMemoryDir(workspace) {
60
+ ensureDir(getMemoryDir(workspace));
61
+ ensureDir(getSessionsMemoryDir(workspace));
62
+ }
63
+
64
+ // ============== 文件名处理 ==============
65
+
66
+ /**
67
+ * 生成会话文件名
68
+ * @param {string} name - 会话名称
69
+ * @returns {string} 格式: YYYY-MM-DD-<name>.md
70
+ */
71
+ function generateSessionFilename(name) {
72
+ const date = getDateString();
73
+ const safeName = name
74
+ .toLowerCase()
75
+ .replace(/[^a-z0-9\u4e00-\u9fa5]+/g, '-') // 支持中文
76
+ .replace(/^-+|-+$/g, '');
77
+ return `${date}-${safeName || 'session'}.md`;
78
+ }
79
+
80
+ /**
81
+ * 解析会话文件名
82
+ * @param {string} filename - 不含扩展名的文件名
83
+ * @returns {{date: string, name: string}}
84
+ */
85
+ function parseSessionFilename(filename) {
86
+ const match = filename.match(/^(\d{4}-\d{2}-\d{2})-(.+)$/);
87
+ if (match) {
88
+ return { date: match[1], name: match[2] };
89
+ }
90
+ return { date: '', name: filename };
91
+ }
92
+
93
+ // ============== 记忆文件解析 ==============
94
+
95
+ /**
96
+ * 解析记忆文件内容提取元数据
97
+ * @param {string} filePath - 文件路径
98
+ * @returns {object} 元数据
99
+ */
100
+ function parseMemoryFile(filePath) {
101
+ const content = readFile(filePath);
102
+ if (!content) return {};
103
+
104
+ const metadata = {
105
+ title: '',
106
+ project: '',
107
+ sessionId: '',
108
+ status: 'unknown',
109
+ hasInProgress: false,
110
+ hasTodos: false
111
+ };
112
+
113
+ // 提取标题
114
+ const titleMatch = content.match(/^#\s+会话:\s*(.+)$/m);
115
+ if (titleMatch) {
116
+ metadata.title = titleMatch[1].trim();
117
+ }
118
+
119
+ // 提取项目
120
+ const projectMatch = content.match(/\*\*项目\*\*:\s*(.+)$/m);
121
+ if (projectMatch) {
122
+ metadata.project = projectMatch[1].trim();
123
+ }
124
+
125
+ // 提取会话 ID
126
+ const sessionIdMatch = content.match(/\*\*会话ID\*\*:\s*(.+)$/m);
127
+ if (sessionIdMatch) {
128
+ metadata.sessionId = sessionIdMatch[1].trim();
129
+ }
130
+
131
+ // 检查进行中项目
132
+ metadata.hasInProgress = /##\s+进行中/.test(content) &&
133
+ content.includes('- [') &&
134
+ !/##\s+进行中\s*\n+(?:##|\*\*|$)/.test(content);
135
+
136
+ // 检查待办事项
137
+ metadata.hasTodos = /##\s+下次继续/.test(content) &&
138
+ /- \[ \]/.test(content);
139
+
140
+ // 判断状态
141
+ if (metadata.hasInProgress || metadata.hasTodos) {
142
+ metadata.status = '进行中';
143
+ } else {
144
+ metadata.status = '已完成';
145
+ }
146
+
147
+ return metadata;
148
+ }
149
+
150
+ // ============== 记忆列表 ==============
151
+
152
+ /**
153
+ * 列出所有会话记忆文件
154
+ * @param {object} options - { maxAge: days, limit: number, workspace: string }
155
+ * @returns {Array} 记忆列表
156
+ */
157
+ function listSessionMemories(options = {}) {
158
+ const {
159
+ maxAge = DEFAULT_CONFIG.storage.max_session_age_days,
160
+ limit = DEFAULT_CONFIG.storage.max_sessions_to_show,
161
+ workspace
162
+ } = options;
163
+
164
+ const sessionsDir = getSessionsMemoryDir(workspace);
165
+ const files = findFiles(sessionsDir, '*.md', { maxAge });
166
+
167
+ return files.slice(0, limit).map(file => {
168
+ const filename = path.basename(file.path, '.md');
169
+ const parsed = parseSessionFilename(filename);
170
+ const metadata = parseMemoryFile(file.path);
171
+
172
+ return {
173
+ path: file.path,
174
+ relativePath: `.claude/memory/sessions/${path.basename(file.path)}`,
175
+ mtime: file.mtime,
176
+ filename,
177
+ ...parsed,
178
+ ...metadata
179
+ };
180
+ });
181
+ }
182
+
183
+ /**
184
+ * 获取最近的记忆
185
+ */
186
+ function getLatestMemory(workspace) {
187
+ const memories = listSessionMemories({ limit: 1, workspace });
188
+ return memories.length > 0 ? memories[0] : null;
189
+ }
190
+
191
+ /**
192
+ * 按名称查找记忆(模糊匹配)
193
+ * @param {string} query - 查询(名称或序号)
194
+ */
195
+ function findMemoryByName(query, workspace) {
196
+ const memories = listSessionMemories({ workspace, limit: 100 });
197
+
198
+ // 数字则按索引
199
+ const num = parseInt(query, 10);
200
+ if (!isNaN(num) && num > 0 && num <= memories.length) {
201
+ return memories[num - 1];
202
+ }
203
+
204
+ // 模糊匹配
205
+ const queryLower = query.toLowerCase();
206
+ return memories.find(m =>
207
+ m.name.toLowerCase().includes(queryLower) ||
208
+ m.filename.toLowerCase().includes(queryLower) ||
209
+ (m.title && m.title.toLowerCase().includes(queryLower))
210
+ ) || null;
211
+ }
212
+
213
+ // ============== 记忆内容生成 ==============
214
+
215
+ /**
216
+ * 生成记忆文件内容
217
+ * @param {object} data - 记忆数据
218
+ * @returns {string} Markdown 内容
219
+ */
220
+ function generateMemoryContent(data) {
221
+ const {
222
+ title = '会话记录',
223
+ project = getCurrentProject(),
224
+ sessionId = getSessionIdShort(),
225
+ completed = [],
226
+ inProgress = [],
227
+ decisions = [],
228
+ problems = [],
229
+ todos = [],
230
+ filesToLoad = [],
231
+ context = ''
232
+ } = data;
233
+
234
+ const date = getDateString();
235
+ const time = getTimeString();
236
+ const filename = generateSessionFilename(title);
237
+
238
+ return `# 会话: ${title}
239
+
240
+ **日期**: ${date} ${time}
241
+ **项目**: ${project}
242
+ **路径**: .claude/memory/sessions/${filename}
243
+ **会话ID**: ${sessionId}
244
+
245
+ ## 已完成
246
+ ${completed.length > 0 ? completed.map(item => `- ${item}`).join('\n') : '- (无)'}
247
+
248
+ ## 进行中
249
+ ${inProgress.length > 0 ? inProgress.map(item => `- ${item}`).join('\n') : '- (无)'}
250
+
251
+ ## 关键决策
252
+ ${decisions.length > 0 ? decisions.map(item => `- ${item}`).join('\n') : '- (无)'}
253
+
254
+ ## 遇到的问题
255
+ ${problems.length > 0 ? problems.map(item => `- ${item}`).join('\n') : '- (无)'}
256
+
257
+ ## 下次继续
258
+ ${todos.length > 0 ? todos.map(item => `- [ ] ${item}`).join('\n') : '- [ ] (待定)'}
259
+
260
+ ## 需要加载的文件
261
+ ${filesToLoad.length > 0 ? filesToLoad.map(item => `- \`${item}\``).join('\n') : '- (无)'}
262
+
263
+ ## 相关上下文
264
+ ${context || '(无额外上下文)'}
265
+ `;
266
+ }
267
+
268
+ // ============== 记忆保存/加载 ==============
269
+
270
+ /**
271
+ * 保存会话记忆
272
+ * @param {object} data - 记忆数据
273
+ * @param {string} [workspace] - 工作区路径
274
+ */
275
+ function saveSessionMemory(data, workspace) {
276
+ try {
277
+ ensureMemoryDir(workspace);
278
+
279
+ const content = generateMemoryContent(data);
280
+ const filename = generateSessionFilename(data.title || 'session');
281
+ const filePath = path.join(getSessionsMemoryDir(workspace), filename);
282
+
283
+ writeFile(filePath, content);
284
+
285
+ return {
286
+ success: true,
287
+ path: filePath,
288
+ relativePath: `.claude/memory/sessions/${filename}`,
289
+ filename
290
+ };
291
+ } catch (err) {
292
+ return {
293
+ success: false,
294
+ error: err.message
295
+ };
296
+ }
297
+ }
298
+
299
+ /**
300
+ * 加载会话记忆
301
+ * @param {string} pathOrQuery - 文件路径、名称或索引
302
+ */
303
+ function loadSessionMemory(pathOrQuery, workspace) {
304
+ try {
305
+ let filePath;
306
+
307
+ // 直接路径
308
+ if (pathOrQuery.endsWith('.md') && fs.existsSync(pathOrQuery)) {
309
+ filePath = pathOrQuery;
310
+ } else {
311
+ // 按名称/索引查找
312
+ const memory = findMemoryByName(pathOrQuery, workspace);
313
+ if (!memory) {
314
+ return { success: false, error: `未找到匹配的记忆文件: ${pathOrQuery}` };
315
+ }
316
+ filePath = memory.path;
317
+ }
318
+
319
+ const content = readFile(filePath);
320
+ if (!content) {
321
+ return { success: false, error: `无法读取文件: ${filePath}` };
322
+ }
323
+
324
+ const metadata = parseMemoryFile(filePath);
325
+
326
+ return {
327
+ success: true,
328
+ path: filePath,
329
+ relativePath: `.claude/memory/sessions/${path.basename(filePath)}`,
330
+ content,
331
+ metadata
332
+ };
333
+ } catch (err) {
334
+ return { success: false, error: err.message };
335
+ }
336
+ }
337
+
338
+ // ============== 状态检查 ==============
339
+
340
+ /**
341
+ * 检查记忆目录状态
342
+ */
343
+ function checkMemoryStatus(workspace) {
344
+ const memoryDir = getMemoryDir(workspace);
345
+
346
+ if (!fs.existsSync(memoryDir)) {
347
+ return { exists: false, count: 0, latest: null };
348
+ }
349
+
350
+ const memories = listSessionMemories({ workspace, maxAge: 7 });
351
+
352
+ return {
353
+ exists: true,
354
+ count: memories.length,
355
+ latest: memories.length > 0 ? memories[0] : null
356
+ };
357
+ }
358
+
359
+ // ============== 格式化输出 ==============
360
+
361
+ /**
362
+ * 格式化记忆列表为表格
363
+ */
364
+ function formatMemoriesList(memories) {
365
+ if (memories.length === 0) {
366
+ return '暂无会话记忆。使用 `/save-session <名称>` 保存当前会话。';
367
+ }
368
+
369
+ let output = '## 可用会话记忆\n\n';
370
+ output += '| # | 日期 | 名称 | 状态 | 路径 |\n';
371
+ output += '|---|------|------|------|------|\n';
372
+
373
+ memories.forEach((m, idx) => {
374
+ output += `| ${idx + 1} | ${m.date} | ${m.name} | ${m.status} | ${m.relativePath} |\n`;
375
+ });
376
+
377
+ output += '\n💡 使用方式:\n';
378
+ output += '- `/load-session <#>` 或 `/load-session <名称>` 加载\n';
379
+ output += '- 直接 `@.claude/memory/sessions/<文件名>` 引用\n';
380
+
381
+ return output;
382
+ }
383
+
384
+ module.exports = {
385
+ // 路径
386
+ getMemoryDir,
387
+ getSessionsMemoryDir,
388
+ getContextFile,
389
+ ensureMemoryDir,
390
+
391
+ // 文件名
392
+ generateSessionFilename,
393
+ parseSessionFilename,
394
+
395
+ // 解析
396
+ parseMemoryFile,
397
+
398
+ // 列表
399
+ listSessionMemories,
400
+ getLatestMemory,
401
+ findMemoryByName,
402
+
403
+ // 内容
404
+ generateMemoryContent,
405
+
406
+ // 操作
407
+ saveSessionMemory,
408
+ loadSessionMemory,
409
+ checkMemoryStatus,
410
+
411
+ // 格式化
412
+ formatMemoriesList,
413
+
414
+ // 配置
415
+ DEFAULT_CONFIG
416
+ };