@winspan/claude-forge 8.41.0 → 8.50.6

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 (804) hide show
  1. package/.claude/CLAUDE.md +17 -0
  2. package/.eslintrc.js +23 -0
  3. package/.prettierrc +8 -0
  4. package/ARCHITECTURE_ISSUES.md +249 -0
  5. package/CLAUDE.md +265 -0
  6. package/CLAUDE.md.backup +488 -0
  7. package/DEVELOPMENT.md +310 -0
  8. package/dist/claudemd/claudemd-generator.d.ts +38 -3
  9. package/dist/claudemd/claudemd-generator.d.ts.map +1 -1
  10. package/dist/claudemd/claudemd-generator.js +629 -11
  11. package/dist/claudemd/claudemd-generator.js.map +1 -1
  12. package/dist/claudemd/index.d.ts +2 -2
  13. package/dist/claudemd/index.d.ts.map +1 -1
  14. package/dist/claudemd/index.js.map +1 -1
  15. package/dist/claudemd/resume-manager.d.ts.map +1 -1
  16. package/dist/claudemd/resume-manager.js +5 -2
  17. package/dist/claudemd/resume-manager.js.map +1 -1
  18. package/dist/claudemd/tech-detector.d.ts +1 -0
  19. package/dist/claudemd/tech-detector.d.ts.map +1 -1
  20. package/dist/claudemd/tech-detector.js +53 -0
  21. package/dist/claudemd/tech-detector.js.map +1 -1
  22. package/dist/cli/commands/claudemd.js +2 -2
  23. package/dist/cli/commands/claudemd.js.map +1 -1
  24. package/dist/cli/commands/daemon.d.ts +28 -0
  25. package/dist/cli/commands/daemon.d.ts.map +1 -1
  26. package/dist/cli/commands/daemon.js +200 -8
  27. package/dist/cli/commands/daemon.js.map +1 -1
  28. package/dist/cli/commands/init.d.ts.map +1 -1
  29. package/dist/cli/commands/init.js +3 -35
  30. package/dist/cli/commands/init.js.map +1 -1
  31. package/dist/cli/commands/menu.js +10 -10
  32. package/dist/cli/commands/menu.js.map +1 -1
  33. package/dist/cli/commands/skills.d.ts.map +1 -1
  34. package/dist/cli/commands/skills.js +8 -2
  35. package/dist/cli/commands/skills.js.map +1 -1
  36. package/dist/cli/commands/stats.d.ts.map +1 -1
  37. package/dist/cli/commands/stats.js +0 -17
  38. package/dist/cli/commands/stats.js.map +1 -1
  39. package/dist/cli/commands/trace.d.ts +9 -0
  40. package/dist/cli/commands/trace.d.ts.map +1 -0
  41. package/dist/cli/commands/trace.js +137 -0
  42. package/dist/cli/commands/trace.js.map +1 -0
  43. package/dist/cli/index.js +2 -4
  44. package/dist/cli/index.js.map +1 -1
  45. package/dist/core/ai/provider.d.ts +10 -2
  46. package/dist/core/ai/provider.d.ts.map +1 -1
  47. package/dist/core/ai/provider.js.map +1 -1
  48. package/dist/core/ai/types.d.ts +1 -19
  49. package/dist/core/ai/types.d.ts.map +1 -1
  50. package/dist/core/ai/types.js +1 -1
  51. package/dist/core/config.d.ts +2 -1
  52. package/dist/core/config.d.ts.map +1 -1
  53. package/dist/core/config.js +23 -6
  54. package/dist/core/config.js.map +1 -1
  55. package/dist/core/constants.d.ts +2 -2
  56. package/dist/core/constants.js +2 -2
  57. package/dist/core/constants.js.map +1 -1
  58. package/dist/core/queue/index.d.ts +52 -0
  59. package/dist/core/queue/index.d.ts.map +1 -0
  60. package/dist/core/queue/index.js +176 -0
  61. package/dist/core/queue/index.js.map +1 -0
  62. package/dist/core/storage/base.d.ts +33 -0
  63. package/dist/core/storage/base.d.ts.map +1 -0
  64. package/dist/core/storage/base.js +211 -0
  65. package/dist/core/storage/base.js.map +1 -0
  66. package/dist/core/storage/events.d.ts +52 -0
  67. package/dist/core/storage/events.d.ts.map +1 -0
  68. package/dist/core/storage/events.js +201 -0
  69. package/dist/core/storage/events.js.map +1 -0
  70. package/dist/core/storage/injections.d.ts +27 -0
  71. package/dist/core/storage/injections.d.ts.map +1 -0
  72. package/dist/core/storage/injections.js +51 -0
  73. package/dist/core/storage/injections.js.map +1 -0
  74. package/dist/core/storage/maintenance.d.ts +21 -0
  75. package/dist/core/storage/maintenance.d.ts.map +1 -0
  76. package/dist/core/storage/maintenance.js +52 -0
  77. package/dist/core/storage/maintenance.js.map +1 -0
  78. package/dist/core/storage/routing.d.ts +71 -0
  79. package/dist/core/storage/routing.d.ts.map +1 -0
  80. package/dist/core/storage/routing.js +141 -0
  81. package/dist/core/storage/routing.js.map +1 -0
  82. package/dist/core/storage/rows.d.ts +0 -47
  83. package/dist/core/storage/rows.d.ts.map +1 -1
  84. package/dist/core/storage/schema.sql +74 -136
  85. package/dist/core/storage/sessions.d.ts +34 -0
  86. package/dist/core/storage/sessions.d.ts.map +1 -0
  87. package/dist/core/storage/sessions.js +78 -0
  88. package/dist/core/storage/sessions.js.map +1 -0
  89. package/dist/core/storage/skills.d.ts +40 -0
  90. package/dist/core/storage/skills.d.ts.map +1 -0
  91. package/dist/core/storage/skills.js +107 -0
  92. package/dist/core/storage/skills.js.map +1 -0
  93. package/dist/core/storage/sqlite.d.ts +63 -265
  94. package/dist/core/storage/sqlite.d.ts.map +1 -1
  95. package/dist/core/storage/sqlite.js +102 -759
  96. package/dist/core/storage/sqlite.js.map +1 -1
  97. package/dist/core/storage/tasks.d.ts +64 -0
  98. package/dist/core/storage/tasks.d.ts.map +1 -0
  99. package/dist/core/storage/tasks.js +134 -0
  100. package/dist/core/storage/tasks.js.map +1 -0
  101. package/dist/core/storage/token-usage.d.ts +36 -0
  102. package/dist/core/storage/token-usage.d.ts.map +1 -0
  103. package/dist/core/storage/token-usage.js +59 -0
  104. package/dist/core/storage/token-usage.js.map +1 -0
  105. package/dist/core/types.d.ts +60 -4
  106. package/dist/core/types.d.ts.map +1 -1
  107. package/dist/core/types.js +24 -1
  108. package/dist/core/types.js.map +1 -1
  109. package/dist/core/utils/format.d.ts +28 -0
  110. package/dist/core/utils/format.d.ts.map +1 -0
  111. package/dist/core/utils/format.js +68 -0
  112. package/dist/core/utils/format.js.map +1 -0
  113. package/dist/core/utils/logger.d.ts +6 -1
  114. package/dist/core/utils/logger.d.ts.map +1 -1
  115. package/dist/core/utils/logger.js +72 -2
  116. package/dist/core/utils/logger.js.map +1 -1
  117. package/dist/core/utils/session.d.ts +16 -0
  118. package/dist/core/utils/session.d.ts.map +1 -0
  119. package/dist/core/utils/session.js +25 -0
  120. package/dist/core/utils/session.js.map +1 -0
  121. package/dist/core/utils/time.d.ts +22 -0
  122. package/dist/core/utils/time.d.ts.map +1 -0
  123. package/dist/core/utils/time.js +38 -0
  124. package/dist/core/utils/time.js.map +1 -0
  125. package/dist/daemon/handlers/history-exporter.d.ts.map +1 -1
  126. package/dist/daemon/handlers/history-exporter.js +6 -4
  127. package/dist/daemon/handlers/history-exporter.js.map +1 -1
  128. package/dist/daemon/handlers/post-tool-use.d.ts +5 -12
  129. package/dist/daemon/handlers/post-tool-use.d.ts.map +1 -1
  130. package/dist/daemon/handlers/post-tool-use.js +21 -79
  131. package/dist/daemon/handlers/post-tool-use.js.map +1 -1
  132. package/dist/daemon/handlers/stop.d.ts +24 -12
  133. package/dist/daemon/handlers/stop.d.ts.map +1 -1
  134. package/dist/daemon/handlers/stop.js +141 -42
  135. package/dist/daemon/handlers/stop.js.map +1 -1
  136. package/dist/daemon/handlers/user-prompt.d.ts +18 -19
  137. package/dist/daemon/handlers/user-prompt.d.ts.map +1 -1
  138. package/dist/daemon/handlers/user-prompt.js +103 -227
  139. package/dist/daemon/handlers/user-prompt.js.map +1 -1
  140. package/dist/daemon/index.d.ts +6 -2
  141. package/dist/daemon/index.d.ts.map +1 -1
  142. package/dist/daemon/index.js +76 -120
  143. package/dist/daemon/index.js.map +1 -1
  144. package/dist/daemon/launchd/com.claude-forge.daemon.plist.template +47 -0
  145. package/dist/daemon/launchd-installer.d.ts +61 -0
  146. package/dist/daemon/launchd-installer.d.ts.map +1 -0
  147. package/dist/daemon/launchd-installer.js +182 -0
  148. package/dist/daemon/launchd-installer.js.map +1 -0
  149. package/dist/daemon/lifecycle.d.ts +11 -0
  150. package/dist/daemon/lifecycle.d.ts.map +1 -1
  151. package/dist/daemon/lifecycle.js +44 -0
  152. package/dist/daemon/lifecycle.js.map +1 -1
  153. package/dist/daemon/router.d.ts +9 -2
  154. package/dist/daemon/router.d.ts.map +1 -1
  155. package/dist/daemon/router.js +27 -3
  156. package/dist/daemon/router.js.map +1 -1
  157. package/dist/daemon/server.d.ts.map +1 -1
  158. package/dist/daemon/server.js +6 -5
  159. package/dist/daemon/server.js.map +1 -1
  160. package/dist/daemon/services/anti-pattern-detector.d.ts +50 -0
  161. package/dist/daemon/services/anti-pattern-detector.d.ts.map +1 -0
  162. package/dist/daemon/services/anti-pattern-detector.js +357 -0
  163. package/dist/daemon/services/anti-pattern-detector.js.map +1 -0
  164. package/dist/daemon/services/drift-detector.d.ts +64 -0
  165. package/dist/daemon/services/drift-detector.d.ts.map +1 -0
  166. package/dist/daemon/services/drift-detector.js +201 -0
  167. package/dist/daemon/services/drift-detector.js.map +1 -0
  168. package/dist/{intelligence → daemon/services}/task-segmenter.d.ts +7 -1
  169. package/dist/daemon/services/task-segmenter.d.ts.map +1 -0
  170. package/dist/{intelligence → daemon/services}/task-segmenter.js +29 -6
  171. package/dist/daemon/services/task-segmenter.js.map +1 -0
  172. package/dist/daemon/services/weekly-report.d.ts +91 -0
  173. package/dist/daemon/services/weekly-report.d.ts.map +1 -0
  174. package/dist/daemon/services/weekly-report.js +327 -0
  175. package/dist/daemon/services/weekly-report.js.map +1 -0
  176. package/dist/hooks/hook-lib.sh +81 -0
  177. package/dist/hooks/notification.sh +7 -3
  178. package/dist/hooks/post-tool-use.sh +8 -4
  179. package/dist/hooks/pre-tool-use.sh +7 -4
  180. package/dist/hooks/stop.sh +1 -1
  181. package/dist/hooks/user-prompt-submit.sh +8 -9
  182. package/dist/mcp/server.d.ts +2 -2
  183. package/dist/mcp/server.d.ts.map +1 -1
  184. package/dist/mcp/server.js +71 -11
  185. package/dist/mcp/server.js.map +1 -1
  186. package/dist/skills/invocation-guard.d.ts +20 -0
  187. package/dist/skills/invocation-guard.d.ts.map +1 -1
  188. package/dist/skills/invocation-guard.js +63 -0
  189. package/dist/skills/invocation-guard.js.map +1 -1
  190. package/dist/skills/matcher.d.ts.map +1 -1
  191. package/dist/skills/matcher.js +12 -3
  192. package/dist/skills/matcher.js.map +1 -1
  193. package/dist/skills/official/code-simplifier.md +16 -0
  194. package/dist/skills/official/find-skills.md +23 -0
  195. package/dist/skills/official/official-api-design.md +17 -0
  196. package/dist/skills/official/official-architecture-decision.md +20 -0
  197. package/dist/skills/official/official-bmad.md +118 -0
  198. package/dist/skills/official/official-db-schema-design.md +16 -0
  199. package/dist/skills/official/official-debug.md +17 -0
  200. package/dist/skills/official/official-doc-driven.md +31 -0
  201. package/dist/skills/official/official-harness-engineering.md +108 -0
  202. package/dist/skills/official/official-performance-optimization.md +30 -0
  203. package/dist/skills/official/official-pr-review.md +35 -0
  204. package/dist/skills/official/official-release-checklist.md +30 -0
  205. package/dist/skills/official/official-security-hardening.md +26 -0
  206. package/dist/skills/official/official-spec-driven-design.md +31 -0
  207. package/dist/skills/official/planning-with-files.md +37 -0
  208. package/dist/skills/official/ui-ux-pro-max.md +18 -0
  209. package/dist/skills/official/webapp-testing.md +12 -0
  210. package/dist/skills/official-skills.d.ts +8 -4
  211. package/dist/skills/official-skills.d.ts.map +1 -1
  212. package/dist/skills/official-skills.js +48 -704
  213. package/dist/skills/official-skills.js.map +1 -1
  214. package/dist/skills/registry.d.ts +5 -0
  215. package/dist/skills/registry.d.ts.map +1 -1
  216. package/dist/skills/registry.js +48 -15
  217. package/dist/skills/registry.js.map +1 -1
  218. package/dist/skills/tools/pipeline-suggest.d.ts +30 -0
  219. package/dist/skills/tools/pipeline-suggest.d.ts.map +1 -0
  220. package/dist/skills/tools/pipeline-suggest.js +178 -0
  221. package/dist/skills/tools/pipeline-suggest.js.map +1 -0
  222. package/dist/web/routes/ai.d.ts.map +1 -1
  223. package/dist/web/routes/ai.js +16 -22
  224. package/dist/web/routes/ai.js.map +1 -1
  225. package/dist/web/routes/drift.d.ts +10 -0
  226. package/dist/web/routes/drift.d.ts.map +1 -0
  227. package/dist/web/routes/drift.js +21 -0
  228. package/dist/web/routes/drift.js.map +1 -0
  229. package/dist/web/routes/error-handler.d.ts +43 -0
  230. package/dist/web/routes/error-handler.d.ts.map +1 -0
  231. package/dist/web/routes/error-handler.js +99 -0
  232. package/dist/web/routes/error-handler.js.map +1 -0
  233. package/dist/web/routes/insights.d.ts +9 -0
  234. package/dist/web/routes/insights.d.ts.map +1 -0
  235. package/dist/web/routes/insights.js +34 -0
  236. package/dist/web/routes/insights.js.map +1 -0
  237. package/dist/web/routes/patch.js +2 -2
  238. package/dist/web/routes/patch.js.map +1 -1
  239. package/dist/web/routes/reports.d.ts +10 -0
  240. package/dist/web/routes/reports.d.ts.map +1 -0
  241. package/dist/web/routes/reports.js +27 -0
  242. package/dist/web/routes/reports.js.map +1 -0
  243. package/dist/web/routes/rules.d.ts +10 -3
  244. package/dist/web/routes/rules.d.ts.map +1 -1
  245. package/dist/web/routes/rules.js +80 -95
  246. package/dist/web/routes/rules.js.map +1 -1
  247. package/dist/web/routes/sessions.d.ts +1 -2
  248. package/dist/web/routes/sessions.d.ts.map +1 -1
  249. package/dist/web/routes/sessions.js +27 -39
  250. package/dist/web/routes/sessions.js.map +1 -1
  251. package/dist/web/routes/skill-stats.d.ts.map +1 -1
  252. package/dist/web/routes/skill-stats.js +38 -0
  253. package/dist/web/routes/skill-stats.js.map +1 -1
  254. package/dist/web/routes/skills.d.ts.map +1 -1
  255. package/dist/web/routes/skills.js +34 -0
  256. package/dist/web/routes/skills.js.map +1 -1
  257. package/dist/web/routes/stats.d.ts +7 -0
  258. package/dist/web/routes/stats.d.ts.map +1 -0
  259. package/dist/web/routes/stats.js +44 -0
  260. package/dist/web/routes/stats.js.map +1 -0
  261. package/dist/web/routes/status.js +1 -1
  262. package/dist/web/routes/status.js.map +1 -1
  263. package/dist/web/routes/tasks.d.ts +4 -0
  264. package/dist/web/routes/tasks.d.ts.map +1 -0
  265. package/dist/web/routes/tasks.js +181 -0
  266. package/dist/web/routes/tasks.js.map +1 -0
  267. package/dist/web/routes/trace.d.ts +10 -0
  268. package/dist/web/routes/trace.d.ts.map +1 -0
  269. package/dist/web/routes/trace.js +123 -0
  270. package/dist/web/routes/trace.js.map +1 -0
  271. package/dist/web/routes/types.d.ts +1 -14
  272. package/dist/web/routes/types.d.ts.map +1 -1
  273. package/dist/web/routes/types.js +8 -17
  274. package/dist/web/routes/types.js.map +1 -1
  275. package/dist/web/server.d.ts +1 -9
  276. package/dist/web/server.d.ts.map +1 -1
  277. package/dist/web/server.js +28 -28
  278. package/dist/web/server.js.map +1 -1
  279. package/dist/web/static/assets/AIConfig-BQCAQE9D.js +2 -0
  280. package/dist/web/static/assets/AIConfig-BQCAQE9D.js.map +1 -0
  281. package/dist/web/static/assets/Dashboard-D7Bo6Kan.js +2 -0
  282. package/dist/web/static/assets/Dashboard-D7Bo6Kan.js.map +1 -0
  283. package/dist/web/static/assets/{Drawer-DcU3ln98.js → Drawer-BeHRQxUS.js} +2 -2
  284. package/dist/web/static/assets/{Drawer-DcU3ln98.js.map → Drawer-BeHRQxUS.js.map} +1 -1
  285. package/dist/web/static/assets/Events-K_tCY2ti.js +2 -0
  286. package/dist/web/static/assets/Events-K_tCY2ti.js.map +1 -0
  287. package/dist/web/static/assets/Reports-BJCmBnc_.js +2 -0
  288. package/dist/web/static/assets/Reports-BJCmBnc_.js.map +1 -0
  289. package/dist/web/static/assets/SearchInput-BX2KhMkw.js +2 -0
  290. package/dist/web/static/assets/SearchInput-BX2KhMkw.js.map +1 -0
  291. package/dist/web/static/assets/SessionDetail-Bkr-kC7V.js +2 -0
  292. package/dist/web/static/assets/SessionDetail-Bkr-kC7V.js.map +1 -0
  293. package/dist/web/static/assets/Sessions-Chx9OCLH.js +2 -0
  294. package/dist/web/static/assets/Sessions-Chx9OCLH.js.map +1 -0
  295. package/dist/web/static/assets/Skills-O0GT1i7m.js +2 -0
  296. package/dist/web/static/assets/Skills-O0GT1i7m.js.map +1 -0
  297. package/dist/web/static/assets/TaskDetail-5SR8zGzv.js +2 -0
  298. package/dist/web/static/assets/TaskDetail-5SR8zGzv.js.map +1 -0
  299. package/dist/web/static/assets/Tasks-DCgDqvOZ.js +2 -0
  300. package/dist/web/static/assets/Tasks-DCgDqvOZ.js.map +1 -0
  301. package/dist/web/static/assets/export-L_VBD2p1.js +4 -0
  302. package/dist/web/static/assets/export-L_VBD2p1.js.map +1 -0
  303. package/dist/web/static/assets/index-D8AKj26b.css +1 -0
  304. package/dist/web/static/assets/index-DxIbmNmr.js +3 -0
  305. package/dist/web/static/assets/index-DxIbmNmr.js.map +1 -0
  306. package/dist/web/static/assets/{lucide-53bR2rki.js → lucide-fJlPI3H7.js} +68 -38
  307. package/dist/web/static/assets/lucide-fJlPI3H7.js.map +1 -0
  308. package/dist/web/static/assets/time-Bxuk0M-C.js +2 -0
  309. package/dist/web/static/assets/time-Bxuk0M-C.js.map +1 -0
  310. package/dist/web/static/index.html +3 -3
  311. package/docs/concurrent-agents.md +129 -0
  312. package/docs/design/architecture-review-20260516.md +232 -0
  313. package/docs/design/fix-skills-data-and-set-leak-spec-20260516-1300.md +219 -0
  314. package/docs/design/hook-failure-queue-spec-20260516-1530.md +204 -0
  315. package/docs/design/refactor-phase1-spec-20260515-1600.md +543 -0
  316. package/docs/design/refactor-phase2-spec-20260515-1700.md +424 -0
  317. package/docs/design/tasks-list-filter-pagination-spec-20260518-0930.md +208 -0
  318. package/docs/implementation/fix-skills-data-and-set-leak-changelog-20260516-1300.md +104 -0
  319. package/docs/implementation/hook-failure-queue-changelog-20260516-1530.md +196 -0
  320. package/docs/implementation/hotfix-daemon-event-reject-20260516-1430.md +56 -0
  321. package/docs/implementation/refactor-phase1-changelog-20260515-1630.md +354 -0
  322. package/docs/implementation/refactor-phase2-changelog-20260515-1705.md +421 -0
  323. package/docs/implementation/tasks-list-filter-pagination-changelog-20260518-0930.md +72 -0
  324. package/docs/reviews/claudemd-template-sync.md +54 -0
  325. package/docs/reviews/tasks-filter-pagination.md +80 -0
  326. package/docs/ruflo-learning-strategy.md +322 -0
  327. package/docs/skills-deduplication-analysis.md +83 -0
  328. package/docs/skills-multiformat-support.md +177 -0
  329. package/docs/skills-third-party.md +183 -0
  330. package/docs/testing/tasks-filter-pagination-test-report.md +86 -0
  331. package/forge +321 -0
  332. package/package.json +28 -62
  333. package/playwright.config.ts +40 -0
  334. package/scripts/demo-v2.ts +91 -0
  335. package/scripts/dev-daemon.sh +232 -0
  336. package/scripts/dev-web.ts +109 -0
  337. package/scripts/e2e-mcp-link.ts +423 -0
  338. package/scripts/e2e-methodology-quality.ts +253 -0
  339. package/scripts/e2e-routing.ts +456 -0
  340. package/scripts/e2e-user-methodology.ts +326 -0
  341. package/scripts/e2e-web-workflows.ts +299 -0
  342. package/scripts/migrate-legacy-to-dynamic.sql +108 -0
  343. package/scripts/regenerate-execution-docs.ts +116 -0
  344. package/scripts/sync-agent-skills.ts +193 -0
  345. package/scripts/test-hook.sh +71 -0
  346. package/scripts/verify-skill-loading.ts +62 -0
  347. package/src/claudemd/claudemd-generator.ts +777 -0
  348. package/src/claudemd/convention-extractor.ts +69 -0
  349. package/src/claudemd/index.ts +35 -0
  350. package/src/claudemd/persona-manager.ts +88 -0
  351. package/src/claudemd/resume-manager.ts +236 -0
  352. package/src/claudemd/tech-detector.ts +220 -0
  353. package/src/cli/commands/claudemd.ts +84 -0
  354. package/src/cli/commands/config.ts +46 -0
  355. package/src/cli/commands/daemon.ts +310 -0
  356. package/src/cli/commands/executions.ts +114 -0
  357. package/src/cli/commands/init.ts +204 -0
  358. package/src/cli/commands/logs.ts +181 -0
  359. package/src/cli/commands/mcp.ts +244 -0
  360. package/src/cli/commands/menu.ts +356 -0
  361. package/src/cli/commands/skills.ts +185 -0
  362. package/src/cli/commands/stats.ts +74 -0
  363. package/src/cli/commands/status.ts +69 -0
  364. package/src/cli/commands/template.ts +77 -0
  365. package/src/cli/commands/trace.ts +164 -0
  366. package/src/cli/index.ts +42 -0
  367. package/src/cli/init/hook-manager.ts +132 -0
  368. package/src/core/ai/provider.ts +308 -0
  369. package/src/core/ai/types.ts +51 -0
  370. package/src/core/config.ts +124 -0
  371. package/src/core/constants.ts +45 -0
  372. package/src/core/queue/index.ts +193 -0
  373. package/src/core/storage/base.ts +226 -0
  374. package/src/core/storage/events.ts +255 -0
  375. package/src/core/storage/injections.ts +78 -0
  376. package/src/core/storage/maintenance.ts +59 -0
  377. package/src/core/storage/migrations/002_add_skill_tracking.sql +6 -0
  378. package/src/core/storage/migrations/003_add_skill_invocations.sql +23 -0
  379. package/src/core/storage/performance-indexes.sql +23 -0
  380. package/src/core/storage/routing.ts +194 -0
  381. package/src/core/storage/rows.ts +112 -0
  382. package/src/core/storage/schema.sql +214 -0
  383. package/src/core/storage/sessions.ts +104 -0
  384. package/src/core/storage/skills.ts +164 -0
  385. package/src/core/storage/sqlite.ts +194 -0
  386. package/src/core/storage/tasks.ts +170 -0
  387. package/src/core/storage/token-usage.ts +93 -0
  388. package/src/core/types.ts +154 -0
  389. package/src/core/utils/error-handler.ts +256 -0
  390. package/src/core/utils/forge-resume-block.ts +74 -0
  391. package/src/core/utils/format.ts +69 -0
  392. package/src/core/utils/logger.ts +119 -0
  393. package/src/core/utils/lru-cache.ts +50 -0
  394. package/src/core/utils/path.ts +19 -0
  395. package/src/core/utils/session.ts +26 -0
  396. package/src/core/utils/time.ts +37 -0
  397. package/src/core/utils/token-tracker.ts +97 -0
  398. package/src/daemon/event-parser.ts +35 -0
  399. package/src/daemon/handlers/history-exporter.ts +117 -0
  400. package/src/daemon/handlers/post-tool-use.ts +50 -0
  401. package/src/daemon/handlers/stop.ts +215 -0
  402. package/src/daemon/handlers/user-prompt.ts +188 -0
  403. package/src/daemon/index.ts +278 -0
  404. package/src/daemon/launchd/com.claude-forge.daemon.plist.template +47 -0
  405. package/src/daemon/launchd-installer.ts +260 -0
  406. package/src/daemon/lifecycle.ts +128 -0
  407. package/src/daemon/router.ts +40 -0
  408. package/src/daemon/server.ts +209 -0
  409. package/src/daemon/services/anti-pattern-detector.ts +412 -0
  410. package/src/daemon/services/drift-detector.ts +232 -0
  411. package/src/daemon/services/task-segmenter.ts +112 -0
  412. package/src/daemon/services/weekly-report.ts +454 -0
  413. package/src/hooks/hook-lib.sh +81 -0
  414. package/src/hooks/notification.sh +35 -0
  415. package/src/hooks/post-tool-use.sh +61 -0
  416. package/src/hooks/pre-tool-use.sh +63 -0
  417. package/src/hooks/stop.sh +40 -0
  418. package/src/hooks/user-prompt-submit.sh +69 -0
  419. package/src/mcp/server.ts +322 -0
  420. package/src/skills/index.ts +2 -0
  421. package/src/skills/invocation-guard.ts +177 -0
  422. package/src/skills/matcher.ts +148 -0
  423. package/src/skills/official/code-simplifier.md +16 -0
  424. package/src/skills/official/find-skills.md +23 -0
  425. package/src/skills/official/official-api-design.md +17 -0
  426. package/src/skills/official/official-architecture-decision.md +20 -0
  427. package/src/skills/official/official-bmad.md +118 -0
  428. package/src/skills/official/official-db-schema-design.md +16 -0
  429. package/src/skills/official/official-debug.md +17 -0
  430. package/src/skills/official/official-doc-driven.md +31 -0
  431. package/src/skills/official/official-harness-engineering.md +108 -0
  432. package/src/skills/official/official-performance-optimization.md +30 -0
  433. package/src/skills/official/official-pr-review.md +35 -0
  434. package/src/skills/official/official-release-checklist.md +30 -0
  435. package/src/skills/official/official-security-hardening.md +26 -0
  436. package/src/skills/official/official-spec-driven-design.md +31 -0
  437. package/src/skills/official/planning-with-files.md +37 -0
  438. package/src/skills/official/ui-ux-pro-max.md +18 -0
  439. package/src/skills/official/webapp-testing.md +12 -0
  440. package/src/skills/official-skills.ts +89 -0
  441. package/src/skills/registry.ts +355 -0
  442. package/src/skills/semantic-matcher.ts +231 -0
  443. package/src/skills/tools/pipeline-suggest.ts +226 -0
  444. package/src/skills/tools/skill-invoke.ts +168 -0
  445. package/src/skills/tools/skill-list.ts +59 -0
  446. package/src/templates/go.yaml +53 -0
  447. package/src/templates/python.yaml +59 -0
  448. package/src/templates/react.yaml +55 -0
  449. package/src/templates/template-manager.ts +170 -0
  450. package/src/web/auth-middleware.ts +55 -0
  451. package/src/web/routes/ai.ts +204 -0
  452. package/src/web/routes/auth.ts +22 -0
  453. package/src/web/routes/drift.ts +25 -0
  454. package/src/web/routes/error-handler.ts +120 -0
  455. package/src/web/routes/events.ts +47 -0
  456. package/src/web/routes/insights.ts +43 -0
  457. package/src/web/routes/patch.ts +117 -0
  458. package/src/web/routes/reports.ts +34 -0
  459. package/src/web/routes/rules.ts +101 -0
  460. package/src/web/routes/sessions.ts +262 -0
  461. package/src/web/routes/skill-stats.ts +132 -0
  462. package/src/web/routes/skills.ts +349 -0
  463. package/src/web/routes/static.ts +67 -0
  464. package/src/web/routes/stats.ts +60 -0
  465. package/src/web/routes/status.ts +30 -0
  466. package/src/web/routes/tasks.ts +218 -0
  467. package/src/web/routes/token-usage.ts +20 -0
  468. package/src/web/routes/trace.ts +138 -0
  469. package/src/web/routes/types.ts +56 -0
  470. package/src/web/server.ts +134 -0
  471. package/src/web/ssrf-guard.ts +112 -0
  472. package/src/web/static/index.html +3251 -0
  473. package/src/web/static/vendor/chart.umd.min.js +20 -0
  474. package/tests/e2e/dashboard.spec.ts +205 -0
  475. package/tests/e2e/routing-skill-e2e.test.ts +39 -0
  476. package/tests/helpers/mock-ai.ts +92 -0
  477. package/tests/helpers/mock-storage.ts +159 -0
  478. package/tests/integration/queue-replay.integration.test.ts +193 -0
  479. package/tests/integration/tasks-filter.integration.test.ts +154 -0
  480. package/tests/performance/database.benchmark.ts +161 -0
  481. package/tests/semantic-matcher.test.ts +99 -0
  482. package/tests/skill-matcher.test.ts +110 -0
  483. package/tests/unit/ai-provider-retry.test.ts +194 -0
  484. package/tests/unit/ai-provider-vision.test.ts +224 -0
  485. package/tests/unit/claudemd-generator.test.ts +68 -0
  486. package/tests/unit/cli-mcp.test.ts +141 -0
  487. package/tests/unit/handlers.test.ts +171 -0
  488. package/tests/unit/invocation-guard.test.ts +125 -0
  489. package/tests/unit/queue.test.ts +272 -0
  490. package/tests/unit/router.test.ts +138 -0
  491. package/tests/unit/security.test.ts +128 -0
  492. package/tests/unit/skill-invocations-workflow.test.ts +495 -0
  493. package/tests/unit/skill-registry.test.ts +94 -0
  494. package/tests/unit/skills/invocation-guard-ttl.test.ts +211 -0
  495. package/tests/unit/skills/official-skills-loader.test.ts +126 -0
  496. package/tests/unit/skills/registry-multiformat.test.ts +92 -0
  497. package/tests/unit/storage/sessions-aggregate.test.ts +435 -0
  498. package/tests/unit/storage/sqlite-refactor-harness.test.ts +314 -0
  499. package/tests/unit/storage.test.ts +172 -0
  500. package/tests/unit/token-usage.test.ts +144 -0
  501. package/tests/unit/type-guards.test.ts +201 -0
  502. package/tests/unit/utils/format.test.ts +189 -0
  503. package/tests/unit/utils/session.test.ts +89 -0
  504. package/tests/unit/utils/time.test.ts +112 -0
  505. package/tests/unit/web/routes-auth.test.ts +93 -0
  506. package/tests/unit/web/routes-events.test.ts +101 -0
  507. package/tests/unit/web/routes-sessions.test.ts +181 -0
  508. package/tests/unit/web/routes-skill-stats.test.ts +179 -0
  509. package/tests/unit/web/routes-stats.test.ts +92 -0
  510. package/tests/unit/web/routes-tasks.test.ts +351 -0
  511. package/tsconfig.json +22 -0
  512. package/vitest.config.ts +21 -0
  513. package/vitest.integration.config.ts +16 -0
  514. package/web/CLAUDE.md +20 -0
  515. package/web/index.html +13 -0
  516. package/web/package-lock.json +4854 -0
  517. package/web/package.json +35 -0
  518. package/web/postcss.config.js +6 -0
  519. package/web/src/App.tsx +110 -0
  520. package/web/src/components/CodeBlock.tsx +31 -0
  521. package/web/src/components/Confirm.tsx +96 -0
  522. package/web/src/components/Drawer.tsx +60 -0
  523. package/web/src/components/Layout.tsx +145 -0
  524. package/web/src/components/MarkdownRenderer.tsx +77 -0
  525. package/web/src/components/SearchInput.tsx +31 -0
  526. package/web/src/components/SessionDetailContent.tsx +157 -0
  527. package/web/src/components/Toast.tsx +92 -0
  528. package/web/src/index.css +19 -0
  529. package/web/src/main.tsx +31 -0
  530. package/web/src/pages/AIConfig.tsx +233 -0
  531. package/web/src/pages/Dashboard.tsx +572 -0
  532. package/web/src/pages/Events.tsx +271 -0
  533. package/web/src/pages/Reports.tsx +428 -0
  534. package/web/src/pages/SessionDetail.tsx +162 -0
  535. package/web/src/pages/Sessions.tsx +205 -0
  536. package/web/src/pages/Skills.tsx +180 -0
  537. package/web/src/pages/TaskDetail.tsx +511 -0
  538. package/web/src/pages/Tasks.tsx +150 -0
  539. package/web/src/utils/auth.ts +59 -0
  540. package/web/src/utils/export.ts +54 -0
  541. package/web/src/utils/time.ts +13 -0
  542. package/web/tailwind.config.js +11 -0
  543. package/web/tsconfig.json +21 -0
  544. package/web/tsconfig.node.json +10 -0
  545. package/web/vite.config.ts +76 -0
  546. package/winspan-claude-forge-8.43.0.tgz +0 -0
  547. package/dist/agents/definition.d.ts +0 -62
  548. package/dist/agents/definition.d.ts.map +0 -1
  549. package/dist/agents/definition.js +0 -27
  550. package/dist/agents/definition.js.map +0 -1
  551. package/dist/agents/distributor.d.ts +0 -23
  552. package/dist/agents/distributor.d.ts.map +0 -1
  553. package/dist/agents/distributor.js +0 -85
  554. package/dist/agents/distributor.js.map +0 -1
  555. package/dist/agents/index.d.ts +0 -5
  556. package/dist/agents/index.d.ts.map +0 -1
  557. package/dist/agents/index.js +0 -5
  558. package/dist/agents/index.js.map +0 -1
  559. package/dist/agents/methodologies/agent-builder.d.ts +0 -21
  560. package/dist/agents/methodologies/agent-builder.d.ts.map +0 -1
  561. package/dist/agents/methodologies/agent-builder.js +0 -149
  562. package/dist/agents/methodologies/agent-builder.js.map +0 -1
  563. package/dist/agents/methodologies/phases/bmad/analyze.d.ts +0 -3
  564. package/dist/agents/methodologies/phases/bmad/analyze.d.ts.map +0 -1
  565. package/dist/agents/methodologies/phases/bmad/analyze.js +0 -19
  566. package/dist/agents/methodologies/phases/bmad/analyze.js.map +0 -1
  567. package/dist/agents/methodologies/phases/bmad/design.d.ts +0 -3
  568. package/dist/agents/methodologies/phases/bmad/design.d.ts.map +0 -1
  569. package/dist/agents/methodologies/phases/bmad/design.js +0 -18
  570. package/dist/agents/methodologies/phases/bmad/design.js.map +0 -1
  571. package/dist/agents/methodologies/phases/bmad/implement.d.ts +0 -3
  572. package/dist/agents/methodologies/phases/bmad/implement.d.ts.map +0 -1
  573. package/dist/agents/methodologies/phases/bmad/implement.js +0 -17
  574. package/dist/agents/methodologies/phases/bmad/implement.js.map +0 -1
  575. package/dist/agents/methodologies/phases/bmad/index.d.ts +0 -6
  576. package/dist/agents/methodologies/phases/bmad/index.d.ts.map +0 -1
  577. package/dist/agents/methodologies/phases/bmad/index.js +0 -6
  578. package/dist/agents/methodologies/phases/bmad/index.js.map +0 -1
  579. package/dist/agents/methodologies/phases/bmad/review.d.ts +0 -3
  580. package/dist/agents/methodologies/phases/bmad/review.d.ts.map +0 -1
  581. package/dist/agents/methodologies/phases/bmad/review.js +0 -17
  582. package/dist/agents/methodologies/phases/bmad/review.js.map +0 -1
  583. package/dist/agents/methodologies/phases/bmad/test.d.ts +0 -3
  584. package/dist/agents/methodologies/phases/bmad/test.d.ts.map +0 -1
  585. package/dist/agents/methodologies/phases/bmad/test.js +0 -21
  586. package/dist/agents/methodologies/phases/bmad/test.js.map +0 -1
  587. package/dist/agents/methodologies/phases/harness/fix.d.ts +0 -3
  588. package/dist/agents/methodologies/phases/harness/fix.d.ts.map +0 -1
  589. package/dist/agents/methodologies/phases/harness/fix.js +0 -17
  590. package/dist/agents/methodologies/phases/harness/fix.js.map +0 -1
  591. package/dist/agents/methodologies/phases/harness/index.d.ts +0 -6
  592. package/dist/agents/methodologies/phases/harness/index.d.ts.map +0 -1
  593. package/dist/agents/methodologies/phases/harness/index.js +0 -6
  594. package/dist/agents/methodologies/phases/harness/index.js.map +0 -1
  595. package/dist/agents/methodologies/phases/harness/reproduce.d.ts +0 -3
  596. package/dist/agents/methodologies/phases/harness/reproduce.d.ts.map +0 -1
  597. package/dist/agents/methodologies/phases/harness/reproduce.js +0 -20
  598. package/dist/agents/methodologies/phases/harness/reproduce.js.map +0 -1
  599. package/dist/agents/methodologies/phases/harness/root-cause.d.ts +0 -3
  600. package/dist/agents/methodologies/phases/harness/root-cause.d.ts.map +0 -1
  601. package/dist/agents/methodologies/phases/harness/root-cause.js +0 -21
  602. package/dist/agents/methodologies/phases/harness/root-cause.js.map +0 -1
  603. package/dist/agents/methodologies/phases/harness/safety-net.d.ts +0 -3
  604. package/dist/agents/methodologies/phases/harness/safety-net.d.ts.map +0 -1
  605. package/dist/agents/methodologies/phases/harness/safety-net.js +0 -17
  606. package/dist/agents/methodologies/phases/harness/safety-net.js.map +0 -1
  607. package/dist/agents/methodologies/phases/harness/verify.d.ts +0 -3
  608. package/dist/agents/methodologies/phases/harness/verify.d.ts.map +0 -1
  609. package/dist/agents/methodologies/phases/harness/verify.js +0 -22
  610. package/dist/agents/methodologies/phases/harness/verify.js.map +0 -1
  611. package/dist/agents/methodologies/presets.d.ts +0 -10
  612. package/dist/agents/methodologies/presets.d.ts.map +0 -1
  613. package/dist/agents/methodologies/presets.js +0 -79
  614. package/dist/agents/methodologies/presets.js.map +0 -1
  615. package/dist/agents/methodologies/types.d.ts +0 -45
  616. package/dist/agents/methodologies/types.d.ts.map +0 -1
  617. package/dist/agents/methodologies/types.js +0 -10
  618. package/dist/agents/methodologies/types.js.map +0 -1
  619. package/dist/agents/methodologies/user-config-loader.d.ts +0 -30
  620. package/dist/agents/methodologies/user-config-loader.d.ts.map +0 -1
  621. package/dist/agents/methodologies/user-config-loader.js +0 -159
  622. package/dist/agents/methodologies/user-config-loader.js.map +0 -1
  623. package/dist/agents/official-agents.d.ts +0 -4
  624. package/dist/agents/official-agents.d.ts.map +0 -1
  625. package/dist/agents/official-agents.js +0 -559
  626. package/dist/agents/official-agents.js.map +0 -1
  627. package/dist/agents/registry.d.ts +0 -57
  628. package/dist/agents/registry.d.ts.map +0 -1
  629. package/dist/agents/registry.js +0 -271
  630. package/dist/agents/registry.js.map +0 -1
  631. package/dist/capability/index.d.ts +0 -10
  632. package/dist/capability/index.d.ts.map +0 -1
  633. package/dist/capability/index.js +0 -10
  634. package/dist/capability/index.js.map +0 -1
  635. package/dist/capability/types.d.ts +0 -10
  636. package/dist/capability/types.d.ts.map +0 -1
  637. package/dist/capability/types.js +0 -10
  638. package/dist/capability/types.js.map +0 -1
  639. package/dist/cli/commands/agents.d.ts +0 -3
  640. package/dist/cli/commands/agents.d.ts.map +0 -1
  641. package/dist/cli/commands/agents.js +0 -62
  642. package/dist/cli/commands/agents.js.map +0 -1
  643. package/dist/cli/commands/rules.d.ts +0 -8
  644. package/dist/cli/commands/rules.d.ts.map +0 -1
  645. package/dist/cli/commands/rules.js +0 -89
  646. package/dist/cli/commands/rules.js.map +0 -1
  647. package/dist/daemon/auto-disable-scheduler.d.ts +0 -53
  648. package/dist/daemon/auto-disable-scheduler.d.ts.map +0 -1
  649. package/dist/daemon/auto-disable-scheduler.js +0 -114
  650. package/dist/daemon/auto-disable-scheduler.js.map +0 -1
  651. package/dist/daemon/handlers/pre-tool-use.d.ts +0 -39
  652. package/dist/daemon/handlers/pre-tool-use.d.ts.map +0 -1
  653. package/dist/daemon/handlers/pre-tool-use.js +0 -166
  654. package/dist/daemon/handlers/pre-tool-use.js.map +0 -1
  655. package/dist/daemon/routing-observer.d.ts +0 -42
  656. package/dist/daemon/routing-observer.d.ts.map +0 -1
  657. package/dist/daemon/routing-observer.js +0 -264
  658. package/dist/daemon/routing-observer.js.map +0 -1
  659. package/dist/daemon/routing-state.d.ts +0 -64
  660. package/dist/daemon/routing-state.d.ts.map +0 -1
  661. package/dist/daemon/routing-state.js +0 -240
  662. package/dist/daemon/routing-state.js.map +0 -1
  663. package/dist/engine/agent-router.d.ts +0 -142
  664. package/dist/engine/agent-router.d.ts.map +0 -1
  665. package/dist/engine/agent-router.js +0 -276
  666. package/dist/engine/agent-router.js.map +0 -1
  667. package/dist/engine/context-builder.d.ts +0 -23
  668. package/dist/engine/context-builder.d.ts.map +0 -1
  669. package/dist/engine/context-builder.js +0 -63
  670. package/dist/engine/context-builder.js.map +0 -1
  671. package/dist/engine/conventions/basic-security.yaml +0 -109
  672. package/dist/engine/conventions/code-quality.yaml +0 -123
  673. package/dist/engine/conventions/database-safety.yaml +0 -74
  674. package/dist/engine/conventions/dependency-safety.yaml +0 -132
  675. package/dist/engine/conventions/docker-safety.yaml +0 -69
  676. package/dist/engine/conventions/git-safety.yaml +0 -118
  677. package/dist/engine/conventions/go-best-practices.yaml +0 -84
  678. package/dist/engine/conventions/python-best-practices.yaml +0 -96
  679. package/dist/engine/conventions/react-best-practices.yaml +0 -96
  680. package/dist/engine/conventions/routing.yaml +0 -378
  681. package/dist/engine/conventions/strict-security.yaml +0 -30
  682. package/dist/engine/conventions/ts-quality.yaml +0 -49
  683. package/dist/engine/dsl/compiler.d.ts +0 -34
  684. package/dist/engine/dsl/compiler.d.ts.map +0 -1
  685. package/dist/engine/dsl/compiler.js +0 -702
  686. package/dist/engine/dsl/compiler.js.map +0 -1
  687. package/dist/engine/dsl/parser.d.ts +0 -25
  688. package/dist/engine/dsl/parser.d.ts.map +0 -1
  689. package/dist/engine/dsl/parser.js +0 -208
  690. package/dist/engine/dsl/parser.js.map +0 -1
  691. package/dist/engine/dsl/runtime.d.ts +0 -46
  692. package/dist/engine/dsl/runtime.d.ts.map +0 -1
  693. package/dist/engine/dsl/runtime.js +0 -173
  694. package/dist/engine/dsl/runtime.js.map +0 -1
  695. package/dist/engine/dsl/types.d.ts +0 -139
  696. package/dist/engine/dsl/types.d.ts.map +0 -1
  697. package/dist/engine/dsl/types.js +0 -11
  698. package/dist/engine/dsl/types.js.map +0 -1
  699. package/dist/engine/evidence-store.d.ts +0 -44
  700. package/dist/engine/evidence-store.d.ts.map +0 -1
  701. package/dist/engine/evidence-store.js +0 -109
  702. package/dist/engine/evidence-store.js.map +0 -1
  703. package/dist/engine/experiment-router.d.ts +0 -102
  704. package/dist/engine/experiment-router.d.ts.map +0 -1
  705. package/dist/engine/experiment-router.js +0 -289
  706. package/dist/engine/experiment-router.js.map +0 -1
  707. package/dist/engine/recommender.d.ts +0 -52
  708. package/dist/engine/recommender.d.ts.map +0 -1
  709. package/dist/engine/recommender.js +0 -162
  710. package/dist/engine/recommender.js.map +0 -1
  711. package/dist/engine/rule-engine.d.ts +0 -33
  712. package/dist/engine/rule-engine.d.ts.map +0 -1
  713. package/dist/engine/rule-engine.js +0 -250
  714. package/dist/engine/rule-engine.js.map +0 -1
  715. package/dist/engine/security-gates.d.ts +0 -42
  716. package/dist/engine/security-gates.d.ts.map +0 -1
  717. package/dist/engine/security-gates.js +0 -210
  718. package/dist/engine/security-gates.js.map +0 -1
  719. package/dist/intelligence/classifier.d.ts +0 -75
  720. package/dist/intelligence/classifier.d.ts.map +0 -1
  721. package/dist/intelligence/classifier.js +0 -352
  722. package/dist/intelligence/classifier.js.map +0 -1
  723. package/dist/intelligence/context-gatherer.d.ts +0 -101
  724. package/dist/intelligence/context-gatherer.d.ts.map +0 -1
  725. package/dist/intelligence/context-gatherer.js +0 -417
  726. package/dist/intelligence/context-gatherer.js.map +0 -1
  727. package/dist/intelligence/cot-classifier.d.ts +0 -95
  728. package/dist/intelligence/cot-classifier.d.ts.map +0 -1
  729. package/dist/intelligence/cot-classifier.js +0 -391
  730. package/dist/intelligence/cot-classifier.js.map +0 -1
  731. package/dist/intelligence/distiller.d.ts +0 -22
  732. package/dist/intelligence/distiller.d.ts.map +0 -1
  733. package/dist/intelligence/distiller.js +0 -108
  734. package/dist/intelligence/distiller.js.map +0 -1
  735. package/dist/intelligence/execution-doc-builder.d.ts +0 -151
  736. package/dist/intelligence/execution-doc-builder.d.ts.map +0 -1
  737. package/dist/intelligence/execution-doc-builder.js +0 -1018
  738. package/dist/intelligence/execution-doc-builder.js.map +0 -1
  739. package/dist/intelligence/intent-types.d.ts +0 -13
  740. package/dist/intelligence/intent-types.d.ts.map +0 -1
  741. package/dist/intelligence/intent-types.js +0 -19
  742. package/dist/intelligence/intent-types.js.map +0 -1
  743. package/dist/intelligence/multimodal-parser.d.ts +0 -105
  744. package/dist/intelligence/multimodal-parser.d.ts.map +0 -1
  745. package/dist/intelligence/multimodal-parser.js +0 -425
  746. package/dist/intelligence/multimodal-parser.js.map +0 -1
  747. package/dist/intelligence/quality-gate.d.ts +0 -45
  748. package/dist/intelligence/quality-gate.d.ts.map +0 -1
  749. package/dist/intelligence/quality-gate.js +0 -193
  750. package/dist/intelligence/quality-gate.js.map +0 -1
  751. package/dist/intelligence/task-segmenter.d.ts.map +0 -1
  752. package/dist/intelligence/task-segmenter.js.map +0 -1
  753. package/dist/web/routes/agents.d.ts +0 -7
  754. package/dist/web/routes/agents.d.ts.map +0 -1
  755. package/dist/web/routes/agents.js +0 -209
  756. package/dist/web/routes/agents.js.map +0 -1
  757. package/dist/web/routes/execution-trace.d.ts +0 -21
  758. package/dist/web/routes/execution-trace.d.ts.map +0 -1
  759. package/dist/web/routes/execution-trace.js +0 -353
  760. package/dist/web/routes/execution-trace.js.map +0 -1
  761. package/dist/web/routes/experiments.d.ts +0 -15
  762. package/dist/web/routes/experiments.d.ts.map +0 -1
  763. package/dist/web/routes/experiments.js +0 -187
  764. package/dist/web/routes/experiments.js.map +0 -1
  765. package/dist/web/routes/routing.d.ts +0 -17
  766. package/dist/web/routes/routing.d.ts.map +0 -1
  767. package/dist/web/routes/routing.js +0 -592
  768. package/dist/web/routes/routing.js.map +0 -1
  769. package/dist/web/routes/workflows.d.ts +0 -19
  770. package/dist/web/routes/workflows.d.ts.map +0 -1
  771. package/dist/web/routes/workflows.js +0 -86
  772. package/dist/web/routes/workflows.js.map +0 -1
  773. package/dist/web/static/assets/AIConfig-R5wZ3ZKT.js +0 -2
  774. package/dist/web/static/assets/AIConfig-R5wZ3ZKT.js.map +0 -1
  775. package/dist/web/static/assets/Agents-Beg34V1g.js +0 -2
  776. package/dist/web/static/assets/Agents-Beg34V1g.js.map +0 -1
  777. package/dist/web/static/assets/CodeBlock--H53gk46.js +0 -2
  778. package/dist/web/static/assets/CodeBlock--H53gk46.js.map +0 -1
  779. package/dist/web/static/assets/Dashboard-Cy1xsj1J.js +0 -2
  780. package/dist/web/static/assets/Dashboard-Cy1xsj1J.js.map +0 -1
  781. package/dist/web/static/assets/Events-mFhXl4zI.js +0 -2
  782. package/dist/web/static/assets/Events-mFhXl4zI.js.map +0 -1
  783. package/dist/web/static/assets/ExecutionTrace-DG901hLR.js +0 -3
  784. package/dist/web/static/assets/ExecutionTrace-DG901hLR.js.map +0 -1
  785. package/dist/web/static/assets/MarkdownRenderer-CCIz1MOz.js +0 -2
  786. package/dist/web/static/assets/MarkdownRenderer-CCIz1MOz.js.map +0 -1
  787. package/dist/web/static/assets/Routing-B7BFLfjh.js +0 -2
  788. package/dist/web/static/assets/Routing-B7BFLfjh.js.map +0 -1
  789. package/dist/web/static/assets/SessionDetail-BT0l4RrK.js +0 -2
  790. package/dist/web/static/assets/SessionDetail-BT0l4RrK.js.map +0 -1
  791. package/dist/web/static/assets/Sessions-C6J_HQ_u.js +0 -2
  792. package/dist/web/static/assets/Sessions-C6J_HQ_u.js.map +0 -1
  793. package/dist/web/static/assets/Skills-4DQWLaTv.js +0 -2
  794. package/dist/web/static/assets/Skills-4DQWLaTv.js.map +0 -1
  795. package/dist/web/static/assets/WorkflowDetail-zhNqUkBE.js +0 -2
  796. package/dist/web/static/assets/WorkflowDetail-zhNqUkBE.js.map +0 -1
  797. package/dist/web/static/assets/Workflows-Btvi-lGw.js +0 -2
  798. package/dist/web/static/assets/Workflows-Btvi-lGw.js.map +0 -1
  799. package/dist/web/static/assets/export-BQQZLaHV.js +0 -4
  800. package/dist/web/static/assets/export-BQQZLaHV.js.map +0 -1
  801. package/dist/web/static/assets/index-Cgr9qMtq.js +0 -3
  802. package/dist/web/static/assets/index-Cgr9qMtq.js.map +0 -1
  803. package/dist/web/static/assets/index-CngWb5gC.css +0 -1
  804. package/dist/web/static/assets/lucide-53bR2rki.js.map +0 -1
@@ -0,0 +1,232 @@
1
+ # claude-forge 架构评审报告
2
+
3
+ 生成时间:2026-05-16
4
+
5
+ ## 一、当前架构概览
6
+
7
+ ### 1.1 分层架构
8
+
9
+ ```
10
+ claude-forge/
11
+ ├── src/
12
+ │ ├── cli/ # CLI 命令层(用户交互入口)
13
+ │ ├── daemon/ # 守护进程层(事件处理、生命周期管理)
14
+ │ ├── web/ # Web API 层(Express + React Dashboard)
15
+ │ ├── mcp/ # MCP 协议层(Model Context Protocol)
16
+ │ ├── core/ # 核心共享层(storage、config、types、ai)
17
+ │ ├── skills/ # Skill 匹配与注入层
18
+ │ ├── claudemd/ # CLAUDE.md 生成器
19
+ │ └── templates/ # 模板管理
20
+ ├── tests/
21
+ │ └── integration/ # 集成测试(28 个测试文件)
22
+ └── web/ # React 前端源码
23
+ ```
24
+
25
+ ### 1.2 核心依赖关系
26
+
27
+ ```
28
+ ┌─────────────────────────────────────┐
29
+ │ CLI (用户入口) │
30
+ └──────────────┬──────────────────────┘
31
+
32
+ ┌───────┴────────┐
33
+ ▼ ▼
34
+ ┌──────────────┐ ┌──────────────┐
35
+ │ Daemon │ │ Web │
36
+ │ (事件处理) │ │ (API/UI) │
37
+ └──────┬───────┘ └──────┬───────┘
38
+ │ │
39
+ └────────┬────────┘
40
+
41
+ ┌───────────────┐
42
+ │ Core │
43
+ │ (storage/ai) │
44
+ └───────┬───────┘
45
+
46
+ ┌───────┴────────┐
47
+ ▼ ▼
48
+ ┌──────────┐ ┌──────────┐
49
+ │ Skills │ │ CLAUDEmd │
50
+ │ (匹配器) │ │ (生成器) │
51
+ └──────────┘ └──────────┘
52
+ ```
53
+
54
+ ### 1.3 数据流
55
+
56
+ ```
57
+ Claude Code Hook
58
+ ↓ (Unix Socket)
59
+ Daemon Server (router.ts)
60
+
61
+ Event Handlers (user-prompt.ts / post-tool-use.ts / stop.ts)
62
+
63
+ Storage (SQLite) + Services (TaskSegmenter / ResumeManager / SkillRegistry)
64
+
65
+ Injection (systemMessage / additionalContext)
66
+
67
+ Claude Code (返回给 AI)
68
+ ```
69
+
70
+ ## 二、发现的问题
71
+
72
+ ### 2.1 严重问题(P0)
73
+
74
+ **无严重架构问题**
75
+
76
+ 当前架构清晰,分层合理,依赖方向正确(单向依赖 core)。
77
+
78
+ ### 2.2 中等问题(P1)
79
+
80
+ #### 问题 1:单元测试缺失
81
+
82
+ - **现状**:`src/` 目录下 0 个单元测试,仅 `tests/integration/` 有 28 个集成测试
83
+ - **影响**:重构风险高,无法快速验证单个模块的正确性
84
+ - **位置**:所有 `src/**/*.ts` 文件
85
+ - **建议**:为 core 层(storage/utils/types)补充单元测试
86
+
87
+ #### 问题 2:Web 层路由文件过多
88
+
89
+ - **现状**:`src/web/routes/` 下有 15+ 个路由文件
90
+ - **影响**:维护成本高,每个功能一个文件略显碎片化
91
+ - **位置**:`src/web/routes/`
92
+ - **建议**:考虑按功能域合并(如 stats + skill-stats + reports + insights 合并为 analytics 路由)
93
+
94
+ ### 2.3 轻微问题(P2)
95
+
96
+ #### 问题 3:Daemon 主文件职责过多
97
+
98
+ - **现状**:`src/daemon/index.ts` 包含初始化、生命周期、事件处理、维护任务等多个职责
99
+ - **影响**:文件较长(250 行),职责边界不够清晰
100
+ - **位置**:`src/daemon/index.ts`
101
+ - **建议**:将维护任务(maintenance interval)抽取为独立模块
102
+
103
+ #### 问题 4:Storage 层已重构但缺乏文档
104
+
105
+ - **现状**:`sqlite.ts` 已从 1000+ 行单文件拆分为 9 个 Operations 类,但重构文档缺失
106
+ - **影响**:新开发者可能不清楚如何添加新的存储操作
107
+ - **位置**:`src/core/storage/`
108
+ - **建议**:添加 `README.md` 说明存储层架构和扩展方式
109
+
110
+ #### 问题 5:类型系统可以更严格
111
+
112
+ - **现状**:`ForgeEvent` 使用可选字段(`tool_name?`),需要运行时检查
113
+ - **影响**:类型安全性略低,需要 type guard 保护
114
+ - **位置**:`src/core/types.ts`
115
+ - **建议**:当前已通过 `ForgeEventNarrow` 联合类型解决,无需进一步优化
116
+
117
+ ## 三、重构必要性评估
118
+
119
+ ### 评估结论:**建议优化,无需大规模重构**
120
+
121
+ ### 理由
122
+
123
+ 1. **架构健康度高**
124
+ - 分层清晰(CLI / Daemon / Web / Core)
125
+ - 依赖方向正确(单向依赖 core)
126
+ - 模块边界明确(storage / skills / claudemd)
127
+
128
+ 2. **已有重构基础良好**
129
+ - Storage 层已完成职责拆分(9 个 Operations 类)
130
+ - 类型系统已优化(ForgeEvent → ForgeEventNarrow)
131
+ - 命名规范已统一(kebab-case 文件名)
132
+
133
+ 3. **主要问题是测试覆盖不足**
134
+ - 缺少单元测试是新功能的最大风险
135
+ - 但不需要架构重构,只需补充测试
136
+
137
+ ### 如果要重构,优先级排序
138
+
139
+ 1. **P1:补充单元测试**(提升重构信心)
140
+ - 范围:core/storage, core/utils, daemon/handlers
141
+ - 工作量:中等(约 2-3 周)
142
+ - 风险:低(不改变现有代码)
143
+
144
+ 2. **P2:合并 Web 路由**(降低维护成本)
145
+ - 范围:stats + skill-stats + reports + insights → analytics
146
+ - 工作量:小(约 2-3 天)
147
+ - 风险:低(仅文件合并)
148
+
149
+ 3. **P3:抽取 Daemon 维护任务**(职责分离)
150
+ - 范围:daemon/index.ts 中的 maintenance interval
151
+ - 工作量:极小(约 1 天)
152
+ - 风险:极低(纯重构)
153
+
154
+ ## 四、升维优化方向(如果决定重构)
155
+
156
+ ### 方向 1:事件驱动架构升级
157
+
158
+ **目标**:将当前同步事件处理改为异步消息队列
159
+
160
+ **收益**:
161
+ - 提升吞吐量(高并发场景)
162
+ - 支持事件重放和恢复
163
+ - 解耦事件生产者和消费者
164
+
165
+ **代价**:
166
+ - 引入消息队列(如 BullMQ)
167
+ - 架构复杂度上升
168
+ - 需要处理消息幂等性
169
+
170
+ **适用场景**:单机事件量 > 10万/天
171
+
172
+ ### 方向 2:插件化架构
173
+
174
+ **目标**:将 Skills、CLAUDE.md、Handlers 都设计为可插拔插件
175
+
176
+ **收益**:
177
+ - 用户可自定义扩展(如自定义 Handler)
178
+ - 核心代码更稳定
179
+ - 便于社区贡献
180
+
181
+ **代价**:
182
+ - 需要设计插件 API
183
+ - 插件版本管理复杂
184
+ - 文档负担增加
185
+
186
+ **适用场景**:用户有自定义扩展需求
187
+
188
+ ### 方向 3:多租户隔离
189
+
190
+ **目标**:支持多项目隔离存储和配置
191
+
192
+ **收益**:
193
+ - 支持团队协作场景
194
+ - 数据隔离更安全
195
+ - 可支持 SaaS 模式
196
+
197
+ **代价**:
198
+ - 数据库 schema 需要调整
199
+ - 权限控制复杂度上升
200
+ - 需要租户管理功能
201
+
202
+ **适用场景**:企业级团队使用
203
+
204
+ ## 五、建议
205
+
206
+ ### 短期建议(1-2 个月)
207
+
208
+ 1. **补充单元测试**:优先为 core/storage 和 daemon/handlers 添加测试
209
+ 2. **添加存储层文档**:在 `src/core/storage/README.md` 说明架构
210
+ 3. **合并 Web 路由**:将相关路由文件合并(analytics 相关)
211
+
212
+ ### 中期建议(3-6 个月)
213
+
214
+ 1. **评估事件驱动升级**:如果事件量增长,考虑引入消息队列
215
+ 2. **插件化设计调研**:如果用户有自定义需求,启动插件 API 设计
216
+
217
+ ### 长期建议(6-12 个月)
218
+
219
+ 1. **多租户支持**:如果转向企业级产品,启动多租户架构设计
220
+
221
+ ## 六、总结
222
+
223
+ **当前架构评级:B+(良好)**
224
+
225
+ - ✅ 分层清晰,依赖方向正确
226
+ - ✅ 已完成部分重构(Storage 层拆分)
227
+ - ⚠️ 单元测试缺失,重构风险较高
228
+ - ⚠️ Web 路由略碎片化
229
+
230
+ **核心建议:补充测试 > 小范围优化 > 大规模重构**
231
+
232
+ 当前架构足够支撑业务发展,优先补充测试覆盖,无需立即进行大规模重构。
@@ -0,0 +1,219 @@
1
+ # Fix Spec: Official Skills 数据分离 + UserPromptHandler Set 内存泄漏
2
+
3
+ **日期**: 2026-05-16
4
+ **状态**: Draft(待用户 review)
5
+
6
+ ---
7
+
8
+ ## 一、目标
9
+
10
+ | # | 修复点 | 成功标准 |
11
+ |---|--------|---------|
12
+ | 1 | Official Skills 数据/代码分离 | `official-skills.ts` 不再包含任何 skill 内容字符串;新增 `.md` 文件可被 `tsc` + `npm pack` 正确带入 `dist/` |
13
+ | 2 | UserPromptHandler 无界 Set 内存泄漏 | `resumeInjected` / `conventionInjected` Set 在 session 结束后被清理,或存在 LRU 上限,daemon 长期运行不会无限增长 |
14
+
15
+ ---
16
+
17
+ ## 二、调研结论摘要
18
+
19
+ ### 修复点 1 — 现状数据结构
20
+
21
+ `OfficialSkill` 接口(`src/skills/official-skills.ts:6-12`)有 5 个字段:
22
+
23
+ | 字段 | 类型 | 说明 |
24
+ |------|------|------|
25
+ | `name` | `string` | skill id,如 `official-tdd` |
26
+ | `version` | `string` | 版本号,如 `1.2.0` |
27
+ | `description` | `string` | 一句话描述 |
28
+ | `keywords` | `string[]` | 关键词(部分 skill 有扩展 keywords 在 `OFFICIAL_SKILL_KEYWORDS` 里) |
29
+ | `content` | `string` | 完整 `.md` 文本,包含 frontmatter |
30
+
31
+ 共 19 个 skill(OFFICIAL_SKILLS 数组) + 1 个关键词映射表 `OFFICIAL_SKILL_KEYWORDS`(19 条)。
32
+ `content` 字段本身已是 frontmatter+body 的完整 markdown,说明 skill 文件可直接拆分为独立 `.md`。
33
+
34
+ ### 修复点 1 — npm 发布打包现状
35
+
36
+ `package.json` 无 `files` 字段,默认发布全部未被 `.gitignore` 的文件。
37
+ `build` 脚本(`package.json:13`)仅用 `tsc` 编译 `src/**/*.ts` 到 `dist/`,静态文件靠 `cp` 显式拷贝(`schema.sql`、`hooks/*.sh`、`launchd/*.template`)。
38
+ **关键结论**:`.md` 数据文件不在 `tsc` 编译范围内,**需要在 build 脚本中加 `cp` 命令**,否则 `dist/` 运行时找不到文件。
39
+
40
+ ### 修复点 1 — registry 加载逻辑
41
+
42
+ `SkillRegistry.scan()`(`src/skills/registry.ts:49-133`)分两段:
43
+ 1. 先循环 `OFFICIAL_SKILLS` 数组,直接写入 Map(无文件读取)
44
+ 2. 再扫 `~/.claude/skills/*.md`,用 `gray-matter` 解析
45
+
46
+ 改造后只需把第 1 段改为扫内置目录的 `.md`,解析逻辑与第 2 段完全一致。
47
+
48
+ ### 修复点 2 — Set 的语义
49
+
50
+ 两个 Set 均以 `${session_id}:${project_path}` 为 key,目的是**每个 session 只注入一次 resume/convention**。
51
+
52
+ `InvocationGuard` 的参考方案(`src/skills/invocation-guard.ts`):
53
+ - 用 `Map<sessionId, SessionInvocations>` 存状态
54
+ - 有 TTL(30 min)+ 5 min 定时清理
55
+ - StopHandler 显式调用 `guard.clear(sessionId)`(`src/daemon/handlers/stop.ts:61-65`)
56
+
57
+ 两种修复方案对比:
58
+
59
+ | | 方案 A:StopHandler 清理 | 方案 B:TTL + 定时清理 |
60
+ |-|---|---|
61
+ | 原理 | Stop 事件时从 Set 删除对应 key | 用 `Map<key, {timestamp}>` 替换 Set,定期扫描过期 |
62
+ | 实现复杂度 | 低(3-5 行)| 中(需改 Set 为 Map + 定时器)|
63
+ | 覆盖范围 | 正常关闭的 session | 还能覆盖 crash/无 Stop 事件的情况 |
64
+ | 与现有代码一致性 | 与 InvocationGuard.clear() 模式完全一致 | 需引入新依赖模式 |
65
+ | 内存界限保证 | 依赖 Stop 事件的完整性 | 绝对有界 |
66
+
67
+ **结论**:采用 **方案 A(StopHandler 清理)为主 + 方案 B LRU 上限 1000 为兜底**,两者互补。
68
+
69
+ ---
70
+
71
+ ## 三、改动文件清单
72
+
73
+ ### 修复点 1
74
+
75
+ | 文件路径 | 改动类型 | 改动概述 |
76
+ |----------|----------|---------|
77
+ | `src/skills/official/*.md` | **新建 19 个文件** | 每个 skill 对应一个 `.md`,内容为现有 `content` 字段(已含 frontmatter);skill `name` 和 `version` 在 frontmatter 中保留 |
78
+ | `src/skills/official-skills.ts` | **大幅削减** | 删除 `OFFICIAL_SKILLS` 数组全部 skill 字面量;保留 `OFFICIAL_SKILL_KEYWORDS` 常量和 `OfficialSkill` 接口(供类型引用);新增导出函数 `loadOfficialSkills(builtinDir: string): OfficialSkill[]` |
79
+ | `src/skills/registry.ts` | **修改** | `scan()` 第 1 段改为调用 `loadOfficialSkills(resolveBuiltinDir())`;新增私有方法 `resolveBuiltinDir()` 解析 `import.meta.url` 相对路径(兼容 npm 安装和开发环境)|
80
+ | `package.json` | **修改** | `build` 脚本末尾追加 `mkdir -p dist/skills/official && cp src/skills/official/*.md dist/skills/official/` |
81
+ | `tests/unit/skill-registry.test.ts` | **修改** | 调整 skill 数量断言(现在硬编码 `>= 16`,改为 `>= 19` 或使用动态读取数量)|
82
+
83
+ ### 修复点 2
84
+
85
+ | 文件路径 | 改动类型 | 改动概述 |
86
+ |----------|----------|---------|
87
+ | `src/daemon/handlers/user-prompt.ts` | **修改** | 将两个 `Set<string>` 改为 `Map<string, number>`(值存写入时间戳);新增 `clearSession(sessionKey: string)` 公共方法;新增静态常量 `MAX_INJECTION_KEYS = 1000` 作为 LRU 上限兜底 |
88
+ | `src/daemon/handlers/stop.ts` | **修改** | 在 Step 4(InvocationGuard 清理)之后,增加 Step 5:调用 `userPromptHandler.clearSession(sessionKey)` |
89
+ | `src/daemon/index.ts` 或 handler 初始化处 | **修改**(视注入方式) | 确保 `StopHandler` 持有 `UserPromptHandler` 的引用,或通过事件总线传递 |
90
+ | `tests/unit/handlers.test.ts` | **修改** | 新增 case:同一 session 两次调用只注入一次;stop 后再次调用会重新注入 |
91
+
92
+ ---
93
+
94
+ ## 四、关键设计决策
95
+
96
+ ### 修复点 1
97
+
98
+ **决策 1-A:每个 skill 一个 `.md` 文件,不拆 json+md**
99
+
100
+ 理由:`content` 字段本身已是 frontmatter+markdown 格式,直接拆分零转换成本。独立文件对 diff 友好,增删 skill 只需增删一个文件。避免引入额外的索引文件维护负担。
101
+
102
+ **决策 1-B:文件放在 `src/skills/official/` 而非 `data/official-skills/`**
103
+
104
+ 理由:与其他 skill 相关代码同目录,减少跨目录路径解析复杂度。`tsc` 的 `rootDir` 是 `src/`,`outDir` 是 `dist/`,拷贝路径天然对应 `dist/skills/official/`,逻辑清晰。
105
+
106
+ **决策 1-C:`loadOfficialSkills` 接收 `builtinDir` 参数而非硬编码 `__dirname`**
107
+
108
+ 理由:便于单元测试(可传入临时目录)。`registry.ts` 中统一用 `resolveBuiltinDir()` 计算路径,该函数用 `import.meta.url` 解析(ESM 环境),兼容 npm 全局安装后路径变更的场景(参考 `feedback_npm_path.md` 记录的教训)。
109
+
110
+ ### 修复点 2
111
+
112
+ **决策 2-A:采用方案 A(Stop 清理)+ 方案 B(LRU 上限 1000)双保险**
113
+
114
+ 理由:方案 A 是精确清理,与 InvocationGuard 模式一致,代码可读性强;方案 B 兜底 crash/无 Stop 场景。上限 1000 entry 约占内存 < 100KB(每个 key 约 80 bytes),完全可接受。
115
+
116
+ **决策 2-B:将 Set 改为 `Map<string, number>`(保存 timestamp),不引入 TTL 定时器**
117
+
118
+ 理由:timestamp 用于 LRU 淘汰,在 `add` 时若超过 1000 条则删最旧的一条。不需要独立定时器(依赖 Stop 清理 + 容量上限已足够),避免增加守护进程复杂度。
119
+
120
+ **决策 2-C:新增 `clearSession(sessionKey)` 为 public 方法,不通过构造函数注入 StopHandler**
121
+
122
+ 理由:`UserPromptHandler` 不应依赖 `StopHandler`,应由 `StopHandler` 持有 `UserPromptHandler` 的引用(单向依赖)。在 daemon 初始化时将 `UserPromptHandler` 实例传入 `StopHandler` 构造函数(或 setter)。
123
+
124
+ ---
125
+
126
+ ## 五、风险点
127
+
128
+ | 风险 | 影响 | 缓解措施 |
129
+ |------|------|---------|
130
+ | **npm 发布后找不到 `.md` 文件** | 运行时加载 0 个 official skill,功能退化 | build 脚本加 `cp`;发布前验证 `dist/skills/official/` 目录存在(可加 `prebuild` 检查) |
131
+ | **`import.meta.url` 路径解析在 CJS 降级时失效** | N/A(项目是纯 ESM,`"type": "module"`)| 无需处理 |
132
+ | **`StopHandler` 持有 `UserPromptHandler` 引用导致循环依赖** | 编译报错 | 检查依赖链:`user-prompt.ts` 不 import `stop.ts`,反向持有安全 |
133
+ | **同 `session_id` 不同 `project_path` 切换**(同一 session key 不同 project)| 理论上 session_id 全局唯一,不会出现此情况 | 无需处理 |
134
+ | **官方 skill 版本管理** | 拆成独立文件后版本号散落各 `.md` frontmatter,不易整体更新 | 可在 `OFFICIAL_SKILL_KEYWORDS` 常量旁维护一个 `OFFICIAL_SKILL_VERSIONS` 对象供版本检查(可选,Phase 2 再做)|
135
+ | **测试中 skill 数量硬编码** | 修复点 1 后 skill 数量变为 19,现有断言 `>= 16` 可能需要调整 | 改动时同步更新 `tests/unit/skill-registry.test.ts` 断言 |
136
+
137
+ ---
138
+
139
+ ## 六、测试策略
140
+
141
+ ### 修复点 1
142
+
143
+ | 测试文件 | 测试内容 |
144
+ |----------|---------|
145
+ | `tests/unit/skill-registry.test.ts` | 修改:`skills.length >= 19`;新增:`official-tdd` 等具体 skill 可被加载;`path !== '<built-in>'`(改为真实文件路径) |
146
+ | 新建 `tests/unit/skills/official-skills-loader.test.ts` | 验证 `loadOfficialSkills(tempDir)` 从指定目录读取所有 `.md`;验证 frontmatter 解析正确(name、version、description、keywords);验证目录不存在时抛出有意义的错误 |
147
+ | `tests/unit/skills/registry-multiformat.test.ts` | 现有测试保持不变(测试 gray-matter 解析逻辑,与文件位置无关)|
148
+
149
+ ### 修复点 2
150
+
151
+ | 测试文件 | 测试内容 |
152
+ |----------|---------|
153
+ | `tests/unit/handlers.test.ts` | 新增:同一 session 第二次调用 `handle()` 不重复注入 resume/convention;新增:`clearSession()` 后再次调用会重新注入;新增:超过 1000 个不同 sessionKey 后不崩溃(LRU 上限生效) |
154
+ | `tests/unit/invocation-guard.test.ts` | 参考现有结构确认模式一致性,无需改动 |
155
+
156
+ ---
157
+
158
+ ## 七、执行步骤(自底向上)
159
+
160
+ ```
161
+ 修复点 1:官方 Skills 数据分离
162
+ ──────────────────────────────
163
+ Step 1 从 official-skills.ts 提取每个 skill 的 content 字段,
164
+ 在 src/skills/official/ 下创建对应 .md 文件(19 个)
165
+ 文件名 = skill.name + '.md'(如 official-tdd.md)
166
+ 内容 = content 字段原文(已含 frontmatter)
167
+
168
+ Step 2 在 src/skills/official-skills.ts 中:
169
+ - 删除 OFFICIAL_SKILLS 数组(整个 export const OFFICIAL_SKILLS)
170
+ - 保留 OfficialSkill interface
171
+ - 保留 OFFICIAL_SKILL_KEYWORDS 常量
172
+ - 新增 loadOfficialSkills(builtinDir: string): OfficialSkill[] 函数
173
+ (用 fs.readdirSync + gray-matter 解析,与 registry 现有 user skill 逻辑对齐)
174
+
175
+ Step 3 修改 src/skills/registry.ts:
176
+ - 新增私有方法 resolveBuiltinDir(): string
177
+ 使用 new URL('./official', import.meta.url).pathname
178
+ - scan() 第 1 段改为调用 loadOfficialSkills(this.resolveBuiltinDir())
179
+ - 其余逻辑不变
180
+
181
+ Step 4 修改 package.json build 脚本:
182
+ 末尾追加 && mkdir -p dist/skills/official && cp src/skills/official/*.md dist/skills/official/
183
+
184
+ Step 5 修改 tests/unit/skill-registry.test.ts 断言数量
185
+
186
+ Step 6 新建 tests/unit/skills/official-skills-loader.test.ts
187
+
188
+ Step 7 运行测试验证:
189
+ npx vitest run tests/unit/skill-registry.test.ts --reporter=verbose
190
+ npx vitest run tests/unit/skills/ --reporter=verbose
191
+ npx tsc --noEmit
192
+
193
+ 修复点 2:UserPromptHandler Set 内存泄漏
194
+ ─────────────────────────────────────────
195
+ Step 8 修改 src/daemon/handlers/user-prompt.ts:
196
+ - 将 resumeInjected: Set<string> 改为 Map<string, number>
197
+ - 将 conventionInjected: Set<string> 改为 Map<string, number>
198
+ - 新增常量 MAX_INJECTION_KEYS = 1000
199
+ - 封装私有方法 hasInjected(map, key): boolean
200
+ - 封装私有方法 markInjected(map, key): void
201
+ (在 map.size >= MAX_INJECTION_KEYS 时删除最旧的一条)
202
+ - 新增 public clearSession(sessionKey: string): void
203
+ (同时从两个 Map 删除该 key)
204
+
205
+ Step 9 修改 src/daemon/handlers/stop.ts:
206
+ - 构造函数新增可选参数 userPromptHandler?: UserPromptHandler
207
+ - Step 4 的 InvocationGuard.clear() 之后,调用
208
+ userPromptHandler?.clearSession(`${event.session_id}:${event.project_path}`)
209
+
210
+ Step 10 修改 daemon 初始化处(src/daemon/index.ts 或类似文件),
211
+ 在构造 StopHandler 时传入 userPromptHandler 实例
212
+
213
+ Step 11 修改 tests/unit/handlers.test.ts,新增 3 个 case(见测试策略)
214
+
215
+ Step 12 运行测试验证:
216
+ npx vitest run tests/unit/handlers.test.ts --reporter=verbose
217
+ npx tsc --noEmit
218
+ npm test -- --reporter=dot
219
+ ```
@@ -0,0 +1,204 @@
1
+ # Hook 失败缓冲队列 + Daemon 启动重放 — Spec
2
+
3
+ **日期**: 2026-05-16
4
+ **状态**: Draft(待用户 review)
5
+
6
+ ---
7
+
8
+ ## 一、目标 + 成功标准
9
+
10
+ **核心目标**:实现「至少一次」事件交付,消除 daemon 重启窗口期的静默丢失。
11
+
12
+ | 成功标准 | 验收方式 |
13
+ |---|---|
14
+ | daemon 停机 30 秒内,5 条 UserPromptSubmit 全部最终入库 | 集成测试:停 daemon → 发 5 事件 → 启动 daemon → 查 DB |
15
+ | 队列目录不超过 500 个文件 / 7 天 | 单元测试:写 600 个文件后调 prune,剩余 ≤500 |
16
+ | hook 总执行时间不超过 1 秒 | 脚本计时测试(`time` 命令) |
17
+ | 重放不产生重复入库 | 集成测试:手动写重复 event_id → 验证 DB 只有一条 |
18
+
19
+ **非目标**:已丢失的历史事件(本次故障之前)、跨机器同步、daemon 运行期间的网络抖动(nc 有超时保护,不属于失败场景)。
20
+
21
+ ---
22
+
23
+ ## 二、设计决策
24
+
25
+ ### 决策 1:队列存储格式 — per-event 独立文件
26
+
27
+ **选择**:`~/.claude-forge/queue/<timestamp>-<uuid>.json` 每个事件一个文件。
28
+
29
+ **理由**:
30
+ 1. 完全避免并发写冲突:5 个 hook bash 进程写不同文件名,无锁需求
31
+ 2. 原子性:`bash` 的 `echo > file` 对新建文件是原子操作(内核 create + write)
32
+ 3. 删除操作幂等:`rm -f file` 不会影响其他事件;追加模式下误删一行会破坏整个 jsonl
33
+
34
+ **否决方案**:append-only jsonl —— bash 并发 `>>` 在 chunk > PIPE_BUF(512B) 时会产生交错写,且部分行损坏会影响整个文件解析。
35
+
36
+ ### 决策 2:队列目录位置 — `~/.claude-forge/queue/`
37
+
38
+ **理由**:
39
+ 1. 与 `daemon.sock`、`data.db`、`daemon.token` 同目录,路径计算逻辑统一
40
+ 2. `expandPath` 工具已有 `~/.claude-forge/` 展开支持
41
+ 3. daemon 启动时已有 `mkdirSync` 保证父目录存在,子目录只需 `mkdir -p queue`
42
+
43
+ ### 决策 3:触发投递条件 — daemon 启动时一次性扫描
44
+
45
+ **理由**:
46
+ 1. 失败窗口期(daemon 重启)是短暂的,启动一次扫描即可覆盖
47
+ 2. 不需要额外的 watcher 进程/定时器,降低复杂度
48
+ 3. 重放完成后队列目录为空,无持续扫描开销
49
+
50
+ ### 决策 4:去重策略 — `event_id` 数据库唯一索引(已存在)+ catch ignore
51
+
52
+ **理由**:
53
+ 1. `events.event_id TEXT PRIMARY KEY` 已存在,无需额外工作
54
+ 2. daemon 侧只需在 `writeEvent` 的 catch 中识别 `UNIQUE constraint failed` 并静默跳过,其他错误仍 re-throw
55
+ 3. 避免内存 LRU 在 daemon 重启时丢失已处理记录的风险
56
+
57
+ ### 决策 5:容量保护 — 500 文件上限 + 7 天 TTL,过期写入 dead-letter
58
+
59
+ - 写入前检查:队列文件数 ≥ 500,**丢弃最旧的超额文件**
60
+ - TTL:daemon 启动重放时,跳过 > 7 天的文件,移入 `~/.claude-forge/queue/dead/`
61
+ - dead-letter 目录不自动清理,供人工审查
62
+
63
+ ### 决策 6:hook 脚本写队列方式 — fork 子进程同步写
64
+
65
+ **方式**:在 `nc` 失败后,用 `( ... ) &` 后台子进程写文件,主进程立即 `exit 0`。
66
+
67
+ **理由**:
68
+ 1. 主进程不阻塞,子进程独立 fork 不受父退出影响
69
+ 2. bash 原生支持,比 nohup/setsid 简单
70
+ 3. 单文件写入 syscall < 5ms,子进程开销可忽略
71
+
72
+ ---
73
+
74
+ ## 三、改动文件清单
75
+
76
+ | 路径 | 改动类型 | 概述 |
77
+ |---|---|---|
78
+ | `src/hooks/user-prompt-submit.sh` | 修改 | nc 失败后 fork 子进程写队列文件 |
79
+ | `src/hooks/pre-tool-use.sh` | 修改 | 同上,补充 socket 存在检测 |
80
+ | `src/hooks/post-tool-use.sh` | 修改 | 同上 |
81
+ | `src/hooks/notification.sh` | 修改 | 同上(低优先级,可选) |
82
+ | `src/hooks/stop.sh` | **不改** | Stop 事件无重放意义 |
83
+ | `src/core/queue/index.ts` | 新建 | 队列读写、prune、重放逻辑 |
84
+ | `src/daemon/index.ts` | 修改 | Step 8 之后插入 `replayQueue()` 调用 |
85
+ | `src/core/storage/events.ts` | 修改 | `writeEvent` catch 中识别并忽略 UNIQUE 冲突 |
86
+ | `src/tests/queue.test.ts` | 新建 | 单元测试 |
87
+ | `tests/integration/queue-replay.integration.test.ts` | 新建 | 集成测试 |
88
+
89
+ ---
90
+
91
+ ## 四、模块设计
92
+
93
+ ### `src/core/queue/index.ts` 接口
94
+
95
+ ```
96
+ QUEUE_DIR = ~/.claude-forge/queue/
97
+ DEAD_DIR = ~/.claude-forge/queue/dead/
98
+ MAX_FILES = 500
99
+ TTL_DAYS = 7
100
+
101
+ enqueueEvent(event: ForgeEvent): void
102
+ - 文件名:<iso-timestamp>-<event_id>.json
103
+ - 写入前 prune:目录文件数 >= MAX_FILES 删最旧
104
+
105
+ replayQueue(storage: SQLiteStorage): Promise<{ replayed, skipped, dead }>
106
+ - 读 QUEUE_DIR 下所有 *.json
107
+ - TTL > 7 天 → 移入 DEAD_DIR
108
+ - JSON.parse → storage.writeEvent
109
+ - UNIQUE constraint → skipped++(去重)
110
+ - 成功入库 → rm 文件 → replayed++
111
+ - JSON 损坏 → 移入 DEAD_DIR → dead++
112
+
113
+ pruneQueue(): void // 内部使用
114
+ ```
115
+
116
+ ### `src/daemon/index.ts` 改动
117
+
118
+ 在 socket `listen` 回调内(`logger.info('Socket 服务器已监听')` 之后)追加:
119
+
120
+ ```
121
+ replayQueue(storage).then(({ replayed, skipped, dead }) => {
122
+ logger.info(`[Queue] Replay: ${replayed} replayed, ${skipped} skipped (dup), ${dead} dead-lettered`);
123
+ });
124
+ ```
125
+
126
+ ### Hook 脚本改动模式
127
+
128
+ ```bash
129
+ # 当前:
130
+ RESPONSE=$(echo "$EVENT" | nc -U -w 10 "$SOCKET_PATH" 2>/dev/null)
131
+
132
+ # 新增:nc 失败或 RESPONSE 为空时 fork 写队列
133
+ if [ -z "$RESPONSE" ]; then
134
+ (
135
+ QUEUE_DIR="$HOME/.claude-forge/queue"
136
+ mkdir -p "$QUEUE_DIR"
137
+ TS=$(date -u +"%Y%m%dT%H%M%S")
138
+ UUID=$(uuidgen 2>/dev/null || cat /proc/sys/kernel/random/uuid 2>/dev/null || echo "$$-$RANDOM")
139
+ echo "$EVENT" > "$QUEUE_DIR/${TS}-${UUID}.json"
140
+ ) &
141
+ fi
142
+ ```
143
+
144
+ 注意:macOS BSD `date` 不支持 `%N` 毫秒,所以 timestamp 用秒精度 + UUID 兜底唯一性。
145
+
146
+ ---
147
+
148
+ ## 五、风险点
149
+
150
+ | 风险 | 概率 | 缓解方案 |
151
+ |---|---|---|
152
+ | 5 hook 同时写同名文件 | 低 | 文件名含 UUID(uuidgen),冲突 < 1/10^12 |
153
+ | JSON 文件写一半被截断 | 低 | replayQueue catch JSON.parse → dead-letter |
154
+ | daemon 重放时 socket 刚启动又挂掉 | 极低 | 每文件独立 try/catch,单失败不中断 |
155
+ | queue 文件含旧 `_auth` token | 必然发生 | 重放走 `storage.writeEvent`,不经 socket 认证,Zod schema strip 自动剥离 |
156
+ | 历史已丢失数据 | 已发生 | 本次范围外;可手动从 `~/.claude/projects/*/*.jsonl` 回填 |
157
+
158
+ ---
159
+
160
+ ## 六、测试策略
161
+
162
+ ### 单元测试 `src/tests/queue.test.ts`
163
+
164
+ | 用例 | 验证点 |
165
+ |---|---|
166
+ | enqueueEvent 写入 | 文件存在,内容可 JSON.parse |
167
+ | 超过 500 文件 prune 删最旧 | 写 510 个 → 文件数 = 500 |
168
+ | replayQueue 成功 → 文件删除 | mock writeEvent 成功 → 文件消失 |
169
+ | UNIQUE 冲突 → 文件删 + skipped++ | mock 抛 UNIQUE → skipped=1 |
170
+ | JSON 损坏 → 移入 dead | 非法 JSON → dead 目录有 |
171
+ | TTL 超期 → 移入 dead | mtime 8 天前 → dead 目录有 |
172
+
173
+ ### 集成测试 `tests/integration/queue-replay.integration.test.ts`
174
+
175
+ 1. 启动 daemon → 停止 daemon
176
+ 2. `enqueueEvent` 写入 3 个 ForgeEvent
177
+ 3. 重启 daemon
178
+ 4. 查 DB:3 条事件在 events 表
179
+ 5. 验证 queue/ 为空
180
+ 6. 第二次重启验证去重(skipped=3)
181
+
182
+ ### E2E 验证
183
+
184
+ ```bash
185
+ ./scripts/dev-daemon.sh restart &
186
+ echo '{"session_id":"test","cwd":"/tmp"}' | bash src/hooks/user-prompt-submit.sh
187
+ sqlite3 ~/.claude-forge/data.db "SELECT count(*) FROM events WHERE session_id='test';"
188
+ # 期望:1
189
+ ```
190
+
191
+ ---
192
+
193
+ ## 七、执行步骤(自底向上)
194
+
195
+ | # | 步骤 | 文件 |
196
+ |---|---|---|
197
+ | 1 | 实现队列模块(enqueueEvent + replayQueue + pruneQueue) | `src/core/queue/index.ts` |
198
+ | 2 | 单元测试 queue.test.ts 全过 | `src/tests/queue.test.ts` |
199
+ | 3 | `events.ts writeEvent` catch UNIQUE constraint 静默忽略 | `src/core/storage/events.ts` |
200
+ | 4 | daemon/index.ts 调用 replayQueue(socket ready 后) | `src/daemon/index.ts` |
201
+ | 5 | 修改 3 个 hook(user-prompt-submit、pre-tool-use、post-tool-use) | `src/hooks/*.sh` |
202
+ | 6 | 集成测试通过 | `tests/integration/queue-replay.integration.test.ts` |
203
+ | 7 | E2E:dev-daemon.sh restart 期间发事件验证 | 手工 + changelog |
204
+ | 8 | 部署:cp hook 到 ~/.claude-forge/hooks/ + 重启 daemon | 手工 |