@specpow/framework 0.2.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 (362) hide show
  1. package/CHANGELOG.md +307 -0
  2. package/LICENSE +21 -0
  3. package/README.md +557 -0
  4. package/agents/controller/sdd-controller.md +55 -0
  5. package/agents/execution/java-codegen-agent.md +39 -0
  6. package/agents/execution/ui-codegen-agent.md +32 -0
  7. package/agents/ops/deploy-agent.md +181 -0
  8. package/agents/planning/db-designer-agent.md +30 -0
  9. package/agents/planning/prd-agent.md +31 -0
  10. package/agents/quality/review-agent.md +36 -0
  11. package/agents/quality/test-agent.md +33 -0
  12. package/bin/specpow.js +10 -0
  13. package/dist/cli/index.d.ts +7 -0
  14. package/dist/cli/index.d.ts.map +1 -0
  15. package/dist/cli/index.js +444 -0
  16. package/dist/cli/index.js.map +1 -0
  17. package/dist/commands/apply.d.ts +14 -0
  18. package/dist/commands/apply.d.ts.map +1 -0
  19. package/dist/commands/apply.js +195 -0
  20. package/dist/commands/apply.js.map +1 -0
  21. package/dist/commands/archive.d.ts +30 -0
  22. package/dist/commands/archive.d.ts.map +1 -0
  23. package/dist/commands/archive.js +141 -0
  24. package/dist/commands/archive.js.map +1 -0
  25. package/dist/commands/channel.d.ts +61 -0
  26. package/dist/commands/channel.d.ts.map +1 -0
  27. package/dist/commands/channel.js +613 -0
  28. package/dist/commands/channel.js.map +1 -0
  29. package/dist/commands/config.d.ts +40 -0
  30. package/dist/commands/config.d.ts.map +1 -0
  31. package/dist/commands/config.js +130 -0
  32. package/dist/commands/config.js.map +1 -0
  33. package/dist/commands/debug.d.ts +45 -0
  34. package/dist/commands/debug.d.ts.map +1 -0
  35. package/dist/commands/debug.js +167 -0
  36. package/dist/commands/debug.js.map +1 -0
  37. package/dist/commands/doctor.d.ts +20 -0
  38. package/dist/commands/doctor.d.ts.map +1 -0
  39. package/dist/commands/doctor.js +121 -0
  40. package/dist/commands/doctor.js.map +1 -0
  41. package/dist/commands/execute.d.ts +25 -0
  42. package/dist/commands/execute.d.ts.map +1 -0
  43. package/dist/commands/execute.js +120 -0
  44. package/dist/commands/execute.js.map +1 -0
  45. package/dist/commands/explore.d.ts +71 -0
  46. package/dist/commands/explore.d.ts.map +1 -0
  47. package/dist/commands/explore.js +481 -0
  48. package/dist/commands/explore.js.map +1 -0
  49. package/dist/commands/init.d.ts +20 -0
  50. package/dist/commands/init.d.ts.map +1 -0
  51. package/dist/commands/init.js +146 -0
  52. package/dist/commands/init.js.map +1 -0
  53. package/dist/commands/memory.d.ts +32 -0
  54. package/dist/commands/memory.d.ts.map +1 -0
  55. package/dist/commands/memory.js +455 -0
  56. package/dist/commands/memory.js.map +1 -0
  57. package/dist/commands/propose.d.ts +13 -0
  58. package/dist/commands/propose.d.ts.map +1 -0
  59. package/dist/commands/propose.js +193 -0
  60. package/dist/commands/propose.js.map +1 -0
  61. package/dist/commands/review.d.ts +50 -0
  62. package/dist/commands/review.d.ts.map +1 -0
  63. package/dist/commands/review.js +198 -0
  64. package/dist/commands/review.js.map +1 -0
  65. package/dist/commands/schema.d.ts +22 -0
  66. package/dist/commands/schema.d.ts.map +1 -0
  67. package/dist/commands/schema.js +79 -0
  68. package/dist/commands/schema.js.map +1 -0
  69. package/dist/commands/status.d.ts +11 -0
  70. package/dist/commands/status.d.ts.map +1 -0
  71. package/dist/commands/status.js +130 -0
  72. package/dist/commands/status.js.map +1 -0
  73. package/dist/commands/store.d.ts +31 -0
  74. package/dist/commands/store.d.ts.map +1 -0
  75. package/dist/commands/store.js +109 -0
  76. package/dist/commands/store.js.map +1 -0
  77. package/dist/commands/update.d.ts +42 -0
  78. package/dist/commands/update.d.ts.map +1 -0
  79. package/dist/commands/update.js +239 -0
  80. package/dist/commands/update.js.map +1 -0
  81. package/dist/commands/verify.d.ts +39 -0
  82. package/dist/commands/verify.d.ts.map +1 -0
  83. package/dist/commands/verify.js +386 -0
  84. package/dist/commands/verify.js.map +1 -0
  85. package/dist/commands/workflow/index.d.ts +12 -0
  86. package/dist/commands/workflow/index.d.ts.map +1 -0
  87. package/dist/commands/workflow/index.js +435 -0
  88. package/dist/commands/workflow/index.js.map +1 -0
  89. package/dist/core/agent-contract.d.ts +133 -0
  90. package/dist/core/agent-contract.d.ts.map +1 -0
  91. package/dist/core/agent-contract.js +71 -0
  92. package/dist/core/agent-contract.js.map +1 -0
  93. package/dist/core/archive/delta-merger.d.ts +101 -0
  94. package/dist/core/archive/delta-merger.d.ts.map +1 -0
  95. package/dist/core/archive/delta-merger.js +398 -0
  96. package/dist/core/archive/delta-merger.js.map +1 -0
  97. package/dist/core/archive/delta-parser.d.ts +48 -0
  98. package/dist/core/archive/delta-parser.d.ts.map +1 -0
  99. package/dist/core/archive/delta-parser.js +193 -0
  100. package/dist/core/archive/delta-parser.js.map +1 -0
  101. package/dist/core/archive/engine.d.ts +136 -0
  102. package/dist/core/archive/engine.d.ts.map +1 -0
  103. package/dist/core/archive/engine.js +506 -0
  104. package/dist/core/archive/engine.js.map +1 -0
  105. package/dist/core/archive/index.d.ts +11 -0
  106. package/dist/core/archive/index.d.ts.map +1 -0
  107. package/dist/core/archive/index.js +9 -0
  108. package/dist/core/archive/index.js.map +1 -0
  109. package/dist/core/artifact-graph/graph.d.ts +48 -0
  110. package/dist/core/artifact-graph/graph.d.ts.map +1 -0
  111. package/dist/core/artifact-graph/graph.js +170 -0
  112. package/dist/core/artifact-graph/graph.js.map +1 -0
  113. package/dist/core/artifact-graph/index.d.ts +13 -0
  114. package/dist/core/artifact-graph/index.d.ts.map +1 -0
  115. package/dist/core/artifact-graph/index.js +12 -0
  116. package/dist/core/artifact-graph/index.js.map +1 -0
  117. package/dist/core/artifact-graph/instruction-loader.d.ts +60 -0
  118. package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -0
  119. package/dist/core/artifact-graph/instruction-loader.js +166 -0
  120. package/dist/core/artifact-graph/instruction-loader.js.map +1 -0
  121. package/dist/core/artifact-graph/outputs.d.ts +17 -0
  122. package/dist/core/artifact-graph/outputs.d.ts.map +1 -0
  123. package/dist/core/artifact-graph/outputs.js +27 -0
  124. package/dist/core/artifact-graph/outputs.js.map +1 -0
  125. package/dist/core/artifact-graph/resolver.d.ts +34 -0
  126. package/dist/core/artifact-graph/resolver.d.ts.map +1 -0
  127. package/dist/core/artifact-graph/resolver.js +99 -0
  128. package/dist/core/artifact-graph/resolver.js.map +1 -0
  129. package/dist/core/artifact-graph/state.d.ts +54 -0
  130. package/dist/core/artifact-graph/state.d.ts.map +1 -0
  131. package/dist/core/artifact-graph/state.js +149 -0
  132. package/dist/core/artifact-graph/state.js.map +1 -0
  133. package/dist/core/artifact-graph/types.d.ts +151 -0
  134. package/dist/core/artifact-graph/types.d.ts.map +1 -0
  135. package/dist/core/artifact-graph/types.js +44 -0
  136. package/dist/core/artifact-graph/types.js.map +1 -0
  137. package/dist/core/channel/channel-event-log.d.ts +81 -0
  138. package/dist/core/channel/channel-event-log.d.ts.map +1 -0
  139. package/dist/core/channel/channel-event-log.js +177 -0
  140. package/dist/core/channel/channel-event-log.js.map +1 -0
  141. package/dist/core/channel/channel-inbox.d.ts +70 -0
  142. package/dist/core/channel/channel-inbox.d.ts.map +1 -0
  143. package/dist/core/channel/channel-inbox.js +122 -0
  144. package/dist/core/channel/channel-inbox.js.map +1 -0
  145. package/dist/core/channel/channel-runtime.d.ts +81 -0
  146. package/dist/core/channel/channel-runtime.d.ts.map +1 -0
  147. package/dist/core/channel/channel-runtime.js +291 -0
  148. package/dist/core/channel/channel-runtime.js.map +1 -0
  149. package/dist/core/channel/channel-supervisor.d.ts +72 -0
  150. package/dist/core/channel/channel-supervisor.d.ts.map +1 -0
  151. package/dist/core/channel/channel-supervisor.js +189 -0
  152. package/dist/core/channel/channel-supervisor.js.map +1 -0
  153. package/dist/core/channel/channel-types.d.ts +169 -0
  154. package/dist/core/channel/channel-types.d.ts.map +1 -0
  155. package/dist/core/channel/channel-types.js +26 -0
  156. package/dist/core/channel/channel-types.js.map +1 -0
  157. package/dist/core/channel/index.d.ts +21 -0
  158. package/dist/core/channel/index.d.ts.map +1 -0
  159. package/dist/core/channel/index.js +23 -0
  160. package/dist/core/channel/index.js.map +1 -0
  161. package/dist/core/command-generation/index.d.ts +225 -0
  162. package/dist/core/command-generation/index.d.ts.map +1 -0
  163. package/dist/core/command-generation/index.js +462 -0
  164. package/dist/core/command-generation/index.js.map +1 -0
  165. package/dist/core/config/config-schema.d.ts +745 -0
  166. package/dist/core/config/config-schema.d.ts.map +1 -0
  167. package/dist/core/config/config-schema.js +108 -0
  168. package/dist/core/config/config-schema.js.map +1 -0
  169. package/dist/core/config/global-config.d.ts +73 -0
  170. package/dist/core/config/global-config.d.ts.map +1 -0
  171. package/dist/core/config/global-config.js +225 -0
  172. package/dist/core/config/global-config.js.map +1 -0
  173. package/dist/core/config/index.d.ts +8 -0
  174. package/dist/core/config/index.d.ts.map +1 -0
  175. package/dist/core/config/index.js +8 -0
  176. package/dist/core/config/index.js.map +1 -0
  177. package/dist/core/hooks/hook-registry.d.ts +55 -0
  178. package/dist/core/hooks/hook-registry.d.ts.map +1 -0
  179. package/dist/core/hooks/hook-registry.js +172 -0
  180. package/dist/core/hooks/hook-registry.js.map +1 -0
  181. package/dist/core/hooks/hook-types.d.ts +87 -0
  182. package/dist/core/hooks/hook-types.d.ts.map +1 -0
  183. package/dist/core/hooks/hook-types.js +11 -0
  184. package/dist/core/hooks/hook-types.js.map +1 -0
  185. package/dist/core/hooks/index.d.ts +28 -0
  186. package/dist/core/hooks/index.d.ts.map +1 -0
  187. package/dist/core/hooks/index.js +28 -0
  188. package/dist/core/hooks/index.js.map +1 -0
  189. package/dist/core/hooks/post-tool-call-hook.d.ts +21 -0
  190. package/dist/core/hooks/post-tool-call-hook.d.ts.map +1 -0
  191. package/dist/core/hooks/post-tool-call-hook.js +191 -0
  192. package/dist/core/hooks/post-tool-call-hook.js.map +1 -0
  193. package/dist/core/hooks/pre-tool-call-hook.d.ts +31 -0
  194. package/dist/core/hooks/pre-tool-call-hook.d.ts.map +1 -0
  195. package/dist/core/hooks/pre-tool-call-hook.js +122 -0
  196. package/dist/core/hooks/pre-tool-call-hook.js.map +1 -0
  197. package/dist/core/hooks/session-start-hook.d.ts +25 -0
  198. package/dist/core/hooks/session-start-hook.d.ts.map +1 -0
  199. package/dist/core/hooks/session-start-hook.js +226 -0
  200. package/dist/core/hooks/session-start-hook.js.map +1 -0
  201. package/dist/core/hooks/workflow-state-hook.d.ts +18 -0
  202. package/dist/core/hooks/workflow-state-hook.d.ts.map +1 -0
  203. package/dist/core/hooks/workflow-state-hook.js +181 -0
  204. package/dist/core/hooks/workflow-state-hook.js.map +1 -0
  205. package/dist/core/init/engine.d.ts +69 -0
  206. package/dist/core/init/engine.d.ts.map +1 -0
  207. package/dist/core/init/engine.js +211 -0
  208. package/dist/core/init/engine.js.map +1 -0
  209. package/dist/core/init/template-hash.d.ts +86 -0
  210. package/dist/core/init/template-hash.d.ts.map +1 -0
  211. package/dist/core/init/template-hash.js +228 -0
  212. package/dist/core/init/template-hash.js.map +1 -0
  213. package/dist/core/memory/adapters/json-adapter.d.ts +50 -0
  214. package/dist/core/memory/adapters/json-adapter.d.ts.map +1 -0
  215. package/dist/core/memory/adapters/json-adapter.js +273 -0
  216. package/dist/core/memory/adapters/json-adapter.js.map +1 -0
  217. package/dist/core/memory/adapters/sqlite-adapter.d.ts +26 -0
  218. package/dist/core/memory/adapters/sqlite-adapter.d.ts.map +1 -0
  219. package/dist/core/memory/adapters/sqlite-adapter.js +230 -0
  220. package/dist/core/memory/adapters/sqlite-adapter.js.map +1 -0
  221. package/dist/core/memory/index.d.ts +38 -0
  222. package/dist/core/memory/index.d.ts.map +1 -0
  223. package/dist/core/memory/index.js +40 -0
  224. package/dist/core/memory/index.js.map +1 -0
  225. package/dist/core/memory/memory-indexer.d.ts +39 -0
  226. package/dist/core/memory/memory-indexer.d.ts.map +1 -0
  227. package/dist/core/memory/memory-indexer.js +213 -0
  228. package/dist/core/memory/memory-indexer.js.map +1 -0
  229. package/dist/core/memory/memory-manager.d.ts +59 -0
  230. package/dist/core/memory/memory-manager.d.ts.map +1 -0
  231. package/dist/core/memory/memory-manager.js +194 -0
  232. package/dist/core/memory/memory-manager.js.map +1 -0
  233. package/dist/core/memory/memory-store.d.ts +31 -0
  234. package/dist/core/memory/memory-store.d.ts.map +1 -0
  235. package/dist/core/memory/memory-store.js +148 -0
  236. package/dist/core/memory/memory-store.js.map +1 -0
  237. package/dist/core/memory/memory-types.d.ts +154 -0
  238. package/dist/core/memory/memory-types.d.ts.map +1 -0
  239. package/dist/core/memory/memory-types.js +13 -0
  240. package/dist/core/memory/memory-types.js.map +1 -0
  241. package/dist/core/migration/index.d.ts +80 -0
  242. package/dist/core/migration/index.d.ts.map +1 -0
  243. package/dist/core/migration/index.js +361 -0
  244. package/dist/core/migration/index.js.map +1 -0
  245. package/dist/core/parsers/index.d.ts +95 -0
  246. package/dist/core/parsers/index.d.ts.map +1 -0
  247. package/dist/core/parsers/index.js +367 -0
  248. package/dist/core/parsers/index.js.map +1 -0
  249. package/dist/core/sdd-engine/ai-caller.d.ts +118 -0
  250. package/dist/core/sdd-engine/ai-caller.d.ts.map +1 -0
  251. package/dist/core/sdd-engine/ai-caller.js +624 -0
  252. package/dist/core/sdd-engine/ai-caller.js.map +1 -0
  253. package/dist/core/sdd-engine/controller.d.ts +107 -0
  254. package/dist/core/sdd-engine/controller.d.ts.map +1 -0
  255. package/dist/core/sdd-engine/controller.js +357 -0
  256. package/dist/core/sdd-engine/controller.js.map +1 -0
  257. package/dist/core/sdd-engine/dispatcher.d.ts +69 -0
  258. package/dist/core/sdd-engine/dispatcher.d.ts.map +1 -0
  259. package/dist/core/sdd-engine/dispatcher.js +146 -0
  260. package/dist/core/sdd-engine/dispatcher.js.map +1 -0
  261. package/dist/core/sdd-engine/git-ops.d.ts +73 -0
  262. package/dist/core/sdd-engine/git-ops.d.ts.map +1 -0
  263. package/dist/core/sdd-engine/git-ops.js +326 -0
  264. package/dist/core/sdd-engine/git-ops.js.map +1 -0
  265. package/dist/core/sdd-engine/index.d.ts +17 -0
  266. package/dist/core/sdd-engine/index.d.ts.map +1 -0
  267. package/dist/core/sdd-engine/index.js +15 -0
  268. package/dist/core/sdd-engine/index.js.map +1 -0
  269. package/dist/core/sdd-engine/ledger.d.ts +92 -0
  270. package/dist/core/sdd-engine/ledger.d.ts.map +1 -0
  271. package/dist/core/sdd-engine/ledger.js +273 -0
  272. package/dist/core/sdd-engine/ledger.js.map +1 -0
  273. package/dist/core/sdd-engine/model-selector.d.ts +49 -0
  274. package/dist/core/sdd-engine/model-selector.d.ts.map +1 -0
  275. package/dist/core/sdd-engine/model-selector.js +76 -0
  276. package/dist/core/sdd-engine/model-selector.js.map +1 -0
  277. package/dist/core/sdd-engine/parallel-dispatcher.d.ts +99 -0
  278. package/dist/core/sdd-engine/parallel-dispatcher.d.ts.map +1 -0
  279. package/dist/core/sdd-engine/parallel-dispatcher.js +350 -0
  280. package/dist/core/sdd-engine/parallel-dispatcher.js.map +1 -0
  281. package/dist/core/sdd-engine/review-loop.d.ts +61 -0
  282. package/dist/core/sdd-engine/review-loop.d.ts.map +1 -0
  283. package/dist/core/sdd-engine/review-loop.js +139 -0
  284. package/dist/core/sdd-engine/review-loop.js.map +1 -0
  285. package/dist/core/sdd-engine/types.d.ts +104 -0
  286. package/dist/core/sdd-engine/types.d.ts.map +1 -0
  287. package/dist/core/sdd-engine/types.js +7 -0
  288. package/dist/core/sdd-engine/types.js.map +1 -0
  289. package/dist/core/store/index.d.ts +78 -0
  290. package/dist/core/store/index.d.ts.map +1 -0
  291. package/dist/core/store/index.js +182 -0
  292. package/dist/core/store/index.js.map +1 -0
  293. package/dist/core/templates/index.d.ts +58 -0
  294. package/dist/core/templates/index.d.ts.map +1 -0
  295. package/dist/core/templates/index.js +158 -0
  296. package/dist/core/templates/index.js.map +1 -0
  297. package/dist/core/validation/index.d.ts +34 -0
  298. package/dist/core/validation/index.d.ts.map +1 -0
  299. package/dist/core/validation/index.js +153 -0
  300. package/dist/core/validation/index.js.map +1 -0
  301. package/dist/core/workflow-state.d.ts +96 -0
  302. package/dist/core/workflow-state.d.ts.map +1 -0
  303. package/dist/core/workflow-state.js +284 -0
  304. package/dist/core/workflow-state.js.map +1 -0
  305. package/dist/index.d.ts +18 -0
  306. package/dist/index.d.ts.map +1 -0
  307. package/dist/index.js +21 -0
  308. package/dist/index.js.map +1 -0
  309. package/dist/utils/index.d.ts +48 -0
  310. package/dist/utils/index.d.ts.map +1 -0
  311. package/dist/utils/index.js +119 -0
  312. package/dist/utils/index.js.map +1 -0
  313. package/hooks/hooks.json +30 -0
  314. package/hooks/run-hook.cmd +19 -0
  315. package/hooks/session-start +62 -0
  316. package/hooks/workflow-state +150 -0
  317. package/package.json +122 -0
  318. package/schemas/bug-fix/schema.yaml +64 -0
  319. package/schemas/bug-fix/templates/analysis.md +43 -0
  320. package/schemas/bug-fix/templates/fix-plan.md +19 -0
  321. package/schemas/bug-fix/templates/proposal.md +30 -0
  322. package/schemas/crud-module/schema.yaml +65 -0
  323. package/schemas/crud-module/templates/design.md +36 -0
  324. package/schemas/crud-module/templates/proposal.md +30 -0
  325. package/schemas/crud-module/templates/spec.md +33 -0
  326. package/schemas/crud-module/templates/tasks.md +57 -0
  327. package/schemas/spec-driven/schema.yaml +87 -0
  328. package/schemas/spec-driven/templates/design.md +54 -0
  329. package/schemas/spec-driven/templates/proposal.md +31 -0
  330. package/schemas/spec-driven/templates/spec.md +44 -0
  331. package/schemas/spec-driven/templates/tasks.md +98 -0
  332. package/skills/business-code-review/SKILL.md +78 -0
  333. package/skills/business-db-design/SKILL.md +74 -0
  334. package/skills/business-deploy-check/SKILL.md +72 -0
  335. package/skills/business-doc-sync/SKILL.md +72 -0
  336. package/skills/business-java-codegen/SKILL.md +97 -0
  337. package/skills/business-menu-register/SKILL.md +63 -0
  338. package/skills/business-prd-writer/SKILL.md +80 -0
  339. package/skills/business-test-gen/SKILL.md +82 -0
  340. package/skills/business-ui-codegen/SKILL.md +104 -0
  341. package/skills/execution-finish-branch/SKILL.md +58 -0
  342. package/skills/execution-git-worktrees/SKILL.md +48 -0
  343. package/skills/execution-parallel-agents/SKILL.md +51 -0
  344. package/skills/execution-receiving-review/SKILL.md +47 -0
  345. package/skills/execution-requesting-review/SKILL.md +51 -0
  346. package/skills/execution-subagent-driven-dev/SKILL.md +148 -0
  347. package/skills/execution-systematic-debugging/SKILL.md +95 -0
  348. package/skills/execution-tdd/SKILL.md +74 -0
  349. package/skills/execution-verification-before-completion/SKILL.md +75 -0
  350. package/skills/meta-create-skill/SKILL.md +374 -0
  351. package/skills/meta-using-skills/SKILL.md +97 -0
  352. package/skills/meta-writing-skills/SKILL.md +66 -0
  353. package/skills/planning-apply-change/SKILL.md +199 -0
  354. package/skills/planning-archive-change/SKILL.md +43 -0
  355. package/skills/planning-explore/SKILL.md +108 -0
  356. package/skills/planning-onboard/SKILL.md +60 -0
  357. package/skills/planning-propose/SKILL.md +145 -0
  358. package/skills/planning-update-change/SKILL.md +45 -0
  359. package/skills/planning-verify-change/SKILL.md +58 -0
  360. package/skills/planning-write-design/SKILL.md +59 -0
  361. package/skills/planning-write-plans/SKILL.md +55 -0
  362. package/skills/planning-write-specs/SKILL.md +73 -0
@@ -0,0 +1,146 @@
1
+ /**
2
+ * init 命令 - 初始化项目
3
+ *
4
+ * 委托给 core/init/engine.ts 的 InitEngine
5
+ * InitEngine 提供完整的初始化流程:
6
+ * - AI 工具检测(自动发现已安装的 AI 工具)
7
+ * - 目录结构创建
8
+ * - 技能和命令生成
9
+ * - 配置文件初始化
10
+ *
11
+ * P1-10: 集成模板哈希增量更新
12
+ */
13
+ import chalk from 'chalk';
14
+ import { existsSync, readdirSync, readFileSync } from 'fs';
15
+ import { join, dirname, relative } from 'path';
16
+ import { fileURLToPath } from 'url';
17
+ import { InitEngine } from '../core/init/engine.js';
18
+ import { TemplateHashManager } from '../core/init/template-hash.js';
19
+ export async function initProject(options) {
20
+ const projectRoot = process.cwd();
21
+ const tool = options.tool || 'claude';
22
+ const force = options.force || false;
23
+ console.log(chalk.cyan('\n🚀 SpecPow Framework 初始化\n'));
24
+ console.log(` 目标工具: ${chalk.bold(tool)}`);
25
+ console.log(` 项目目录: ${chalk.dim(projectRoot)}\n`);
26
+ const engine = new InitEngine(projectRoot);
27
+ const hashManager = new TemplateHashManager(projectRoot);
28
+ // --force 时重置哈希存储
29
+ if (force) {
30
+ hashManager.reset();
31
+ }
32
+ try {
33
+ const result = await engine.initialize({
34
+ tools: tool,
35
+ force: force,
36
+ quiet: false,
37
+ });
38
+ // 输出检测到的工具
39
+ if (result.toolsDetected.length > 0) {
40
+ console.log(chalk.dim(' 检测到的 AI 工具:'));
41
+ for (const detected of result.toolsDetected) {
42
+ if (detected.available) {
43
+ console.log(chalk.green(` ✓ ${detected.name} (${detected.toolId})`));
44
+ }
45
+ }
46
+ console.log('');
47
+ }
48
+ // 输出创建的目录
49
+ if (result.dirsCreated.length > 0) {
50
+ console.log(chalk.dim(' 创建的目录:'));
51
+ for (const dir of result.dirsCreated.slice(0, 10)) {
52
+ console.log(chalk.green(` ✓ ${dir}`));
53
+ }
54
+ if (result.dirsCreated.length > 10) {
55
+ console.log(chalk.dim(` ... 及其他 ${result.dirsCreated.length - 10} 个目录`));
56
+ }
57
+ console.log('');
58
+ }
59
+ // 输出警告
60
+ for (const warning of result.warnings) {
61
+ console.log(chalk.yellow(` ⚠ ${warning}`));
62
+ }
63
+ // P1-10: 使用哈希管理器复制内置 Schema(增量更新)
64
+ const hashResult = copyBuiltinSchemasWithHash(projectRoot, hashManager);
65
+ if (hashResult.copied > 0) {
66
+ console.log(chalk.green(` ✓ 新增/更新 ${hashResult.copied} 个 Schema 文件`));
67
+ }
68
+ if (hashResult.skipped > 0) {
69
+ console.log(chalk.dim(` ○ 跳过 ${hashResult.skipped} 个未变化文件`));
70
+ }
71
+ if (hashResult.userModified.length > 0) {
72
+ console.log(chalk.yellow(` ⚠ ${hashResult.userModified.length} 个文件已被用户修改,新版本保存为 .new`));
73
+ }
74
+ console.log(chalk.cyan('\n✅ 初始化完成!\n'));
75
+ console.log('下一步:');
76
+ console.log(` 1. ${chalk.bold('specpow explore "你的需求"')} — 探索需求`);
77
+ console.log(` 2. ${chalk.bold('specpow propose <name>')} — 创建变更提案`);
78
+ console.log(` 3. ${chalk.bold('specpow apply')} — 执行实现`);
79
+ console.log('');
80
+ }
81
+ catch (err) {
82
+ console.log(chalk.red(`\n❌ 初始化失败: ${err.message}\n`));
83
+ }
84
+ }
85
+ /**
86
+ * P1-10: 使用模板哈希管理器复制内置 Schema
87
+ * 实现增量更新:未变化的文件跳过,用户修改的文件创建 .new
88
+ */
89
+ function copyBuiltinSchemasWithHash(projectRoot, hashManager) {
90
+ // 定位包的 schemas 目录(兼容 ESM 和开发模式)
91
+ let packageSchemasDir;
92
+ try {
93
+ const thisFile = fileURLToPath(import.meta.url);
94
+ packageSchemasDir = join(dirname(thisFile), '..', '..', 'schemas');
95
+ }
96
+ catch {
97
+ return { copied: 0, skipped: 0, userModified: [] };
98
+ }
99
+ if (!existsSync(packageSchemasDir))
100
+ return { copied: 0, skipped: 0, userModified: [] };
101
+ const targetSchemasDir = join(projectRoot, 'schemas');
102
+ const files = [];
103
+ try {
104
+ const entries = readdirSync(packageSchemasDir, { withFileTypes: true });
105
+ for (const entry of entries) {
106
+ if (!entry.isDirectory())
107
+ continue;
108
+ const srcDir = join(packageSchemasDir, entry.name);
109
+ collectFiles(srcDir, join(targetSchemasDir, entry.name), projectRoot, files);
110
+ }
111
+ }
112
+ catch (e) {
113
+ console.warn(`Warning: failed to read builtin schemas: ${e.message}`);
114
+ return { copied: 0, skipped: 0, userModified: [] };
115
+ }
116
+ // 使用哈希管理器批量处理
117
+ const result = hashManager.processFiles(files);
118
+ return {
119
+ copied: result.added.length + result.updated.length,
120
+ skipped: result.skipped.length,
121
+ userModified: result.userModified,
122
+ };
123
+ }
124
+ /**
125
+ * 递归收集目录中的文件
126
+ */
127
+ function collectFiles(srcDir, destDir, projectRoot, files) {
128
+ if (!existsSync(srcDir))
129
+ return;
130
+ const entries = readdirSync(srcDir, { withFileTypes: true });
131
+ for (const entry of entries) {
132
+ const srcPath = join(srcDir, entry.name);
133
+ const destPath = join(destDir, entry.name);
134
+ if (entry.isDirectory()) {
135
+ collectFiles(srcPath, destPath, projectRoot, files);
136
+ }
137
+ else {
138
+ const content = readFileSync(srcPath, 'utf-8');
139
+ files.push({
140
+ path: relative(projectRoot, destPath),
141
+ content,
142
+ });
143
+ }
144
+ }
145
+ }
146
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Memory CLI 命令
3
+ *
4
+ * 提供跨会话记忆的索引、搜索、统计、时间线、阶段切片、清除功能。
5
+ * 复用 src/core/memory/ 的 createMemoryManager、extractKeywords、detectPhase、calculateRelevance。
6
+ */
7
+ export declare function memoryIndex(sessionFile: string, options: {
8
+ json?: boolean;
9
+ }): Promise<void>;
10
+ export declare function memorySearch(keywords: string[], options: {
11
+ phase?: string;
12
+ session?: string;
13
+ limit?: string;
14
+ minRelevance?: string;
15
+ json?: boolean;
16
+ }): Promise<void>;
17
+ export declare function memoryStats(options: {
18
+ json?: boolean;
19
+ }): Promise<void>;
20
+ export declare function memoryTimeline(options: {
21
+ limit?: string;
22
+ json?: boolean;
23
+ }): Promise<void>;
24
+ export declare function memoryPhases(phase: string, options: {
25
+ limit?: string;
26
+ json?: boolean;
27
+ }): Promise<void>;
28
+ export declare function memoryClear(options: {
29
+ json?: boolean;
30
+ yes?: boolean;
31
+ }): Promise<void>;
32
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/commands/memory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA0DH,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CAmEf;AAMD,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,EAAE;IACP,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GACA,OAAO,CAAC,IAAI,CAAC,CA2Gf;AAMD,wBAAsB,WAAW,CAC/B,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CAwCf;AAMD,wBAAsB,cAAc,CAClC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1C,OAAO,CAAC,IAAI,CAAC,CA4Df;AAMD,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1C,OAAO,CAAC,IAAI,CAAC,CAuEf;AAMD,wBAAsB,WAAW,CAC/B,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GACzC,OAAO,CAAC,IAAI,CAAC,CA2Cf"}
@@ -0,0 +1,455 @@
1
+ /**
2
+ * Memory CLI 命令
3
+ *
4
+ * 提供跨会话记忆的索引、搜索、统计、时间线、阶段切片、清除功能。
5
+ * 复用 src/core/memory/ 的 createMemoryManager、extractKeywords、detectPhase、calculateRelevance。
6
+ */
7
+ import chalk from 'chalk';
8
+ import { readFileSync, existsSync } from 'fs';
9
+ import { join } from 'path';
10
+ import { createMemoryManager, } from '../core/memory/index.js';
11
+ import { successResponse, errorResponse, outputJson } from '../core/agent-contract.js';
12
+ // ============================================================
13
+ // 辅助函数
14
+ // ============================================================
15
+ /** 格式化时间戳为可读字符串 */
16
+ function formatTime(ts) {
17
+ const d = new Date(ts);
18
+ const now = Date.now();
19
+ const diff = now - ts;
20
+ if (diff < 60_000)
21
+ return '刚刚';
22
+ if (diff < 3_600_000)
23
+ return `${Math.floor(diff / 60_000)} 分钟前`;
24
+ if (diff < 86_400_000)
25
+ return `${Math.floor(diff / 3_600_000)} 小时前`;
26
+ if (diff < 604_800_000)
27
+ return `${Math.floor(diff / 86_400_000)} 天前`;
28
+ return d.toLocaleDateString('zh-CN', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' });
29
+ }
30
+ /** 格式化字节数 */
31
+ function formatBytes(bytes) {
32
+ if (bytes < 1024)
33
+ return `${bytes} B`;
34
+ if (bytes < 1_048_576)
35
+ return `${(bytes / 1024).toFixed(1)} KB`;
36
+ return `${(bytes / 1_048_576).toFixed(1)} MB`;
37
+ }
38
+ /** 阶段名称映射 */
39
+ const PHASE_LABELS = {
40
+ explore: '探索',
41
+ propose: '提案',
42
+ apply: '实现',
43
+ verify: '验证',
44
+ archive: '归档',
45
+ general: '通用',
46
+ };
47
+ /** 截断文本 */
48
+ function truncate(text, maxLen) {
49
+ if (text.length <= maxLen)
50
+ return text;
51
+ return text.slice(0, maxLen - 3) + '...';
52
+ }
53
+ // ============================================================
54
+ // memory index — 索引会话日志
55
+ // ============================================================
56
+ export async function memoryIndex(sessionFile, options) {
57
+ const jsonMode = !!options.json;
58
+ const projectRoot = process.cwd();
59
+ // 验证文件存在
60
+ const filePath = join(projectRoot, sessionFile);
61
+ if (!existsSync(filePath)) {
62
+ const msg = `会话日志文件不存在: ${sessionFile}`;
63
+ if (jsonMode) {
64
+ outputJson(errorResponse(msg, 'FILE_NOT_FOUND'));
65
+ }
66
+ else {
67
+ console.log(chalk.red(msg));
68
+ }
69
+ return;
70
+ }
71
+ // 读取并解析 JSON
72
+ let sessionLog;
73
+ try {
74
+ const raw = readFileSync(filePath, 'utf-8');
75
+ sessionLog = JSON.parse(raw);
76
+ }
77
+ catch (err) {
78
+ const msg = `无法解析会话日志文件: ${err instanceof Error ? err.message : String(err)}`;
79
+ if (jsonMode) {
80
+ outputJson(errorResponse(msg, 'PARSE_ERROR'));
81
+ }
82
+ else {
83
+ console.log(chalk.red(msg));
84
+ }
85
+ return;
86
+ }
87
+ // 验证基本结构
88
+ if (!sessionLog.sessionId || !Array.isArray(sessionLog.messages)) {
89
+ const msg = '会话日志格式无效: 需要 sessionId 和 messages 数组';
90
+ if (jsonMode) {
91
+ outputJson(errorResponse(msg, 'INVALID_FORMAT'));
92
+ }
93
+ else {
94
+ console.log(chalk.red(msg));
95
+ }
96
+ return;
97
+ }
98
+ try {
99
+ const manager = createMemoryManager(projectRoot);
100
+ const count = await manager.indexSession(sessionLog);
101
+ if (jsonMode) {
102
+ outputJson(successResponse({
103
+ sessionId: sessionLog.sessionId,
104
+ messageCount: sessionLog.messages.length,
105
+ indexedEntries: count,
106
+ message: '会话索引完成',
107
+ }));
108
+ }
109
+ else {
110
+ console.log(chalk.green('✓ 会话索引完成'));
111
+ console.log(` 会话 ID: ${chalk.cyan(sessionLog.sessionId)}`);
112
+ console.log(` 消息总数: ${sessionLog.messages.length}`);
113
+ console.log(` 索引条目: ${chalk.cyan(String(count))}`);
114
+ }
115
+ }
116
+ catch (err) {
117
+ const msg = `索引失败: ${err instanceof Error ? err.message : String(err)}`;
118
+ if (jsonMode) {
119
+ outputJson(errorResponse(msg, 'INDEX_ERROR'));
120
+ }
121
+ else {
122
+ console.log(chalk.red(msg));
123
+ }
124
+ }
125
+ }
126
+ // ============================================================
127
+ // memory search — 搜索记忆
128
+ // ============================================================
129
+ export async function memorySearch(keywords, options) {
130
+ const jsonMode = !!options.json;
131
+ const projectRoot = process.cwd();
132
+ try {
133
+ const manager = createMemoryManager(projectRoot);
134
+ // 构建搜索查询
135
+ const query = {};
136
+ if (keywords.length > 0) {
137
+ query.keywords = keywords;
138
+ }
139
+ if (options.phase) {
140
+ const phase = options.phase;
141
+ const validPhases = ['explore', 'propose', 'apply', 'verify', 'archive', 'general'];
142
+ if (!validPhases.includes(phase)) {
143
+ const msg = `无效的阶段: "${options.phase}"。有效值: ${validPhases.join(', ')}`;
144
+ if (jsonMode) {
145
+ outputJson(errorResponse(msg, 'INVALID_PHASE'));
146
+ }
147
+ else {
148
+ console.log(chalk.red(msg));
149
+ }
150
+ return;
151
+ }
152
+ query.phases = [phase];
153
+ }
154
+ if (options.session) {
155
+ query.sessionId = options.session;
156
+ }
157
+ if (options.limit) {
158
+ const limit = parseInt(options.limit, 10);
159
+ if (isNaN(limit) || limit <= 0) {
160
+ const msg = `无效的 limit: "${options.limit}"`;
161
+ if (jsonMode) {
162
+ outputJson(errorResponse(msg, 'INVALID_LIMIT'));
163
+ }
164
+ else {
165
+ console.log(chalk.red(msg));
166
+ }
167
+ return;
168
+ }
169
+ query.limit = limit;
170
+ }
171
+ if (options.minRelevance) {
172
+ const minRelevance = parseFloat(options.minRelevance);
173
+ if (isNaN(minRelevance) || minRelevance < 0 || minRelevance > 1) {
174
+ const msg = `无效的最小相关性: "${options.minRelevance}"(需要 0-1 之间的数值)`;
175
+ if (jsonMode) {
176
+ outputJson(errorResponse(msg, 'INVALID_RELEVANCE'));
177
+ }
178
+ else {
179
+ console.log(chalk.red(msg));
180
+ }
181
+ return;
182
+ }
183
+ query.minRelevance = minRelevance;
184
+ }
185
+ const result = await manager.search(query);
186
+ if (jsonMode) {
187
+ outputJson(successResponse({
188
+ total: result.total,
189
+ duration: result.duration,
190
+ message: '搜索完成',
191
+ entries: result.entries.map(e => ({
192
+ id: e.id,
193
+ phase: e.phase,
194
+ content: e.content,
195
+ keywords: e.keywords,
196
+ relevance: e.relevance,
197
+ timestamp: e.timestamp,
198
+ sessionId: e.sessionId,
199
+ })),
200
+ }));
201
+ }
202
+ else {
203
+ console.log(chalk.green(`\n🔍 搜索完成 (${result.duration}ms)`));
204
+ console.log(` 找到 ${chalk.cyan(String(result.total))} 条结果\n`);
205
+ if (result.entries.length === 0) {
206
+ console.log(chalk.yellow(' 无匹配结果。'));
207
+ return;
208
+ }
209
+ for (const entry of result.entries) {
210
+ const phaseLabel = PHASE_LABELS[entry.phase] || entry.phase;
211
+ const relevanceBar = '█'.repeat(Math.round(entry.relevance * 10)) + '░'.repeat(10 - Math.round(entry.relevance * 10));
212
+ console.log(` ${chalk.gray(formatTime(entry.timestamp))} ${chalk.blue(`[${phaseLabel}]`)} ${relevanceBar} ${chalk.gray(entry.relevance.toFixed(2))}`);
213
+ console.log(` ${truncate(entry.content, 100)}`);
214
+ if (entry.keywords.length > 0) {
215
+ console.log(` ${chalk.gray('关键词:')} ${entry.keywords.map(k => chalk.dim(k)).join(', ')}`);
216
+ }
217
+ console.log('');
218
+ }
219
+ }
220
+ }
221
+ catch (err) {
222
+ const msg = `搜索失败: ${err instanceof Error ? err.message : String(err)}`;
223
+ if (jsonMode) {
224
+ outputJson(errorResponse(msg, 'SEARCH_ERROR'));
225
+ }
226
+ else {
227
+ console.log(chalk.red(msg));
228
+ }
229
+ }
230
+ }
231
+ // ============================================================
232
+ // memory stats — 显示记忆统计
233
+ // ============================================================
234
+ export async function memoryStats(options) {
235
+ const jsonMode = !!options.json;
236
+ const projectRoot = process.cwd();
237
+ try {
238
+ const manager = createMemoryManager(projectRoot);
239
+ const stats = await manager.getStats();
240
+ if (jsonMode) {
241
+ outputJson(successResponse({ ...stats, message: '记忆统计' }));
242
+ }
243
+ else {
244
+ console.log(chalk.green('\n📊 记忆统计\n'));
245
+ console.log(` 总条目数: ${chalk.cyan(String(stats.totalEntries))}`);
246
+ console.log(` 总会话数: ${chalk.cyan(String(stats.totalSessions))}`);
247
+ console.log(` 索引大小: ${chalk.cyan(formatBytes(stats.indexSize))}`);
248
+ if (stats.oldestEntry && stats.newestEntry) {
249
+ console.log(` 最早记录: ${chalk.gray(formatTime(stats.oldestEntry))}`);
250
+ console.log(` 最新记录: ${chalk.gray(formatTime(stats.newestEntry))}`);
251
+ }
252
+ console.log(chalk.green('\n 阶段分布:'));
253
+ const phases = Object.entries(stats.phaseCounts);
254
+ for (const [phase, count] of phases.sort((a, b) => b[1] - a[1])) {
255
+ if (count > 0) {
256
+ const label = PHASE_LABELS[phase] || phase;
257
+ const bar = '█'.repeat(Math.min(count, 30));
258
+ console.log(` ${chalk.blue(`[${label}]`)} ${bar} ${count}`);
259
+ }
260
+ }
261
+ console.log('');
262
+ }
263
+ }
264
+ catch (err) {
265
+ const msg = `获取统计失败: ${err instanceof Error ? err.message : String(err)}`;
266
+ if (jsonMode) {
267
+ outputJson(errorResponse(msg, 'STATS_ERROR'));
268
+ }
269
+ else {
270
+ console.log(chalk.red(msg));
271
+ }
272
+ }
273
+ }
274
+ // ============================================================
275
+ // memory timeline — 按时间线展示
276
+ // ============================================================
277
+ export async function memoryTimeline(options) {
278
+ const jsonMode = !!options.json;
279
+ const projectRoot = process.cwd();
280
+ try {
281
+ const manager = createMemoryManager(projectRoot);
282
+ const limit = options.limit ? parseInt(options.limit, 10) : 20;
283
+ if (isNaN(limit) || limit <= 0) {
284
+ const msg = `无效的 limit: "${options.limit}"`;
285
+ if (jsonMode) {
286
+ outputJson(errorResponse(msg, 'INVALID_LIMIT'));
287
+ }
288
+ else {
289
+ console.log(chalk.red(msg));
290
+ }
291
+ return;
292
+ }
293
+ const entries = await manager.getRecent(limit);
294
+ if (jsonMode) {
295
+ outputJson(successResponse({
296
+ count: entries.length,
297
+ message: '时间线',
298
+ entries: entries.map(e => ({
299
+ id: e.id,
300
+ phase: e.phase,
301
+ content: e.content,
302
+ keywords: e.keywords,
303
+ relevance: e.relevance,
304
+ timestamp: e.timestamp,
305
+ sessionId: e.sessionId,
306
+ })),
307
+ }));
308
+ }
309
+ else {
310
+ console.log(chalk.green(`\n📅 最近 ${entries.length} 条记忆\n`));
311
+ if (entries.length === 0) {
312
+ console.log(chalk.yellow(' 暂无记忆数据。'));
313
+ return;
314
+ }
315
+ for (const entry of entries) {
316
+ const phaseLabel = PHASE_LABELS[entry.phase] || entry.phase;
317
+ console.log(` ${chalk.gray(formatTime(entry.timestamp))} ${chalk.blue(`[${phaseLabel}]`)} ${chalk.gray(`(相关性: ${entry.relevance.toFixed(2)})`)}`);
318
+ console.log(` ${truncate(entry.content, 120)}`);
319
+ if (entry.keywords.length > 0) {
320
+ console.log(` ${chalk.dim(entry.keywords.join(', '))}`);
321
+ }
322
+ console.log('');
323
+ }
324
+ }
325
+ }
326
+ catch (err) {
327
+ const msg = `获取时间线失败: ${err instanceof Error ? err.message : String(err)}`;
328
+ if (jsonMode) {
329
+ outputJson(errorResponse(msg, 'TIMELINE_ERROR'));
330
+ }
331
+ else {
332
+ console.log(chalk.red(msg));
333
+ }
334
+ }
335
+ }
336
+ // ============================================================
337
+ // memory phases — 按阶段切片
338
+ // ============================================================
339
+ export async function memoryPhases(phase, options) {
340
+ const jsonMode = !!options.json;
341
+ const projectRoot = process.cwd();
342
+ const validPhases = ['explore', 'propose', 'apply', 'verify', 'archive', 'general'];
343
+ if (!validPhases.includes(phase)) {
344
+ const msg = `无效的阶段: "${phase}"。有效值: ${validPhases.join(', ')}`;
345
+ if (jsonMode) {
346
+ outputJson(errorResponse(msg, 'INVALID_PHASE'));
347
+ }
348
+ else {
349
+ console.log(chalk.red(msg));
350
+ }
351
+ return;
352
+ }
353
+ try {
354
+ const manager = createMemoryManager(projectRoot);
355
+ const limit = options.limit ? parseInt(options.limit, 10) : 20;
356
+ if (isNaN(limit) || limit <= 0) {
357
+ const msg = `无效的 limit: "${options.limit}"`;
358
+ if (jsonMode) {
359
+ outputJson(errorResponse(msg, 'INVALID_LIMIT'));
360
+ }
361
+ else {
362
+ console.log(chalk.red(msg));
363
+ }
364
+ return;
365
+ }
366
+ const entries = await manager.getByPhase(phase, limit);
367
+ const phaseLabel = PHASE_LABELS[phase] || phase;
368
+ if (jsonMode) {
369
+ outputJson(successResponse({
370
+ phase,
371
+ count: entries.length,
372
+ message: `${phaseLabel} 阶段记忆`,
373
+ entries: entries.map(e => ({
374
+ id: e.id,
375
+ content: e.content,
376
+ keywords: e.keywords,
377
+ relevance: e.relevance,
378
+ timestamp: e.timestamp,
379
+ sessionId: e.sessionId,
380
+ })),
381
+ }));
382
+ }
383
+ else {
384
+ console.log(chalk.green(`\n📋 ${phaseLabel} 阶段 — 最近 ${entries.length} 条\n`));
385
+ if (entries.length === 0) {
386
+ console.log(chalk.yellow(` 暂无 "${phaseLabel}" 阶段的记忆数据。`));
387
+ return;
388
+ }
389
+ for (const entry of entries) {
390
+ console.log(` ${chalk.gray(formatTime(entry.timestamp))} ${chalk.gray(`(相关性: ${entry.relevance.toFixed(2)})`)}`);
391
+ console.log(` ${truncate(entry.content, 120)}`);
392
+ if (entry.keywords.length > 0) {
393
+ console.log(` ${chalk.dim(entry.keywords.join(', '))}`);
394
+ }
395
+ console.log('');
396
+ }
397
+ }
398
+ }
399
+ catch (err) {
400
+ const msg = `获取阶段记忆失败: ${err instanceof Error ? err.message : String(err)}`;
401
+ if (jsonMode) {
402
+ outputJson(errorResponse(msg, 'PHASE_ERROR'));
403
+ }
404
+ else {
405
+ console.log(chalk.red(msg));
406
+ }
407
+ }
408
+ }
409
+ // ============================================================
410
+ // memory clear — 清除记忆数据
411
+ // ============================================================
412
+ export async function memoryClear(options) {
413
+ const jsonMode = !!options.json;
414
+ const projectRoot = process.cwd();
415
+ if (!options.yes) {
416
+ const msg = '此操作将清除所有记忆数据,不可恢复。使用 --yes 确认。';
417
+ if (jsonMode) {
418
+ outputJson(errorResponse(msg, 'CONFIRMATION_REQUIRED'));
419
+ }
420
+ else {
421
+ console.log(chalk.yellow(`⚠️ ${msg}`));
422
+ }
423
+ return;
424
+ }
425
+ try {
426
+ const manager = createMemoryManager(projectRoot);
427
+ // 先获取统计信息用于报告
428
+ const statsBefore = await manager.getStats();
429
+ const clearedEntries = statsBefore.totalEntries;
430
+ const clearedSessions = statsBefore.totalSessions;
431
+ await manager.clear();
432
+ if (jsonMode) {
433
+ outputJson(successResponse({
434
+ clearedEntries,
435
+ clearedSessions,
436
+ message: '记忆数据已清除',
437
+ }));
438
+ }
439
+ else {
440
+ console.log(chalk.green('✓ 记忆数据已清除'));
441
+ console.log(` 清除条目: ${chalk.cyan(String(clearedEntries))}`);
442
+ console.log(` 清除会话: ${chalk.cyan(String(clearedSessions))}`);
443
+ }
444
+ }
445
+ catch (err) {
446
+ const msg = `清除失败: ${err instanceof Error ? err.message : String(err)}`;
447
+ if (jsonMode) {
448
+ outputJson(errorResponse(msg, 'CLEAR_ERROR'));
449
+ }
450
+ else {
451
+ console.log(chalk.red(msg));
452
+ }
453
+ }
454
+ }
455
+ //# sourceMappingURL=memory.js.map