@chongyan/autospec 1.0.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 (243) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +472 -0
  3. package/README.md +476 -0
  4. package/bin/autospec.js +3 -0
  5. package/knowledge/README.md +144 -0
  6. package/knowledge/checklists/code.md +182 -0
  7. package/knowledge/checklists/design.md +196 -0
  8. package/knowledge/checklists/release.md +70 -0
  9. package/knowledge/checklists/requirement.md +169 -0
  10. package/knowledge/checklists/test.md +46 -0
  11. package/knowledge/config/README.en.md +44 -0
  12. package/knowledge/config/README.md +44 -0
  13. package/knowledge/config/role-composition.yaml +98 -0
  14. package/knowledge/config/role-extensions.yaml +140 -0
  15. package/knowledge/config/skill-compositions.yaml +142 -0
  16. package/knowledge/config/team-stage.yaml +95 -0
  17. package/knowledge/config/team-tasks.yaml +139 -0
  18. package/knowledge/config/team-triggers.yaml +198 -0
  19. package/knowledge/config/validation-patterns.yaml +137 -0
  20. package/knowledge/domain/README.md +115 -0
  21. package/knowledge/domain/flows/README.md +194 -0
  22. package/knowledge/domain/glossary.md +143 -0
  23. package/knowledge/domain/rules.md +138 -0
  24. package/knowledge/environment/README.en.md +36 -0
  25. package/knowledge/environment/README.md +87 -0
  26. package/knowledge/environment/component-knowledge.md +316 -0
  27. package/knowledge/environment/detection-patterns.yaml +502 -0
  28. package/knowledge/environment/middleware-knowledge.md +237 -0
  29. package/knowledge/environment/template-registry.md +321 -0
  30. package/knowledge/guides/domain-driven-design.md +345 -0
  31. package/knowledge/guides/knowledge-management.md +369 -0
  32. package/knowledge/guides/requirement-engineering.md +329 -0
  33. package/knowledge/guides/stages/ai-effect-evaluator.md +93 -0
  34. package/knowledge/guides/stages/code-implementer.md +205 -0
  35. package/knowledge/guides/stages/code-reviewer.md +111 -0
  36. package/knowledge/guides/stages/consistency-checker.md +177 -0
  37. package/knowledge/guides/stages/design-planner.md +401 -0
  38. package/knowledge/guides/stages/design-reviewer.md +83 -0
  39. package/knowledge/guides/stages/integration-test-runner.md +105 -0
  40. package/knowledge/guides/stages/release-checker.md +205 -0
  41. package/knowledge/guides/stages/requirement-analyzer.md +195 -0
  42. package/knowledge/guides/stages/requirement-reviewer.md +83 -0
  43. package/knowledge/guides/stages/security-reviewer.md +89 -0
  44. package/knowledge/guides/stages/test-context-analyzer.md +250 -0
  45. package/knowledge/guides/stages/test-generator.md +241 -0
  46. package/knowledge/guides/stages/test-planner.md +183 -0
  47. package/knowledge/guides/stages/test-reviewer.md +76 -0
  48. package/knowledge/guides/stages/unit-test-runner.md +83 -0
  49. package/knowledge/guides/support/ai-agent-analyzer.md +362 -0
  50. package/knowledge/guides/support/ai-anomaly-analyzer.md +213 -0
  51. package/knowledge/guides/support/ai-artifact-evaluator.md +192 -0
  52. package/knowledge/guides/support/ai-capability-analyzer.md +193 -0
  53. package/knowledge/guides/support/ai-component-analyzer.md +169 -0
  54. package/knowledge/guides/support/ai-data-validator.md +276 -0
  55. package/knowledge/guides/support/ai-evaluation-planner.md +374 -0
  56. package/knowledge/guides/support/ai-path-evaluator.md +274 -0
  57. package/knowledge/guides/support/ai-pipeline-evaluator.md +219 -0
  58. package/knowledge/guides/support/ai-rag-analyzer.md +339 -0
  59. package/knowledge/guides/support/ai-task-assessor.md +418 -0
  60. package/knowledge/guides/support/ai-test-diagnostics.md +133 -0
  61. package/knowledge/guides/support/complexity-assessor.md +268 -0
  62. package/knowledge/guides/support/component-discovery.md +183 -0
  63. package/knowledge/guides/support/environment-scanner.md +207 -0
  64. package/knowledge/guides/support/environment-validator.md +207 -0
  65. package/knowledge/guides/support/knowledge-generator.md +234 -0
  66. package/knowledge/guides/support/methodology-extractor.md +55 -0
  67. package/knowledge/guides/support/pipeline-protocol.md +438 -0
  68. package/knowledge/guides/support/practice-logger.md +359 -0
  69. package/knowledge/guides/support/scope-inference.md +174 -0
  70. package/knowledge/guides/support/skill-distiller.md +91 -0
  71. package/knowledge/guides/support/skill-updater.md +45 -0
  72. package/knowledge/guides/support/skill-validator.md +72 -0
  73. package/knowledge/guides/support/team-orchestrator.md +323 -0
  74. package/knowledge/guides/support/tech-stack-analyzer.md +139 -0
  75. package/knowledge/guides/support/test-runner.md +254 -0
  76. package/knowledge/guides/system-design.md +352 -0
  77. package/knowledge/organization/ai-native-team.md +318 -0
  78. package/knowledge/organization/team-metrics.md +228 -0
  79. package/knowledge/principles/constitution.md +134 -0
  80. package/knowledge/principles/core-principles.md +368 -0
  81. package/knowledge/principles/design-philosophy.md +877 -0
  82. package/knowledge/principles/evolution.md +553 -0
  83. package/knowledge/process/01-requirement.md +113 -0
  84. package/knowledge/process/02-design.md +123 -0
  85. package/knowledge/process/03-implementation.md +90 -0
  86. package/knowledge/process/04-review.md +80 -0
  87. package/knowledge/process/05-testing.md +90 -0
  88. package/knowledge/process/06-delivery.md +88 -0
  89. package/knowledge/process/README.en.md +38 -0
  90. package/knowledge/process/README.md +48 -0
  91. package/knowledge/process/ai-sdlc.md +475 -0
  92. package/knowledge/process/overview.md +319 -0
  93. package/knowledge/standards/code-review.md +876 -0
  94. package/knowledge/standards/coding-style.md +940 -0
  95. package/knowledge/standards/data-consistency.md +1085 -0
  96. package/knowledge/standards/document-versioning.md +210 -0
  97. package/knowledge/standards/risk-detection.md +186 -0
  98. package/knowledge/templates/ai-evaluation.md +150 -0
  99. package/knowledge/templates/api-design.md +117 -0
  100. package/knowledge/templates/database-design.md +132 -0
  101. package/knowledge/templates/domain-driven-design.md +321 -0
  102. package/knowledge/templates/product-proposal.md +201 -0
  103. package/knowledge/templates/system-design.md +227 -0
  104. package/knowledge/templates/task-breakdown.md +107 -0
  105. package/knowledge/templates/test-case.md +170 -0
  106. package/package.json +53 -0
  107. package/plugins/.claude-plugin/plugin.json +134 -0
  108. package/plugins/agents/roles/ai-engineer.md +129 -0
  109. package/plugins/agents/roles/backend-engineer.md +165 -0
  110. package/plugins/agents/roles/ceo.md +94 -0
  111. package/plugins/agents/roles/data-engineer.md +135 -0
  112. package/plugins/agents/roles/devops-engineer.md +181 -0
  113. package/plugins/agents/roles/frontend-engineer.md +129 -0
  114. package/plugins/agents/roles/product-owner.md +98 -0
  115. package/plugins/agents/roles/quality-engineer.md +129 -0
  116. package/plugins/agents/roles/security-engineer.md +180 -0
  117. package/plugins/agents/roles/tech-lead.md +97 -0
  118. package/plugins/agents/support/blind-comparator.md +88 -0
  119. package/plugins/agents/support/consistency-checker.md +103 -0
  120. package/plugins/agents/support/failure-diagnostician.md +141 -0
  121. package/plugins/agents/support/independent-reviewer.md +80 -0
  122. package/plugins/agents/support/safety-auditor.md +121 -0
  123. package/plugins/agents/support/skill-benchmarker.md +86 -0
  124. package/plugins/agents/support/skill-forger.md +105 -0
  125. package/plugins/agents/support/stage-gate-evaluator.md +121 -0
  126. package/plugins/agents/support/test-coverage-reviewer.md +73 -0
  127. package/plugins/benchmarks/templates/README.md +44 -0
  128. package/plugins/benchmarks/templates/commands/explore-template.yaml +48 -0
  129. package/plugins/benchmarks/templates/pipeline/agile-template.yaml +84 -0
  130. package/plugins/benchmarks/templates/pipeline/waterfall-template.yaml +106 -0
  131. package/plugins/benchmarks/templates/skills/requirement-analyzer-template.yaml +48 -0
  132. package/plugins/commands/README.en.md +96 -0
  133. package/plugins/commands/README.md +96 -0
  134. package/plugins/commands/apply.md +191 -0
  135. package/plugins/commands/archive.md +76 -0
  136. package/plugins/commands/env-export.md +79 -0
  137. package/plugins/commands/env-sync.md +640 -0
  138. package/plugins/commands/env-template.md +223 -0
  139. package/plugins/commands/env-update.md +264 -0
  140. package/plugins/commands/env-validate.md +176 -0
  141. package/plugins/commands/env.md +79 -0
  142. package/plugins/commands/explore.md +76 -0
  143. package/plugins/commands/field-evolve.md +536 -0
  144. package/plugins/commands/memory.md +249 -0
  145. package/plugins/commands/project-evolve.md +821 -0
  146. package/plugins/commands/propose.md +93 -0
  147. package/plugins/commands/review.md +140 -0
  148. package/plugins/commands/run.md +224 -0
  149. package/plugins/commands/status.md +62 -0
  150. package/plugins/commands/validate.md +108 -0
  151. package/plugins/hooks/README.en.md +56 -0
  152. package/plugins/hooks/README.md +56 -0
  153. package/plugins/hooks/ai-project-guard.js +329 -0
  154. package/plugins/hooks/artifact-evaluation-hook.js +237 -0
  155. package/plugins/hooks/constitution-guard.js +211 -0
  156. package/plugins/hooks/environment-autocommit.js +264 -0
  157. package/plugins/hooks/environment-manager.js +778 -0
  158. package/plugins/hooks/execution-tracker.js +354 -0
  159. package/plugins/hooks/frozen-zone-guard.js +140 -0
  160. package/plugins/hooks/layer1-validator.js +423 -0
  161. package/plugins/hooks/lib/artifact-evaluator.js +414 -0
  162. package/plugins/hooks/lib/benchmarks/change-detector.js +390 -0
  163. package/plugins/hooks/lib/benchmarks/evaluator.js +605 -0
  164. package/plugins/hooks/lib/benchmarks/integration-example.js +169 -0
  165. package/plugins/hooks/lib/data-and-ai-detector.js +275 -0
  166. package/plugins/hooks/lib/detection-pattern-loader.js +865 -0
  167. package/plugins/hooks/lib/directory-discovery.js +395 -0
  168. package/plugins/hooks/lib/environment-config-loader.js +341 -0
  169. package/plugins/hooks/lib/environment-detector.js +553 -0
  170. package/plugins/hooks/lib/environment-evolver.js +564 -0
  171. package/plugins/hooks/lib/environment-registry.js +813 -0
  172. package/plugins/hooks/lib/execution-path.js +427 -0
  173. package/plugins/hooks/lib/hook-error-recorder.js +245 -0
  174. package/plugins/hooks/lib/hook-logger.js +538 -0
  175. package/plugins/hooks/lib/hook-runner.js +97 -0
  176. package/plugins/hooks/lib/hook-runner.sh +44 -0
  177. package/plugins/hooks/lib/hook-state-manager.js +480 -0
  178. package/plugins/hooks/lib/memory-extractor.js +377 -0
  179. package/plugins/hooks/lib/memory-manager.js +673 -0
  180. package/plugins/hooks/lib/metrics-analyzer.js +489 -0
  181. package/plugins/hooks/lib/project-evolution/auto-fixer.js +511 -0
  182. package/plugins/hooks/lib/project-evolution/memory-manager.js +346 -0
  183. package/plugins/hooks/lib/project-evolution/pattern-detector.js +476 -0
  184. package/plugins/hooks/lib/project-evolution/semantic-indexer.js +480 -0
  185. package/plugins/hooks/lib/project-structure-detector.js +326 -0
  186. package/plugins/hooks/lib/rollback-tracker.js +346 -0
  187. package/plugins/hooks/lib/source-code-scanner.js +596 -0
  188. package/plugins/hooks/lib/technology-stack-detector.js +374 -0
  189. package/plugins/hooks/lib/test-failure-analyzer.js +375 -0
  190. package/plugins/hooks/lib/test-failure-fixer.js +268 -0
  191. package/plugins/hooks/lib/trace-context.js +277 -0
  192. package/plugins/hooks/lib/validation-patterns.js +415 -0
  193. package/plugins/hooks/memory-sync.js +171 -0
  194. package/plugins/hooks/pipeline-observer.js +413 -0
  195. package/plugins/hooks/scope-sentinel.js +204 -0
  196. package/plugins/hooks/trace-initialization.js +169 -0
  197. package/plugins/memory/templates/code-quality.yaml +149 -0
  198. package/plugins/memory/templates/multi-system.yaml +155 -0
  199. package/plugins/memory/templates/team-habits.yaml +119 -0
  200. package/plugins/memory/templates/testing.yaml +121 -0
  201. package/plugins/skills/README.en.md +47 -0
  202. package/plugins/skills/README.md +104 -0
  203. package/plugins/skills/benchmark-executor/README.md +93 -0
  204. package/plugins/skills/benchmark-executor/SKILL.md +647 -0
  205. package/plugins/skills/benchmark-generator/SKILL.md +349 -0
  206. package/plugins/skills/delivery-stage/SKILL.md +203 -0
  207. package/plugins/skills/design-stage/SKILL.md +216 -0
  208. package/plugins/skills/evolution-process/SKILL.md +291 -0
  209. package/plugins/skills/exploration-phase/SKILL.md +133 -0
  210. package/plugins/skills/implementation-stage/SKILL.md +179 -0
  211. package/plugins/skills/layer1-validation/SKILL.md +79 -0
  212. package/plugins/skills/pending-dashboard/SKILL.md +109 -0
  213. package/plugins/skills/project-evolution/SKILL.md +847 -0
  214. package/plugins/skills/requirement-stage/SKILL.md +183 -0
  215. package/plugins/skills/skill-forge/SKILL.md +223 -0
  216. package/plugins/skills/skill-forge/references/description-guide.md +92 -0
  217. package/plugins/skills/skill-forge/references/quality-rubric.md +104 -0
  218. package/plugins/skills/skill-forge/references/skill-template.md +106 -0
  219. package/plugins/skills/startup-guard/SKILL.md +38 -0
  220. package/plugins/skills/testing-stage/SKILL.md +195 -0
  221. package/scripts/cli/global-init.js +288 -0
  222. package/scripts/cli/global.js +324 -0
  223. package/scripts/cli/index.js +55 -0
  224. package/scripts/cli/init.js +382 -0
  225. package/scripts/cli/list.js +69 -0
  226. package/scripts/cli/org.js +340 -0
  227. package/scripts/cli/update.js +44 -0
  228. package/scripts/config/commands.config.js +145 -0
  229. package/scripts/config/hooks.config.js +197 -0
  230. package/scripts/evolution/evolution-router.js +273 -0
  231. package/scripts/evolution/evolution-signal-collector.js +307 -0
  232. package/scripts/evolution/knowledge-loader.js +346 -0
  233. package/scripts/evolution/marketplace.js +317 -0
  234. package/scripts/evolution/version-manager.js +371 -0
  235. package/scripts/install/agents.js +106 -0
  236. package/scripts/install/commands.js +133 -0
  237. package/scripts/install/constants.js +424 -0
  238. package/scripts/install/hook-logger.js +536 -0
  239. package/scripts/install/hooks.js +110 -0
  240. package/scripts/install/index.js +39 -0
  241. package/scripts/install/skills.js +95 -0
  242. package/scripts/postinstall.js +25 -0
  243. package/scripts/state.js +376 -0
@@ -0,0 +1,673 @@
1
+ /**
2
+ * Memory Manager - 统一的记忆管理模块
3
+ *
4
+ * 提供全局 + 项目双模式的记忆读写功能
5
+ * 复用 hook-state-manager.js 的设计模式
6
+ */
7
+
8
+ import fs from 'fs';
9
+ import path from 'path';
10
+ import os from 'os';
11
+ import {
12
+ GLOBAL_MEMORY_DIR,
13
+ MEMORY_DIRS,
14
+ MEMORY_FILES,
15
+ MEMORY_SCOPE,
16
+ MEMORY_TTL,
17
+ MEMORY_LAYERS,
18
+ DEFAULT_NORTH_STAR,
19
+ DEFAULT_TEAM_PREFERENCES,
20
+ DEFAULT_CONSTRAINTS,
21
+ DEFAULT_MEMORY_META
22
+ } from '../../../scripts/install/constants.js';
23
+
24
+ // 缓存
25
+ const memoryCache = new Map();
26
+ const CACHE_TTL = 5000; // 5秒缓存
27
+
28
+ /**
29
+ * 获取全局记忆目录路径
30
+ * @returns {string} 全局记忆目录路径
31
+ */
32
+ export function getGlobalMemoryDir() {
33
+ return path.join(os.homedir(), GLOBAL_MEMORY_DIR);
34
+ }
35
+
36
+ /**
37
+ * 获取项目记忆目录路径
38
+ * @param {string} projectRoot - 项目根目录
39
+ * @returns {string} 项目记忆目录路径
40
+ */
41
+ export function getProjectMemoryDir(projectRoot) {
42
+ return path.join(projectRoot, '.autospec', MEMORY_DIRS.ROOT);
43
+ }
44
+
45
+ /**
46
+ * 解析记忆文件路径
47
+ * @param {string} scope - 作用域 ('global' | 'project')
48
+ * @param {string} relativePath - 相对路径
49
+ * @param {string} projectRoot - 项目根目录(project scope 时必需)
50
+ * @returns {string} 完整文件路径
51
+ */
52
+ export function resolveMemoryPath(scope, relativePath, projectRoot = null) {
53
+ if (scope === MEMORY_SCOPE.GLOBAL) {
54
+ return path.join(getGlobalMemoryDir(), relativePath);
55
+ } else {
56
+ if (!projectRoot) {
57
+ throw new Error('projectRoot is required for project scope');
58
+ }
59
+ return path.join(getProjectMemoryDir(projectRoot), relativePath);
60
+ }
61
+ }
62
+
63
+ /**
64
+ * 安全地读取 JSON 文件
65
+ * @param {string} filePath - 文件路径
66
+ * @param {any} defaultValue - 默认值
67
+ * @returns {any} 解析后的数据或默认值
68
+ */
69
+ function safeReadJson(filePath, defaultValue = null) {
70
+ try {
71
+ if (!fs.existsSync(filePath)) {
72
+ return defaultValue;
73
+ }
74
+ const content = fs.readFileSync(filePath, 'utf-8');
75
+ return JSON.parse(content);
76
+ } catch (e) {
77
+ return defaultValue;
78
+ }
79
+ }
80
+
81
+ /**
82
+ * 安全地写入 JSON 文件
83
+ * @param {string} filePath - 文件路径
84
+ * @param {any} data - 要写入的数据
85
+ * @returns {boolean} 是否成功
86
+ */
87
+ function safeWriteJson(filePath, data) {
88
+ try {
89
+ const dir = path.dirname(filePath);
90
+ if (!fs.existsSync(dir)) {
91
+ fs.mkdirSync(dir, { recursive: true });
92
+ }
93
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
94
+ return true;
95
+ } catch (e) {
96
+ if (e.code === 'EACCES') {
97
+ console.error(`[AutoSpec memory-manager] ⚠️ 权限错误: 无法写入 ${filePath}`);
98
+ console.error(`[AutoSpec memory-manager] 请运行: sudo chown -R $(whoami) ${path.dirname(filePath)}`);
99
+ }
100
+ return false;
101
+ }
102
+ }
103
+
104
+ // ============================================================
105
+ // Memory 读取操作
106
+ // ============================================================
107
+
108
+ /**
109
+ * 获取记忆内容
110
+ * @param {string} scope - 作用域 ('global' | 'project')
111
+ * @param {string} memoryFile - 记忆文件路径(相对)
112
+ * @param {string} projectRoot - 项目根目录(project scope 时必需)
113
+ * @param {boolean} useCache - 是否使用缓存
114
+ * @returns {Object|null} 记忆内容
115
+ */
116
+ export function getMemory(scope, memoryFile, projectRoot = null, useCache = false) {
117
+ const cacheKey = `${scope}:${memoryFile}:${projectRoot || 'global'}`;
118
+
119
+ if (useCache) {
120
+ const cached = memoryCache.get(cacheKey);
121
+ if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
122
+ return cached.data;
123
+ }
124
+ }
125
+
126
+ const filePath = resolveMemoryPath(scope, memoryFile, projectRoot);
127
+ const memory = safeReadJson(filePath, null);
128
+
129
+ if (useCache && memory) {
130
+ memoryCache.set(cacheKey, { data: memory, timestamp: Date.now() });
131
+ }
132
+
133
+ return memory;
134
+ }
135
+
136
+ /**
137
+ * 更新记忆内容
138
+ * @param {string} scope - 作用域 ('global' | 'project')
139
+ * @param {string} memoryFile - 记忆文件路径(相对)
140
+ * @param {Object} updates - 要更新的内容
141
+ * @param {string} projectRoot - 项目根目录(project scope 时必需)
142
+ * @returns {boolean} 是否成功
143
+ */
144
+ export function updateMemory(scope, memoryFile, updates, projectRoot = null) {
145
+ const existing = getMemory(scope, memoryFile, projectRoot, false) || {};
146
+ const newMemory = {
147
+ ...existing,
148
+ ...updates,
149
+ lastUpdated: new Date().toISOString()
150
+ };
151
+
152
+ const filePath = resolveMemoryPath(scope, memoryFile, projectRoot);
153
+ const success = safeWriteJson(filePath, newMemory);
154
+
155
+ if (success) {
156
+ const cacheKey = `${scope}:${memoryFile}:${projectRoot || 'global'}`;
157
+ memoryCache.set(cacheKey, { data: newMemory, timestamp: Date.now() });
158
+ }
159
+
160
+ return success;
161
+ }
162
+
163
+ // ============================================================
164
+ // 北极星指标 (项目级)
165
+ // ============================================================
166
+
167
+ /**
168
+ * 获取北极星指标
169
+ * @param {string} projectRoot - 项目根目录
170
+ * @returns {Object} 北极星指标
171
+ */
172
+ export function getNorthStar(projectRoot) {
173
+ return getMemory(MEMORY_SCOPE.PROJECT, MEMORY_FILES.NORTH_STAR, projectRoot, true)
174
+ || DEFAULT_NORTH_STAR;
175
+ }
176
+
177
+ /**
178
+ * 更新北极星指标
179
+ * @param {string} projectRoot - 项目根目录
180
+ * @param {Object} updates - 要更新的内容
181
+ * @returns {boolean} 是否成功
182
+ */
183
+ export function updateNorthStar(projectRoot, updates) {
184
+ return updateMemory(MEMORY_SCOPE.PROJECT, MEMORY_FILES.NORTH_STAR, updates, projectRoot);
185
+ }
186
+
187
+ /**
188
+ * 添加关键结果
189
+ * @param {string} projectRoot - 项目根目录
190
+ * @param {Object} keyResult - 关键结果
191
+ * @returns {boolean} 是否成功
192
+ */
193
+ export function addKeyResult(projectRoot, keyResult) {
194
+ const northStar = getNorthStar(projectRoot);
195
+ const newKR = {
196
+ id: `kr-${Date.now()}`,
197
+ ...keyResult,
198
+ status: keyResult.status || 'on-track'
199
+ };
200
+ northStar.keyResults = northStar.keyResults || [];
201
+ northStar.keyResults.push(newKR);
202
+ return updateNorthStar(projectRoot, { keyResults: northStar.keyResults });
203
+ }
204
+
205
+ /**
206
+ * 添加活跃决策
207
+ * @param {string} projectRoot - 项目根目录
208
+ * @param {Object} decision - 决策
209
+ * @returns {boolean} 是否成功
210
+ */
211
+ export function addActiveDecision(projectRoot, decision) {
212
+ const northStar = getNorthStar(projectRoot);
213
+ const newDecision = {
214
+ id: `dec-${Date.now()}`,
215
+ madeAt: new Date().toISOString().split('T')[0],
216
+ ...decision
217
+ };
218
+ northStar.activeDecisions = northStar.activeDecisions || [];
219
+ northStar.activeDecisions.push(newDecision);
220
+ return updateNorthStar(projectRoot, { activeDecisions: northStar.activeDecisions });
221
+ }
222
+
223
+ // ============================================================
224
+ // 团队偏好 (全局优先,项目可覆盖)
225
+ // ============================================================
226
+
227
+ /**
228
+ * 获取团队偏好(优先项目覆盖,fallback 全局)
229
+ * @param {string} projectRoot - 项目根目录
230
+ * @returns {Object} 团队偏好
231
+ */
232
+ export function getTeamPreferences(projectRoot) {
233
+ // 优先读取项目级偏好
234
+ const projectPrefs = getMemory(MEMORY_SCOPE.PROJECT, MEMORY_FILES.TEAM_PREFERENCES, projectRoot, true);
235
+ if (projectPrefs && Object.keys(projectPrefs).length > 1) {
236
+ return projectPrefs;
237
+ }
238
+
239
+ // Fallback 到全局偏好
240
+ const globalPrefs = getMemory(MEMORY_SCOPE.GLOBAL, MEMORY_FILES.TEAM_PREFERENCES, null, true);
241
+ if (globalPrefs && Object.keys(globalPrefs).length > 1) {
242
+ return globalPrefs;
243
+ }
244
+
245
+ return DEFAULT_TEAM_PREFERENCES;
246
+ }
247
+
248
+ /**
249
+ * 更新团队偏好
250
+ * @param {string} scope - 作用域 ('global' | 'project')
251
+ * @param {Object} updates - 要更新的内容
252
+ * @param {string} projectRoot - 项目根目录(project scope 时必需)
253
+ * @returns {boolean} 是否成功
254
+ */
255
+ export function updateTeamPreferences(scope, updates, projectRoot = null) {
256
+ return updateMemory(scope, MEMORY_FILES.TEAM_PREFERENCES, updates, projectRoot);
257
+ }
258
+
259
+ // ============================================================
260
+ // 约束条件 (全局优先,项目可覆盖)
261
+ // ============================================================
262
+
263
+ /**
264
+ * 获取约束条件(优先项目覆盖,fallback 全局)
265
+ * @param {string} projectRoot - 项目根目录
266
+ * @returns {Object} 约束条件
267
+ */
268
+ export function getConstraints(projectRoot) {
269
+ // 优先读取项目级约束
270
+ const projectConstraints = getMemory(MEMORY_SCOPE.PROJECT, MEMORY_FILES.CONSTRAINTS, projectRoot, true);
271
+ if (projectConstraints && (projectConstraints.hardConstraints?.length > 0 || projectConstraints.softConstraints?.length > 0)) {
272
+ return projectConstraints;
273
+ }
274
+
275
+ // Fallback 到全局约束
276
+ const globalConstraints = getMemory(MEMORY_SCOPE.GLOBAL, MEMORY_FILES.CONSTRAINTS, null, true);
277
+ if (globalConstraints && (globalConstraints.hardConstraints?.length > 0 || globalConstraints.softConstraints?.length > 0)) {
278
+ return globalConstraints;
279
+ }
280
+
281
+ return DEFAULT_CONSTRAINTS;
282
+ }
283
+
284
+ /**
285
+ * 添加硬约束
286
+ * @param {string} scope - 作用域
287
+ * @param {string} constraint - 约束内容
288
+ * @param {string} projectRoot - 项目根目录(project scope 时必需)
289
+ * @returns {boolean} 是否成功
290
+ */
291
+ export function addHardConstraint(scope, constraint, projectRoot = null) {
292
+ const constraints = getConstraints(projectRoot);
293
+ constraints.hardConstraints = constraints.hardConstraints || [];
294
+ constraints.hardConstraints.push({
295
+ id: `hc-${Date.now()}`,
296
+ content: constraint,
297
+ addedAt: new Date().toISOString()
298
+ });
299
+ return updateMemory(scope, MEMORY_FILES.CONSTRAINTS, constraints, projectRoot);
300
+ }
301
+
302
+ // ============================================================
303
+ // 当前上下文 (工作记忆)
304
+ // ============================================================
305
+
306
+ /**
307
+ * 获取当前任务上下文
308
+ * @param {string} projectRoot - 项目根目录
309
+ * @returns {Object|null} 当前上下文
310
+ */
311
+ export function getCurrentContext(projectRoot) {
312
+ return getMemory(MEMORY_SCOPE.PROJECT, MEMORY_FILES.CURRENT_CONTEXT, projectRoot, true);
313
+ }
314
+
315
+ /**
316
+ * 更新当前任务上下文
317
+ * @param {string} projectRoot - 项目根目录
318
+ * @param {Object} updates - 要更新的内容
319
+ * @returns {boolean} 是否成功
320
+ */
321
+ export function updateCurrentContext(projectRoot, updates) {
322
+ const existing = getCurrentContext(projectRoot) || {};
323
+ const newContext = {
324
+ ...existing,
325
+ ...updates,
326
+ updatedAt: new Date().toISOString()
327
+ };
328
+ return updateMemory(MEMORY_SCOPE.PROJECT, MEMORY_FILES.CURRENT_CONTEXT, newContext, projectRoot);
329
+ }
330
+
331
+ /**
332
+ * 清除当前任务上下文
333
+ * @param {string} projectRoot - 项目根目录
334
+ * @returns {boolean} 是否成功
335
+ */
336
+ export function clearCurrentContext(projectRoot) {
337
+ const filePath = resolveMemoryPath(MEMORY_SCOPE.PROJECT, MEMORY_FILES.CURRENT_CONTEXT, projectRoot);
338
+ try {
339
+ if (fs.existsSync(filePath)) {
340
+ fs.unlinkSync(filePath);
341
+ }
342
+ const cacheKey = `${MEMORY_SCOPE.PROJECT}:${MEMORY_FILES.CURRENT_CONTEXT}:${projectRoot}`;
343
+ memoryCache.delete(cacheKey);
344
+ return true;
345
+ } catch (e) {
346
+ return false;
347
+ }
348
+ }
349
+
350
+ // ============================================================
351
+ // 会话记忆
352
+ // ============================================================
353
+
354
+ /**
355
+ * 获取会话索引
356
+ * @param {string} projectRoot - 项目根目录
357
+ * @returns {Object} 会话索引
358
+ */
359
+ export function getSessionsIndex(projectRoot) {
360
+ return getMemory(MEMORY_SCOPE.PROJECT, MEMORY_FILES.SESSIONS_INDEX, projectRoot, true)
361
+ || { sessions: [], lastIndexed: null };
362
+ }
363
+
364
+ /**
365
+ * 添加会话记录
366
+ * @param {string} projectRoot - 项目根目录
367
+ * @param {Object} session - 会话信息
368
+ * @returns {boolean} 是否成功
369
+ */
370
+ export function addSession(projectRoot, session) {
371
+ const index = getSessionsIndex(projectRoot);
372
+ const newSession = {
373
+ id: `sess-${Date.now()}`,
374
+ date: new Date().toISOString().split('T')[0],
375
+ ...session
376
+ };
377
+
378
+ index.sessions = index.sessions || [];
379
+ index.sessions.unshift(newSession); // 最新的在前面
380
+ index.lastIndexed = new Date().toISOString();
381
+
382
+ // 保留最近 100 条
383
+ if (index.sessions.length > 100) {
384
+ index.sessions = index.sessions.slice(0, 100);
385
+ }
386
+
387
+ return updateMemory(MEMORY_SCOPE.PROJECT, MEMORY_FILES.SESSIONS_INDEX, index, projectRoot);
388
+ }
389
+
390
+ // ============================================================
391
+ // 项目记忆 (技术栈、架构等)
392
+ // ============================================================
393
+
394
+ /**
395
+ * 获取技术栈信息
396
+ * @param {string} projectRoot - 项目根目录
397
+ * @returns {Object} 技术栈信息
398
+ */
399
+ export function getTechStack(projectRoot) {
400
+ return getMemory(MEMORY_SCOPE.PROJECT, MEMORY_FILES.TECH_STACK, projectRoot, true) || {
401
+ primary: {},
402
+ tools: [],
403
+ patterns: []
404
+ };
405
+ }
406
+
407
+ /**
408
+ * 更新技术栈信息
409
+ * @param {string} projectRoot - 项目根目录
410
+ * @param {Object} updates - 要更新的内容
411
+ * @returns {boolean} 是否成功
412
+ */
413
+ export function updateTechStack(projectRoot, updates) {
414
+ return updateMemory(MEMORY_SCOPE.PROJECT, MEMORY_FILES.TECH_STACK, updates, projectRoot);
415
+ }
416
+
417
+ /**
418
+ * 获取架构决策记录
419
+ * @param {string} projectRoot - 项目根目录
420
+ * @returns {Object} 架构决策记录
421
+ */
422
+ export function getArchitecture(projectRoot) {
423
+ return getMemory(MEMORY_SCOPE.PROJECT, MEMORY_FILES.ARCHITECTURE, projectRoot, true) || {
424
+ version: '1.0',
425
+ decisions: []
426
+ };
427
+ }
428
+
429
+ /**
430
+ * 添加架构决策
431
+ * @param {string} projectRoot - 项目根目录
432
+ * @param {Object} decision - 决策内容
433
+ * @returns {boolean} 是否成功
434
+ */
435
+ export function addArchitectureDecision(projectRoot, decision) {
436
+ const arch = getArchitecture(projectRoot);
437
+ const newDecision = {
438
+ id: `adr-${Date.now()}`,
439
+ status: 'accepted',
440
+ decidedAt: new Date().toISOString().split('T')[0],
441
+ ...decision
442
+ };
443
+ arch.decisions = arch.decisions || [];
444
+ arch.decisions.unshift(newDecision);
445
+ return updateMemory(MEMORY_SCOPE.PROJECT, MEMORY_FILES.ARCHITECTURE, arch, projectRoot);
446
+ }
447
+
448
+ // ============================================================
449
+ // 记忆搜索
450
+ // ============================================================
451
+
452
+ /**
453
+ * 搜索记忆
454
+ * @param {string} projectRoot - 项目根目录
455
+ * @param {string} query - 搜索关键词
456
+ * @param {Array<string>} layers - 搜索层次
457
+ * @returns {Object} 搜索结果
458
+ */
459
+ export function searchMemory(projectRoot, query, layers = ['core', 'project']) {
460
+ const results = {
461
+ core: [],
462
+ project: []
463
+ };
464
+ const queryLower = query.toLowerCase();
465
+
466
+ // 搜索核心记忆
467
+ if (layers.includes('core')) {
468
+ const northStar = getNorthStar(projectRoot);
469
+ if (JSON.stringify(northStar).toLowerCase().includes(queryLower)) {
470
+ results.core.push({
471
+ file: MEMORY_FILES.NORTH_STAR,
472
+ type: 'north-star',
473
+ content: northStar
474
+ });
475
+ }
476
+
477
+ const preferences = getTeamPreferences(projectRoot);
478
+ if (JSON.stringify(preferences).toLowerCase().includes(queryLower)) {
479
+ results.core.push({
480
+ file: MEMORY_FILES.TEAM_PREFERENCES,
481
+ type: 'preferences',
482
+ content: preferences
483
+ });
484
+ }
485
+ }
486
+
487
+ // 搜索项目记忆
488
+ if (layers.includes('project')) {
489
+ const techStack = getTechStack(projectRoot);
490
+ if (JSON.stringify(techStack).toLowerCase().includes(queryLower)) {
491
+ results.project.push({
492
+ file: MEMORY_FILES.TECH_STACK,
493
+ type: 'tech-stack',
494
+ content: techStack
495
+ });
496
+ }
497
+
498
+ const architecture = getArchitecture(projectRoot);
499
+ const matchingDecisions = architecture.decisions?.filter(d =>
500
+ JSON.stringify(d).toLowerCase().includes(queryLower)
501
+ );
502
+ if (matchingDecisions?.length > 0) {
503
+ results.project.push({
504
+ file: MEMORY_FILES.ARCHITECTURE,
505
+ type: 'architecture',
506
+ content: matchingDecisions
507
+ });
508
+ }
509
+ }
510
+
511
+ return results;
512
+ }
513
+
514
+ // ============================================================
515
+ // 记忆初始化
516
+ // ============================================================
517
+
518
+ /**
519
+ * 初始化全局记忆目录
520
+ * @returns {boolean} 是否成功
521
+ */
522
+ export function initGlobalMemory() {
523
+ const globalDir = getGlobalMemoryDir();
524
+
525
+ try {
526
+ // 创建目录结构
527
+ Object.values(MEMORY_DIRS).forEach(dir => {
528
+ const fullPath = path.join(globalDir, dir);
529
+ if (!fs.existsSync(fullPath)) {
530
+ fs.mkdirSync(fullPath, { recursive: true });
531
+ }
532
+ });
533
+
534
+ // 创建默认文件
535
+ const defaultFiles = [
536
+ { path: MEMORY_FILES.TEAM_PREFERENCES, content: DEFAULT_TEAM_PREFERENCES },
537
+ { path: MEMORY_FILES.CONSTRAINTS, content: DEFAULT_CONSTRAINTS },
538
+ { path: MEMORY_FILES.MEMORY_META, content: { ...DEFAULT_MEMORY_META, scope: 'global' } }
539
+ ];
540
+
541
+ defaultFiles.forEach(({ path: relPath, content }) => {
542
+ const filePath = path.join(globalDir, relPath);
543
+ if (!fs.existsSync(filePath)) {
544
+ safeWriteJson(filePath, content);
545
+ }
546
+ });
547
+
548
+ return true;
549
+ } catch (e) {
550
+ console.error(`[AutoSpec memory-manager] 初始化全局记忆失败: ${e.message}`);
551
+ return false;
552
+ }
553
+ }
554
+
555
+ /**
556
+ * 初始化项目记忆目录
557
+ * @param {string} projectRoot - 项目根目录
558
+ * @returns {boolean} 是否成功
559
+ */
560
+ export function initProjectMemory(projectRoot) {
561
+ const projectDir = getProjectMemoryDir(projectRoot);
562
+
563
+ try {
564
+ // 创建目录结构
565
+ Object.values(MEMORY_DIRS).forEach(dir => {
566
+ const fullPath = path.join(projectDir, dir);
567
+ if (!fs.existsSync(fullPath)) {
568
+ fs.mkdirSync(fullPath, { recursive: true });
569
+ }
570
+ });
571
+
572
+ // 创建默认文件
573
+ const defaultFiles = [
574
+ { path: MEMORY_FILES.NORTH_STAR, content: DEFAULT_NORTH_STAR },
575
+ { path: MEMORY_FILES.MEMORY_META, content: { ...DEFAULT_MEMORY_META, scope: 'project' } }
576
+ ];
577
+
578
+ defaultFiles.forEach(({ path: relPath, content }) => {
579
+ const filePath = path.join(projectDir, relPath);
580
+ if (!fs.existsSync(filePath)) {
581
+ safeWriteJson(filePath, content);
582
+ }
583
+ });
584
+
585
+ return true;
586
+ } catch (e) {
587
+ console.error(`[AutoSpec memory-manager] 初始化项目记忆失败: ${e.message}`);
588
+ return false;
589
+ }
590
+ }
591
+
592
+ /**
593
+ * 检查全局记忆是否存在
594
+ * @returns {boolean} 是否存在
595
+ */
596
+ export function hasGlobalMemory() {
597
+ const globalDir = getGlobalMemoryDir();
598
+ return fs.existsSync(globalDir);
599
+ }
600
+
601
+ /**
602
+ * 检查项目记忆是否存在
603
+ * @param {string} projectRoot - 项目根目录
604
+ * @returns {boolean} 是否存在
605
+ */
606
+ export function hasProjectMemory(projectRoot) {
607
+ const projectDir = getProjectMemoryDir(projectRoot);
608
+ return fs.existsSync(projectDir);
609
+ }
610
+
611
+ // ============================================================
612
+ // 缓存管理
613
+ // ============================================================
614
+
615
+ /**
616
+ * 清除记忆缓存
617
+ * @param {string} scope - 作用域(可选,不提供则清除所有)
618
+ * @param {string} projectRoot - 项目根目录(可选)
619
+ */
620
+ export function clearMemoryCache(scope = null, projectRoot = null) {
621
+ if (scope && projectRoot) {
622
+ const prefix = `${scope}:`;
623
+ for (const key of memoryCache.keys()) {
624
+ if (key.startsWith(prefix)) {
625
+ memoryCache.delete(key);
626
+ }
627
+ }
628
+ } else {
629
+ memoryCache.clear();
630
+ }
631
+ }
632
+
633
+ export default {
634
+ // 路径解析
635
+ getGlobalMemoryDir,
636
+ getProjectMemoryDir,
637
+ resolveMemoryPath,
638
+ // 通用读写
639
+ getMemory,
640
+ updateMemory,
641
+ // 北极星指标
642
+ getNorthStar,
643
+ updateNorthStar,
644
+ addKeyResult,
645
+ addActiveDecision,
646
+ // 团队偏好
647
+ getTeamPreferences,
648
+ updateTeamPreferences,
649
+ // 约束条件
650
+ getConstraints,
651
+ addHardConstraint,
652
+ // 工作记忆
653
+ getCurrentContext,
654
+ updateCurrentContext,
655
+ clearCurrentContext,
656
+ // 会话记忆
657
+ getSessionsIndex,
658
+ addSession,
659
+ // 项目记忆
660
+ getTechStack,
661
+ updateTechStack,
662
+ getArchitecture,
663
+ addArchitectureDecision,
664
+ // 搜索
665
+ searchMemory,
666
+ // 初始化
667
+ initGlobalMemory,
668
+ initProjectMemory,
669
+ hasGlobalMemory,
670
+ hasProjectMemory,
671
+ // 缓存
672
+ clearMemoryCache
673
+ };