@winspan/claude-forge 8.53.2 → 8.54.3

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 (390) hide show
  1. package/DEVELOPMENT.md +290 -221
  2. package/README.md +50 -8
  3. package/dist/cli/commands/skills.d.ts.map +1 -1
  4. package/dist/cli/commands/skills.js +7 -3
  5. package/dist/cli/commands/skills.js.map +1 -1
  6. package/dist/cli/init/hook-manager.d.ts +1 -1
  7. package/dist/cli/init/hook-manager.d.ts.map +1 -1
  8. package/dist/cli/init/hook-manager.js +1 -0
  9. package/dist/cli/init/hook-manager.js.map +1 -1
  10. package/dist/core/storage/events.d.ts.map +1 -1
  11. package/dist/core/storage/events.js +0 -1
  12. package/dist/core/storage/events.js.map +1 -1
  13. package/dist/core/storage/maintenance.d.ts +25 -3
  14. package/dist/core/storage/maintenance.d.ts.map +1 -1
  15. package/dist/core/storage/maintenance.js +33 -4
  16. package/dist/core/storage/maintenance.js.map +1 -1
  17. package/dist/core/storage/routing.d.ts +4 -0
  18. package/dist/core/storage/routing.d.ts.map +1 -1
  19. package/dist/core/storage/routing.js +10 -4
  20. package/dist/core/storage/routing.js.map +1 -1
  21. package/dist/core/storage/sessions.d.ts +17 -0
  22. package/dist/core/storage/sessions.d.ts.map +1 -1
  23. package/dist/core/storage/sessions.js +64 -0
  24. package/dist/core/storage/sessions.js.map +1 -1
  25. package/dist/core/storage/skills.d.ts +4 -0
  26. package/dist/core/storage/skills.d.ts.map +1 -1
  27. package/dist/core/storage/skills.js +10 -2
  28. package/dist/core/storage/skills.js.map +1 -1
  29. package/dist/core/storage/sqlite.d.ts +5 -0
  30. package/dist/core/storage/sqlite.d.ts.map +1 -1
  31. package/dist/core/storage/sqlite.js +6 -0
  32. package/dist/core/storage/sqlite.js.map +1 -1
  33. package/dist/core/storage/tasks.d.ts.map +1 -1
  34. package/dist/core/storage/tasks.js +2 -0
  35. package/dist/core/storage/tasks.js.map +1 -1
  36. package/dist/core/types.d.ts +7 -0
  37. package/dist/core/types.d.ts.map +1 -1
  38. package/dist/daemon/index.d.ts.map +1 -1
  39. package/dist/daemon/index.js +19 -4
  40. package/dist/daemon/index.js.map +1 -1
  41. package/dist/skills/registry.d.ts.map +1 -1
  42. package/dist/skills/registry.js +13 -2
  43. package/dist/skills/registry.js.map +1 -1
  44. package/dist/skills/semantic-matcher.d.ts +2 -2
  45. package/dist/skills/semantic-matcher.d.ts.map +1 -1
  46. package/dist/skills/semantic-matcher.js +14 -19
  47. package/dist/skills/semantic-matcher.js.map +1 -1
  48. package/dist/skills/upgrade-engine.d.ts +3 -1
  49. package/dist/skills/upgrade-engine.d.ts.map +1 -1
  50. package/dist/skills/upgrade-engine.js +25 -14
  51. package/dist/skills/upgrade-engine.js.map +1 -1
  52. package/dist/web/analytics/weekly-report.d.ts.map +1 -1
  53. package/dist/web/analytics/weekly-report.js +21 -29
  54. package/dist/web/analytics/weekly-report.js.map +1 -1
  55. package/dist/web/routes/patch.d.ts.map +1 -1
  56. package/dist/web/routes/patch.js +32 -2
  57. package/dist/web/routes/patch.js.map +1 -1
  58. package/dist/web/routes/sessions.d.ts.map +1 -1
  59. package/dist/web/routes/sessions.js +9 -7
  60. package/dist/web/routes/sessions.js.map +1 -1
  61. package/dist/web/routes/trace.d.ts.map +1 -1
  62. package/dist/web/routes/trace.js +2 -3
  63. package/dist/web/routes/trace.js.map +1 -1
  64. package/dist/web/server.d.ts.map +1 -1
  65. package/dist/web/server.js +3 -2
  66. package/dist/web/server.js.map +1 -1
  67. package/package.json +12 -2
  68. package/scripts/postinstall.cjs +21 -0
  69. package/.claude/CLAUDE.md +0 -17
  70. package/.eslintrc.js +0 -23
  71. package/.prettierrc +0 -8
  72. package/ARCHITECTURE_ISSUES.md +0 -249
  73. package/CLAUDE.md +0 -265
  74. package/CLAUDE.md.backup +0 -488
  75. package/docs/concurrent-agents.md +0 -129
  76. package/docs/design/architecture-review-20260516.md +0 -232
  77. package/docs/design/fix-skills-data-and-set-leak-spec-20260516-1300.md +0 -219
  78. package/docs/design/h1-storage-aggregation-spec-20260518-1121.md +0 -299
  79. package/docs/design/h2-getdatabase-encapsulation-spec-20260518-1450.md +0 -191
  80. package/docs/design/h3-fallback-removal-spec-20260518-1245.md +0 -76
  81. package/docs/design/h4-index-dedup-spec-20260518-1230.md +0 -109
  82. package/docs/design/h6-services-migration-spec-20260518-1355.md +0 -82
  83. package/docs/design/hook-failure-queue-spec-20260516-1530.md +0 -204
  84. package/docs/design/l1-swarm-protocol-extract-spec-20260518-1605.md +0 -106
  85. package/docs/design/m10-forge-paths-spec-20260518-1320.md +0 -121
  86. package/docs/design/m2-m3-tool-input-spec-20260518-1425.md +0 -131
  87. package/docs/design/m7-routing-event-association-spec-20260518-1545.md +0 -103
  88. package/docs/design/project-path-gitroot-spec-20260518-1715.md +0 -134
  89. package/docs/design/refactor-phase1-spec-20260515-1600.md +0 -543
  90. package/docs/design/refactor-phase2-spec-20260515-1700.md +0 -424
  91. package/docs/design/skill-ai-upgrade-spec-20260518-1930.md +0 -297
  92. package/docs/design/task-active-gc-spec-20260518-1745.md +0 -146
  93. package/docs/design/tasks-list-filter-pagination-spec-20260518-0930.md +0 -208
  94. package/docs/implementation/daemon-skill-sync-changelog-20260518-2000.md +0 -22
  95. package/docs/implementation/fix-skills-data-and-set-leak-changelog-20260516-1300.md +0 -104
  96. package/docs/implementation/h1-storage-aggregation-changelog-20260518-1121.md +0 -82
  97. package/docs/implementation/h2-final-changelog-20260518-1530.md +0 -61
  98. package/docs/implementation/h2-phase1-safety-net-changelog-20260518-1450.md +0 -70
  99. package/docs/implementation/h2-phase2-operations-changelog-20260518-1450.md +0 -120
  100. package/docs/implementation/h2-phase3-callsites-changelog-20260518-1450.md +0 -71
  101. package/docs/implementation/h3-fallback-removal-changelog-20260518-1245.md +0 -71
  102. package/docs/implementation/h4-index-dedup-changelog-20260518-1230.md +0 -60
  103. package/docs/implementation/h6-services-migration-changelog-20260518-1355.md +0 -46
  104. package/docs/implementation/h7-m9-defaults-changelog-20260518-1300.md +0 -46
  105. package/docs/implementation/hook-failure-queue-changelog-20260516-1530.md +0 -196
  106. package/docs/implementation/hotfix-daemon-event-reject-20260516-1430.md +0 -56
  107. package/docs/implementation/l1-swarm-protocol-extract-changelog-20260518-1605.md +0 -45
  108. package/docs/implementation/l3-l4-daemon-perf-changelog-20260518-1410.md +0 -63
  109. package/docs/implementation/l6-l8-final-cleanup-changelog-20260518-1640.md +0 -38
  110. package/docs/implementation/m1-m4-m5-l7-cleanup-changelog-20260518-1310.md +0 -58
  111. package/docs/implementation/m10-forge-paths-changelog-20260518-1320.md +0 -60
  112. package/docs/implementation/m2-m3-tool-input-changelog-20260518-1425.md +0 -43
  113. package/docs/implementation/m6-m8-naming-shutdown-changelog-20260518-1340.md +0 -56
  114. package/docs/implementation/m7-routing-association-changelog-20260518-1545.md +0 -69
  115. package/docs/implementation/project-path-gitroot-changelog-20260518-1715.md +0 -63
  116. package/docs/implementation/refactor-phase1-changelog-20260515-1630.md +0 -354
  117. package/docs/implementation/refactor-phase2-changelog-20260515-1705.md +0 -421
  118. package/docs/implementation/skill-ai-upgrade-changelog-20260518-1930.md +0 -49
  119. package/docs/implementation/task-active-gc-changelog-20260518-1745.md +0 -35
  120. package/docs/implementation/task-title-summary-changelog-20260518-1130.md +0 -39
  121. package/docs/implementation/tasks-detail-back-loses-filters-changelog-20260518-1100.md +0 -22
  122. package/docs/implementation/tasks-list-filter-pagination-changelog-20260518-0930.md +0 -72
  123. package/docs/implementation/tasks-page-white-screen-hotfix-changelog-20260518-1015.md +0 -56
  124. package/docs/reviews/claudemd-template-sync.md +0 -54
  125. package/docs/reviews/task-title-summary.md +0 -92
  126. package/docs/reviews/tasks-detail-back-loses-filters.md +0 -58
  127. package/docs/reviews/tasks-filter-pagination.md +0 -80
  128. package/docs/reviews/tasks-page-white-screen-hotfix.md +0 -126
  129. package/docs/ruflo-learning-strategy.md +0 -322
  130. package/docs/skills-deduplication-analysis.md +0 -83
  131. package/docs/skills-multiformat-support.md +0 -177
  132. package/docs/skills-third-party.md +0 -183
  133. package/docs/testing/tasks-filter-pagination-test-report.md +0 -86
  134. package/forge +0 -321
  135. package/playwright.config.ts +0 -40
  136. package/scripts/demo-v2.ts +0 -91
  137. package/scripts/dev-daemon.sh +0 -232
  138. package/scripts/dev-web.ts +0 -109
  139. package/scripts/e2e-mcp-link.ts +0 -423
  140. package/scripts/e2e-methodology-quality.ts +0 -253
  141. package/scripts/e2e-routing.ts +0 -456
  142. package/scripts/e2e-user-methodology.ts +0 -326
  143. package/scripts/e2e-web-workflows.ts +0 -299
  144. package/scripts/migrate-legacy-to-dynamic.sql +0 -108
  145. package/scripts/regenerate-execution-docs.ts +0 -116
  146. package/scripts/sync-agent-skills.ts +0 -193
  147. package/scripts/test-hook.sh +0 -71
  148. package/scripts/verify-skill-loading.ts +0 -62
  149. package/src/claudemd/claudemd-generator.ts +0 -568
  150. package/src/claudemd/convention-extractor.ts +0 -69
  151. package/src/claudemd/index.ts +0 -35
  152. package/src/claudemd/persona-manager.ts +0 -88
  153. package/src/claudemd/resume-manager.ts +0 -236
  154. package/src/claudemd/tech-detector.ts +0 -220
  155. package/src/claudemd/templates/swarm-protocol.md +0 -222
  156. package/src/cli/commands/claudemd.ts +0 -84
  157. package/src/cli/commands/config.ts +0 -46
  158. package/src/cli/commands/daemon.ts +0 -310
  159. package/src/cli/commands/executions.ts +0 -115
  160. package/src/cli/commands/init.ts +0 -204
  161. package/src/cli/commands/logs.ts +0 -181
  162. package/src/cli/commands/mcp.ts +0 -242
  163. package/src/cli/commands/menu.ts +0 -357
  164. package/src/cli/commands/skills.ts +0 -328
  165. package/src/cli/commands/stats.ts +0 -73
  166. package/src/cli/commands/status.ts +0 -69
  167. package/src/cli/commands/template.ts +0 -77
  168. package/src/cli/commands/trace.ts +0 -148
  169. package/src/cli/index.ts +0 -42
  170. package/src/cli/init/hook-manager.ts +0 -132
  171. package/src/core/ai/provider.ts +0 -308
  172. package/src/core/ai/types.ts +0 -51
  173. package/src/core/config.ts +0 -124
  174. package/src/core/constants.ts +0 -67
  175. package/src/core/event-fields.ts +0 -32
  176. package/src/core/queue/index.ts +0 -192
  177. package/src/core/storage/base.ts +0 -302
  178. package/src/core/storage/events.ts +0 -434
  179. package/src/core/storage/injections.ts +0 -78
  180. package/src/core/storage/maintenance.ts +0 -59
  181. package/src/core/storage/migrations/002_add_skill_tracking.sql +0 -6
  182. package/src/core/storage/migrations/003_add_skill_invocations.sql +0 -23
  183. package/src/core/storage/performance-indexes.sql +0 -23
  184. package/src/core/storage/routing.ts +0 -322
  185. package/src/core/storage/rows.ts +0 -112
  186. package/src/core/storage/schema.sql +0 -224
  187. package/src/core/storage/sessions.ts +0 -168
  188. package/src/core/storage/skills.ts +0 -233
  189. package/src/core/storage/sqlite.ts +0 -293
  190. package/src/core/storage/tasks.ts +0 -318
  191. package/src/core/storage/token-usage.ts +0 -93
  192. package/src/core/types.ts +0 -181
  193. package/src/core/utils/error-handler.ts +0 -257
  194. package/src/core/utils/forge-resume-block.ts +0 -74
  195. package/src/core/utils/format.ts +0 -69
  196. package/src/core/utils/git.ts +0 -23
  197. package/src/core/utils/logger.ts +0 -134
  198. package/src/core/utils/lru-cache.ts +0 -54
  199. package/src/core/utils/path.ts +0 -19
  200. package/src/core/utils/session.ts +0 -26
  201. package/src/core/utils/time.ts +0 -37
  202. package/src/core/utils/token-tracker.ts +0 -97
  203. package/src/daemon/event-parser.ts +0 -36
  204. package/src/daemon/handlers/history-exporter.ts +0 -117
  205. package/src/daemon/handlers/post-tool-use.ts +0 -54
  206. package/src/daemon/handlers/stop.ts +0 -208
  207. package/src/daemon/handlers/user-prompt.ts +0 -178
  208. package/src/daemon/hook-sync.ts +0 -91
  209. package/src/daemon/index.ts +0 -312
  210. package/src/daemon/launchd/com.claude-forge.daemon.plist.template +0 -47
  211. package/src/daemon/launchd-installer.ts +0 -260
  212. package/src/daemon/lifecycle.ts +0 -128
  213. package/src/daemon/router.ts +0 -40
  214. package/src/daemon/server.ts +0 -196
  215. package/src/daemon/services/task-segmenter.ts +0 -112
  216. package/src/daemon/skill-sync.ts +0 -88
  217. package/src/hooks/hook-lib.sh +0 -118
  218. package/src/hooks/notification.sh +0 -35
  219. package/src/hooks/post-tool-use.sh +0 -61
  220. package/src/hooks/pre-tool-use.sh +0 -63
  221. package/src/hooks/stop.sh +0 -43
  222. package/src/hooks/user-prompt-submit.sh +0 -69
  223. package/src/mcp/server.ts +0 -322
  224. package/src/skills/index.ts +0 -2
  225. package/src/skills/invocation-guard.ts +0 -177
  226. package/src/skills/matcher.ts +0 -148
  227. package/src/skills/official/code-simplifier.md +0 -52
  228. package/src/skills/official/find-skills.md +0 -142
  229. package/src/skills/official/official-api-design.md +0 -30
  230. package/src/skills/official/official-architecture-decision.md +0 -41
  231. package/src/skills/official/official-bmad.md +0 -118
  232. package/src/skills/official/official-db-schema-design.md +0 -34
  233. package/src/skills/official/official-debug.md +0 -25
  234. package/src/skills/official/official-doc-driven.md +0 -31
  235. package/src/skills/official/official-harness-engineering.md +0 -108
  236. package/src/skills/official/official-performance-optimization.md +0 -30
  237. package/src/skills/official/official-pr-review.md +0 -35
  238. package/src/skills/official/official-release-checklist.md +0 -30
  239. package/src/skills/official/official-security-hardening.md +0 -32
  240. package/src/skills/official/official-spec-driven-design.md +0 -31
  241. package/src/skills/official/planning-with-files.md +0 -241
  242. package/src/skills/official/ui-ux-pro-max.md +0 -105
  243. package/src/skills/official/webapp-testing.md +0 -96
  244. package/src/skills/official-skills.ts +0 -89
  245. package/src/skills/registry.ts +0 -355
  246. package/src/skills/semantic-matcher.ts +0 -234
  247. package/src/skills/tools/pipeline-suggest.ts +0 -226
  248. package/src/skills/tools/skill-invoke.ts +0 -168
  249. package/src/skills/tools/skill-list.ts +0 -59
  250. package/src/skills/upgrade-engine.ts +0 -541
  251. package/src/skills/upgrade-prompt.ts +0 -84
  252. package/src/templates/go.yaml +0 -53
  253. package/src/templates/python.yaml +0 -59
  254. package/src/templates/react.yaml +0 -55
  255. package/src/templates/template-manager.ts +0 -170
  256. package/src/web/analytics/anti-pattern-detector.ts +0 -367
  257. package/src/web/analytics/drift-detector.ts +0 -219
  258. package/src/web/analytics/weekly-report.ts +0 -431
  259. package/src/web/auth-middleware.ts +0 -54
  260. package/src/web/routes/_helpers.ts +0 -34
  261. package/src/web/routes/ai.ts +0 -204
  262. package/src/web/routes/auth.ts +0 -22
  263. package/src/web/routes/drift.ts +0 -25
  264. package/src/web/routes/error-handler.ts +0 -120
  265. package/src/web/routes/events.ts +0 -47
  266. package/src/web/routes/insights.ts +0 -43
  267. package/src/web/routes/patch.ts +0 -117
  268. package/src/web/routes/reports.ts +0 -34
  269. package/src/web/routes/rules.ts +0 -76
  270. package/src/web/routes/sessions.ts +0 -250
  271. package/src/web/routes/skill-stats.ts +0 -92
  272. package/src/web/routes/skills.ts +0 -350
  273. package/src/web/routes/static.ts +0 -67
  274. package/src/web/routes/stats.ts +0 -50
  275. package/src/web/routes/status.ts +0 -30
  276. package/src/web/routes/tasks.ts +0 -193
  277. package/src/web/routes/token-usage.ts +0 -20
  278. package/src/web/routes/trace.ts +0 -126
  279. package/src/web/routes/types.ts +0 -57
  280. package/src/web/server.ts +0 -134
  281. package/src/web/ssrf-guard.ts +0 -112
  282. package/src/web/static/index.html +0 -3251
  283. package/src/web/static/vendor/chart.umd.min.js +0 -20
  284. package/tests/e2e/dashboard.spec.ts +0 -205
  285. package/tests/e2e/routing-skill-e2e.test.ts +0 -39
  286. package/tests/helpers/mock-ai.ts +0 -92
  287. package/tests/helpers/mock-storage.ts +0 -159
  288. package/tests/integration/claudemd-generator.test.ts +0 -90
  289. package/tests/integration/queue-replay.integration.test.ts +0 -193
  290. package/tests/integration/tasks-filter.integration.test.ts +0 -154
  291. package/tests/integration/web-analytics.integration.test.ts +0 -133
  292. package/tests/integration/web-stats.integration.test.ts +0 -135
  293. package/tests/integration/web-trace.integration.test.ts +0 -175
  294. package/tests/performance/database.benchmark.ts +0 -161
  295. package/tests/semantic-matcher.test.ts +0 -99
  296. package/tests/skill-matcher.test.ts +0 -110
  297. package/tests/unit/ai-provider-retry.test.ts +0 -194
  298. package/tests/unit/ai-provider-vision.test.ts +0 -224
  299. package/tests/unit/claudemd-generator.test.ts +0 -68
  300. package/tests/unit/cli-mcp.test.ts +0 -141
  301. package/tests/unit/core/forge-paths.test.ts +0 -99
  302. package/tests/unit/daemon/hook-sync.test.ts +0 -71
  303. package/tests/unit/daemon/post-tool-use.test.ts +0 -121
  304. package/tests/unit/daemon/skill-sync.test.ts +0 -75
  305. package/tests/unit/daemon/stop-handler-behavior-summary.test.ts +0 -202
  306. package/tests/unit/daemon/task-segmenter-recover.test.ts +0 -84
  307. package/tests/unit/event-fields.test.ts +0 -88
  308. package/tests/unit/event-parser.test.ts +0 -55
  309. package/tests/unit/handlers.test.ts +0 -171
  310. package/tests/unit/hooks/resolve-project-path.test.ts +0 -122
  311. package/tests/unit/invocation-guard.test.ts +0 -125
  312. package/tests/unit/queue.test.ts +0 -272
  313. package/tests/unit/router.test.ts +0 -138
  314. package/tests/unit/security.test.ts +0 -128
  315. package/tests/unit/skill-invocations-workflow.test.ts +0 -495
  316. package/tests/unit/skill-registry.test.ts +0 -94
  317. package/tests/unit/skills/invocation-guard-ttl.test.ts +0 -211
  318. package/tests/unit/skills/official-skills-loader.test.ts +0 -126
  319. package/tests/unit/skills/registry-multiformat.test.ts +0 -92
  320. package/tests/unit/skills/upgrade-engine-parse.test.ts +0 -138
  321. package/tests/unit/skills/upgrade-engine.test.ts +0 -401
  322. package/tests/unit/skills/upgrade-prompt.test.ts +0 -89
  323. package/tests/unit/socket-server.test.ts +0 -183
  324. package/tests/unit/storage/event-operations-aggregates.test.ts +0 -342
  325. package/tests/unit/storage/migration-idempotent.test.ts +0 -304
  326. package/tests/unit/storage/routing-aggregates.test.ts +0 -276
  327. package/tests/unit/storage/routing.test.ts +0 -117
  328. package/tests/unit/storage/schema-missing.test.ts +0 -81
  329. package/tests/unit/storage/session-operations-aggregates.test.ts +0 -120
  330. package/tests/unit/storage/sessions-aggregate.test.ts +0 -435
  331. package/tests/unit/storage/skill-operations-counts.test.ts +0 -106
  332. package/tests/unit/storage/skills-aggregates.test.ts +0 -104
  333. package/tests/unit/storage/sqlite-refactor-harness.test.ts +0 -314
  334. package/tests/unit/storage/task-operations-counts.test.ts +0 -46
  335. package/tests/unit/storage/tasks-getById.test.ts +0 -343
  336. package/tests/unit/storage/tasks-stale-gc.test.ts +0 -86
  337. package/tests/unit/storage.test.ts +0 -172
  338. package/tests/unit/token-usage.test.ts +0 -144
  339. package/tests/unit/type-guards.test.ts +0 -201
  340. package/tests/unit/utils/format.test.ts +0 -189
  341. package/tests/unit/utils/session.test.ts +0 -89
  342. package/tests/unit/utils/time.test.ts +0 -112
  343. package/tests/unit/web/navigation-back-contract.test.ts +0 -134
  344. package/tests/unit/web/routes-auth.test.ts +0 -93
  345. package/tests/unit/web/routes-events.test.ts +0 -101
  346. package/tests/unit/web/routes-rules.test.ts +0 -182
  347. package/tests/unit/web/routes-sessions.test.ts +0 -181
  348. package/tests/unit/web/routes-skill-stats.test.ts +0 -179
  349. package/tests/unit/web/routes-stats.test.ts +0 -92
  350. package/tests/unit/web/routes-tasks.test.ts +0 -385
  351. package/tests/unit/web/task-title-contract.test.ts +0 -210
  352. package/tests/unit/web/tasks-component-contract.test.ts +0 -179
  353. package/tsconfig.json +0 -22
  354. package/vitest.config.ts +0 -21
  355. package/vitest.integration.config.ts +0 -16
  356. package/web/CLAUDE.md +0 -20
  357. package/web/index.html +0 -13
  358. package/web/package-lock.json +0 -4854
  359. package/web/package.json +0 -35
  360. package/web/postcss.config.js +0 -6
  361. package/web/src/App.tsx +0 -110
  362. package/web/src/components/CodeBlock.tsx +0 -31
  363. package/web/src/components/Confirm.tsx +0 -96
  364. package/web/src/components/Drawer.tsx +0 -60
  365. package/web/src/components/Layout.tsx +0 -145
  366. package/web/src/components/MarkdownRenderer.tsx +0 -77
  367. package/web/src/components/SearchInput.tsx +0 -31
  368. package/web/src/components/SessionDetailContent.tsx +0 -157
  369. package/web/src/components/Toast.tsx +0 -92
  370. package/web/src/index.css +0 -19
  371. package/web/src/main.tsx +0 -31
  372. package/web/src/pages/AIConfig.tsx +0 -233
  373. package/web/src/pages/Dashboard.tsx +0 -572
  374. package/web/src/pages/Events.tsx +0 -271
  375. package/web/src/pages/Reports.tsx +0 -428
  376. package/web/src/pages/SessionDetail.tsx +0 -162
  377. package/web/src/pages/Sessions.tsx +0 -205
  378. package/web/src/pages/Skills.tsx +0 -180
  379. package/web/src/pages/TaskDetail.tsx +0 -515
  380. package/web/src/pages/Tasks.tsx +0 -415
  381. package/web/src/utils/auth.ts +0 -59
  382. package/web/src/utils/export.ts +0 -54
  383. package/web/src/utils/navigation.ts +0 -25
  384. package/web/src/utils/task-title.ts +0 -49
  385. package/web/src/utils/time.ts +0 -13
  386. package/web/tailwind.config.js +0 -11
  387. package/web/tsconfig.json +0 -21
  388. package/web/tsconfig.node.json +0 -10
  389. package/web/vite.config.ts +0 -76
  390. package/winspan-claude-forge-8.43.0.tgz +0 -0
@@ -1,109 +0,0 @@
1
- # H4: DB 索引/列去重 Spec
2
-
3
- ## 目标
4
- 消除 `schema.sql` 与 `base.ts::runMigrations` 之间的索引/列重复定义,让 schema.sql 成为新库权威源,runMigrations 只承担"存量库补齐"的职责,并保持 idempotent。
5
-
6
- ## 涉及文件
7
- - `src/core/storage/schema.sql`(权威 schema,新库初始化)
8
- - `src/core/storage/base.ts`(migration 入口,存量库补齐)
9
-
10
- ## 重复清单
11
-
12
- | 名称 | schema.sql | base.ts | 类型 | 备注 |
13
- |------|------------|---------|------|------|
14
- | `first_prompt` | L55 | L99 | column | schema 已含,migration 仍 ALTER |
15
- | `skill_confidence` | L139 | L101 | column | 同上 |
16
- | `skill_source` | L140 | L102 | column | 同上 |
17
- | `workflow` | L178 | L104 | column | 同上 |
18
- | `phase` | L179 | L105 | column | 同上 |
19
- | `feature_slug` | L180 | L106 | column | 同上 |
20
- | `artifact_path` | L181 | L107 | column | 同上 |
21
- | `idx_sessions_start_time` | L66 | L119 | index | 双写 |
22
- | `idx_events_session_ts` | L198 | L127 | index | 双写 |
23
- | `idx_routing_events_session_ts` | L199 | L128 | index | 双写 |
24
- | `idx_skill_invocations_session_ts` | L200 | L129 | index | 双写 |
25
- | `idx_routing_events_obeyed_ts` | L205 | L138 | index | 双写 |
26
- | `idx_events_session_hook` | L211 | L139 | index | 双写 |
27
- | `idx_injections_session_handler` | L214 | L140 | index | 双写 |
28
- | `idx_routing_events_type_ts` | L217 | L141 | index | 双写(H1 新增)|
29
- | `idx_skill_invocations_workflow` | 缺 | L111 | index | **仅 migration**,应补到 schema |
30
- | `idx_skill_invocations_feature` | 缺 | L112 | index | 同上 |
31
-
32
- ## 设计方案
33
-
34
- ### 决策:方案 B(保留 idempotent 双写 + 显式 has 判断)
35
-
36
- **理由**:
37
- - 简单删 base.ts 的 `CREATE INDEX IF NOT EXISTS` 会导致存量库(旧版未跑过 H1 migration 的用户)永远缺索引;migration 必须保留补齐能力。
38
- - 不能依赖"新装用户走 schema.sql、老用户走 migration"——同一份 base.ts 两端都跑。
39
- - 索引层面 `CREATE INDEX IF NOT EXISTS` 本身已 idempotent,"双写"代价仅是一次 PRAGMA 查表,可接受。
40
- - 列层面 ALTER TABLE 无 IF NOT EXISTS,必须靠 `hasColumn`(已存在)守护。
41
-
42
- ### 选定方案的详细做法
43
-
44
- 1. **schema.sql** 补两条缺失的索引:
45
- - `idx_skill_invocations_workflow ON skill_invocations(workflow, phase)`
46
- - `idx_skill_invocations_feature ON skill_invocations(feature_slug)`
47
- 这样新库一次成型,migration 块只是"防御性补齐"。
48
-
49
- 2. **base.ts::runMigrations** 全部改造为 has 判断守护:
50
- - 列:维持 `addColumnIfMissing`(已有 hasColumn)。
51
- - 索引:新增 `hasIndex(name)` 工具;每个 migration 索引创建前先判断 `if (!this.hasIndex(name)) exec(...)`,跳过则记一行 debug 日志。
52
- - 目的不是性能(CREATE INDEX IF NOT EXISTS 已便宜),而是让"哪些索引由 migration 补齐"显式可读、便于日后裁剪。
53
-
54
- 3. **删除 inline fallback**(base.ts L57-72)—— 如果 schema.sql 缺失,应直接抛错而不是用残缺 schema 启动;保留只会埋坑。可在 spec 里建议但放在 H4 之外。**本次 H4 不动它**,仅注释 TODO。
55
-
56
- ### 新增工具函数(base.ts)
57
-
58
- ```ts
59
- protected hasIndex(name: string): boolean {
60
- try {
61
- const row = this.db
62
- .prepare(`SELECT name FROM sqlite_master WHERE type='index' AND name = ?`)
63
- .get(name);
64
- return !!row;
65
- } catch { return false; }
66
- }
67
- ```
68
-
69
- 注:`pragma_index_list(table)` 需要知道表名,而 `sqlite_master` 直接按索引名查更简单。
70
-
71
- ## 测试策略
72
-
73
- 新增 `tests/unit/storage/migration-idempotent.test.ts`:
74
-
75
- 1. **baseline(旧库补齐)**:
76
- - 建临时 db,先 exec 一份"H1 之前的旧 schema"(手写删掉 `idx_routing_events_type_ts` 等)+ 缺 `first_prompt` 列。
77
- - 用 `new SQLiteStorage(path)` 启动,断言所有重复清单中的索引/列都已存在(`sqlite_master` + `PRAGMA table_info`)。
78
-
79
- 2. **新库无害**:
80
- - 临时 db 走完整 `schema.sql` 初始化。
81
- - 再实例化一次 SQLiteStorage,断言 migration 不抛错、不重复创建(spy `db.exec` 调用次数或检查 logger.warn 无输出)。
82
-
83
- 3. **idempotent(多次启动)**:
84
- - 同一 db 连续 `new SQLiteStorage()` 3 次。
85
- - 断言索引数量、列数量两次之间相等;断言 logger 无 error/warn。
86
-
87
- 4. **现有测试回归**:跑 `npx vitest run src/tests/storage*.test.ts` 与 `tests/unit/storage/`。
88
-
89
- ## 实施顺序
90
-
91
- 1. schema.sql 补 `idx_skill_invocations_workflow` / `idx_skill_invocations_feature`
92
- 2. base.ts 加 `hasIndex`
93
- 3. base.ts::runMigrations 所有 `CREATE INDEX IF NOT EXISTS` 用 `if (!this.hasIndex(...))` 守护
94
- 4. 新增 `tests/unit/storage/migration-idempotent.test.ts`
95
- 5. 跑 `npx vitest run tests/unit/storage` + `npx tsc --noEmit`
96
- 6. 跑全量 `npm test`
97
-
98
- ## 风险与回滚
99
-
100
- - **风险**:存量数据库(线上用户)必须能补齐 → baseline 测试是硬门槛,CI 必跑。
101
- - **风险**:`hasIndex` 名字查询不区分表(同名索引理论上不会跨表,SQLite 索引名全局唯一)—— 实际安全。
102
- - **回滚**:所有改动局限在 schema.sql + base.ts + 1 个新测试,`git revert` 单 commit 即可。
103
- - **不动 inline fallback**:H4 范围之外,避免一次改太多。
104
-
105
- ## 命名遵循
106
-
107
- - `hasIndex` / `hasColumn`:has 前缀 → 符合 CLAUDE.md "布尔值用 is/has/should 前缀"。
108
- - 测试文件名 `migration-idempotent.test.ts`:kebab-case + `.test.ts` → 符合命名规范。
109
- - 工具函数 `hasIndex` 与已有 `hasColumn` 并列,对称命名。
@@ -1,82 +0,0 @@
1
- # H6: daemon/services analytics 类迁移 Spec
2
-
3
- ## 目标
4
- 将 3 个纯查询/聚合类从 `src/daemon/services/` 迁出,纠正位置错配,使依赖图反映真实调用方向(仅 web 层使用)。
5
-
6
- ## 调研结果
7
-
8
- ### 调用链
9
- | 类 | 文件 | daemon 调用 | web 调用 | cli 调用 |
10
- |---|---|---|---|---|
11
- | DriftDetector | `src/daemon/services/drift-detector.ts` | 0 | `web/routes/drift.ts:3,21` | 0 |
12
- | WeeklyReportGenerator | `src/daemon/services/weekly-report.ts`(注意:非 `weekly-report-generator.ts`) | 0 | `web/routes/reports.ts:10,20` | 0 |
13
- | AntiPatternDetector | `src/daemon/services/anti-pattern-detector.ts` | 0 | `web/routes/insights.ts:4,7,25` | 0 |
14
-
15
- `src/daemon/{index,handlers,pipeline}` 全无引用。同目录的 `task-segmenter.ts` 是真 daemon 服务(`daemon/index.ts:28,105` + `handlers/stop.ts:14,27`),**留在原地**。
16
-
17
- ### 依赖关系
18
- 3 个文件 imports 仅有:
19
- - `core/storage/sqlite` (SQLiteStorage 类型)
20
- - `core/storage/sessions` (SessionSummary 类型,仅 anti-pattern)
21
- - `core/types` (ForgeEvent,仅 anti-pattern)
22
- - `node:crypto`(标准库)
23
-
24
- **零 daemon 内部依赖** → 无反向依赖风险。注意 `weekly-report.ts:20` 构造时还接收 `skillRegistry`(来自 `web/routes/reports.ts` 的 ctx),但类型来源属 core 层,安全。
25
-
26
- ### 现有测试
27
- - 单元测试:**无**(3 个文件 + 3 个调用方 routes 均无 `.test.ts`)
28
- - 集成测试覆盖路由:**无**(`tests/` 下无 drift/report/insight/anti-pattern 测试)
29
- - 现有 web 路由测试:sessions/stats/skill-stats/events/auth/tasks/rules(均不覆盖本次迁移路径)
30
-
31
- ## 目标目录决策
32
-
33
- **推荐:`src/web/analytics/`**
34
-
35
- 理由:
36
- 1. 实际调用方 100% 是 `web/routes/`,符合"用在哪放在哪"
37
- 2. 当前无 cli/daemon 消费,提升到 core 是过度设计;未来若 cli 需要再上提成本低
38
- 3. 与同层模块 `web/routes/`、`web/static/` 平行,依赖方向天然向下(web → core)
39
-
40
- ## 改造范围
41
-
42
- | 操作 | 来源 → 目标 / 修改点 |
43
- |---|---|
44
- | git mv | `src/daemon/services/drift-detector.ts` → `src/web/analytics/drift-detector.ts` |
45
- | git mv | `src/daemon/services/weekly-report.ts` → `src/web/analytics/weekly-report.ts` |
46
- | git mv | `src/daemon/services/anti-pattern-detector.ts` → `src/web/analytics/anti-pattern-detector.ts` |
47
- | 改 import | `src/web/routes/drift.ts:3` → `'../analytics/drift-detector.js'` |
48
- | 改 import | `src/web/routes/reports.ts:10` → `'../analytics/weekly-report.js'` |
49
- | 改 import | `src/web/routes/insights.ts:7` → `'../analytics/anti-pattern-detector.js'` |
50
- | 清理注释 | `weekly-report.ts:294`、`anti-pattern-detector.ts:80` 引用"daemon/services 既定做法"的文字 |
51
- | barrel | **不建** `index.ts`(仅 3 个文件、3 个调用方,barrel 收益低) |
52
- | 保留 | `src/daemon/services/task-segmenter.ts` 原地不动 |
53
-
54
- ## 测试策略
55
-
56
- - **safety-net(必做)**:迁移前补一个最小集成测试 baseline
57
- - `tests/integration/web-analytics.integration.test.ts`:分别 GET `/api/drift`、`/api/reports/weekly`、`/api/insights`,断言 200 + 关键字段存在(不校验业务正确性,只校验 wiring 没断)
58
- - **回归**:`npx tsc --noEmit` + `npm test` 全量
59
- - **手测**:`./scripts/dev-daemon.sh restart` 后 `curl` 3 个 endpoint
60
-
61
- ## 风险与回滚
62
-
63
- - 风险 1:dist/ 残留旧路径 → `npm run build` 前清理 `dist/daemon/services/{drift,weekly,anti}*`
64
- - 风险 2:第三方/外部脚本 import 旧路径 → 已 grep 确认仅 src/ 内部使用,无外部入口
65
- - 风险 3:`weekly-report.ts:294` 注释提到 anti-pattern-detector 协作历史,迁移后描述失真(仅文档影响)
66
- - 回滚:`git mv` 保留 history,单 commit 完成;失败 `git revert <hash>` 即可
67
-
68
- ## 实施顺序
69
-
70
- 1. 补 safety-net 集成测试(独立 commit,验证当前 main 通过)
71
- 2. `mkdir -p src/web/analytics`
72
- 3. `git mv` 3 个文件(一个 commit)
73
- 4. 改 3 处 import + 清理 2 处误导注释(同 commit 或下一 commit)
74
- 5. `npx tsc --noEmit` → `npm test` → daemon 重启 + curl 三 endpoint
75
- 6. 提交 PR / push
76
-
77
- ## 命名遵循
78
-
79
- - 文件名 kebab-case ✓(保持原名)
80
- - 类名 PascalCase ✓(无改动)
81
- - 目录 `web/analytics/` 全小写 ✓
82
- - 注意:源文件叫 `weekly-report.ts` 而非任务描述里写的 `weekly-report-generator.ts`,spec 以实际文件名为准
@@ -1,204 +0,0 @@
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 | 手工 |
@@ -1,106 +0,0 @@
1
- # L1: SWARM_PROTOCOL 字面量抽到 .md 文件 Spec
2
-
3
- ## 目标
4
-
5
- 把 `src/claudemd/claudemd-generator.ts` 中 223 行的 `SWARM_PROTOCOL` 字符串字面量抽到 `src/claudemd/templates/swarm-protocol.md`,build 时 cp 到 dist/,加载方式对齐 H3 `schema.sql` 的 fail-fast 模式。
6
-
7
- ## 调研结果
8
-
9
- ### 当前位置
10
-
11
- - `src/claudemd/claudemd-generator.ts:555-777`(`const SWARM_PROTOCOL = `...`;`)
12
- - 内容:223 行 markdown,含转义反引号
13
- - 唯一使用点:第 59 行 `const full = SWARM_PROTOCOL + '\n\n' + projectContent;`(`generate()` 方法内)
14
- - 上方有两段重复注释(547-553),可顺手清理
15
-
16
- ### 加载先例
17
-
18
- 1. **`src/core/storage/base.ts:61-73`(H3 schema.sql)**:`fileURLToPath(import.meta.url)` + `dirname` 解析同级目录,`existsSync` 校验,缺失抛 `[SQLiteStorage] schema.sql not found at ...`。ESM 兼容,dev/npm 一致。
19
- 2. **`src/skills/registry.ts:46-49` + `src/skills/official-skills.ts:52-55`(skills/official)**:同样 `fileURLToPath(import.meta.url)`。
20
-
21
- ### 现有测试
22
-
23
- - `tests/integration/` 与 `src/tests/` 均无 `claudemd-generator` 测试 → **零覆盖**,必须先建 safety-net。
24
-
25
- ## 设计方案
26
-
27
- ### 文件位置
28
-
29
- - 新建 `src/claudemd/templates/swarm-protocol.md`(kebab-case,内容为现 555-777 行的原文,去掉 JS 反引号转义)
30
-
31
- ### claudemd-generator.ts 改造
32
-
33
- ```text
34
- - 删除 const SWARM_PROTOCOL = `...`;(555-777)
35
- - 删除上方 547-553 重复注释块
36
- - 新增模块级函数 getSwarmProtocol(): string
37
- · const thisDir = dirname(fileURLToPath(import.meta.url))
38
- · const p = join(thisDir, 'templates', 'swarm-protocol.md')
39
- · 若 !existsSync(p) 抛 `[ClaudeMdGenerator] swarm-protocol.md not found at ${p}. Run npm run build or reinstall.`
40
- · readFileSync(p, 'utf-8')
41
- - 一级缓存:模块级 let cached: string | null = null(避免每次 generate 都读盘)
42
- - 第 59 行:const full = getSwarmProtocol() + '\n\n' + projectContent;
43
- - 顶部 import 加 fileURLToPath(node:url)、dirname(已从 node:path 导入需补 dirname)
44
- ```
45
-
46
- 命名 `get` 前缀(获取单一资源)。
47
-
48
- ### package.json build 改造
49
-
50
- 在现有 `build` 命令中追加:
51
-
52
- ```bash
53
- mkdir -p dist/claudemd/templates && cp src/claudemd/templates/*.md dist/claudemd/templates/
54
- ```
55
-
56
- 末尾 fail-fast 校验追加:
57
-
58
- ```bash
59
- && (test -f dist/claudemd/templates/swarm-protocol.md || (echo '[build] FATAL: dist/claudemd/templates/swarm-protocol.md missing' && exit 1))
60
- ```
61
-
62
- 与现有 `dist/core/storage/schema.sql` 校验风格保持一致。
63
-
64
- ## 测试策略
65
-
66
- ### safety-net(必做,先行)
67
-
68
- 新增 `tests/integration/claudemd-generator.test.ts`:
69
-
70
- 1. **Baseline 测试(迁移前跑通)**:
71
- - mock `ClaudeProvider.complete` 抛错(走 fallback 路径),调 `generator.generate(tmpDir)`
72
- - 断言输出包含 SWARM_PROTOCOL 关键字段:`# claude-forge 工作区规范`、`## 自检`、`Two-Phase Workflow`、`harness-hotfix`、`refactor-safe`、`hybrid-feature-with-safety`
73
- - 断言总行数 ≥ 200
74
- 2. **快照锚点**:保存 SWARM 段的 SHA256 或长度,迁移后断言不变
75
-
76
- ### 回归
77
-
78
- - 迁移完成后重跑 safety-net,断言行为完全一致(同一 hash / 同一行数 / 同一关键字)
79
- - `npx tsc --noEmit`
80
- - `npm test`
81
- - 手测:`npm run build` 后 `ls dist/claudemd/templates/swarm-protocol.md`
82
-
83
- ## 风险与回滚
84
-
85
- | 风险 | 缓解 |
86
- |---|---|
87
- | dev 跑 `tsx src/` 时 dist 不存在 | `fileURLToPath(import.meta.url)` 解析到 `src/claudemd/`,同级 `templates/` 在 src 下存在,dev 路径天然兼容 |
88
- | npm 安装包 cp 失败 | build 末尾 `test -f` 校验,CI 失败而非运行时炸 |
89
- | .md 内反引号转义遗漏 | safety-net 哈希比对会发现 |
90
- | 模块级缓存导致测试串扰 | 暴露 `__resetCache()` 仅 test 用,或不缓存(223 行读盘成本可忽略) |
91
-
92
- **回滚**:单 commit revert 即可(generator.ts + package.json + 新 .md 文件)。
93
-
94
- ## 实施顺序
95
-
96
- 1. 补 `tests/integration/claudemd-generator.test.ts`(safety-net,**当前字面量实现下跑绿**)
97
- 2. 创建 `src/claudemd/templates/swarm-protocol.md`(复制 555-777 原文,去 JS 转义)
98
- 3. 改 `claudemd-generator.ts`:加 `getSwarmProtocol()`,删字面量与重复注释
99
- 4. 改 `package.json` build:cp + fail-fast 校验
100
- 5. 跑 `npm run build && npm test && npx tsc --noEmit`,对比 safety-net hash
101
-
102
- ## 命名遵循
103
-
104
- - 文件 kebab-case:`swarm-protocol.md`、`claudemd-generator.test.ts`
105
- - 加载函数 `get` 前缀:`getSwarmProtocol()`
106
- - 错误前缀 `[ClaudeMdGenerator]`,与 `[SQLiteStorage]` 风格一致
@@ -1,121 +0,0 @@
1
- # M10: ~/.claude-forge 子路径硬编码收敛 Spec
2
-
3
- ## 目标
4
- 把 `~/.claude-forge/<子路径>` 的硬编码(共 7 类、20+ 处)统一收敛到 `src/core/constants.ts` 的 `FORGE_PATHS`,消除 `path.join(homedir(), '.claude-forge', ...)` 重复并降低未来路径变更的成本。
5
-
6
- ## 调研结果
7
-
8
- ### 子路径分组(仅 `~/.claude-forge/` 下的真实文件路径)
9
-
10
- | 子路径 | 引用文件:行 | 总次数 | 现有 FORGE_PATHS |
11
- |---|---|---|---|
12
- | `daemon.token` | lifecycle.ts:9; cli/mcp.ts:45; auth-middleware.ts:18 | 3 | 否 |
13
- | `daemon.pid` | lifecycle.ts:10; cli/daemon.ts:45; cli/status.ts:8; cli/mcp.ts:86 | 4 | 否 |
14
- | `daemon.sock` | lifecycle.ts:52 | 1(外加 error-handler.ts:239 的"forge.sock"字面量提示文本,**待统一**) | 否 |
15
- | `daemon.log` / `daemon-stdout.log` / `daemon-stderr.log` | cli/daemon.ts:47,48,115 | 3 | 否 |
16
- | `hooks/` | cli/init/hook-manager.ts:8 | 1 | 否 |
17
- | `queue/` + `queue/dead/` | core/queue/index.ts:26-28 | 2 | 否 |
18
- | `routing.yaml` | web/routes/types.ts:37 | 1 | 否 |
19
- | `backups/skills` | web/routes/skills.ts:208,235,279,321; web/routes/types.ts:32 | 5 | 否 |
20
- | `backups/routing` | web/routes/types.ts:38 | 1 | 否 |
21
- | `data.db` (字面量) | cli/stats.ts:21 | 1 | **已有但未用** → 改为 `FORGE_PATHS.database()` |
22
-
23
- ### 不属于 FORGE_PATHS 的引用(保留硬编码)
24
-
25
- - `process.cwd() + '.claude-forge/executions/by-route'`(cli/executions.ts:16,53,85)— **项目级目录**,不是 `~/.claude-forge`
26
- - `project_path + '.claude-forge/history'`(daemon/handlers/history-exporter.ts:24)— 同上
27
- - `templates/template-manager.ts:88`(在项目 `projectPath` 下创建 `.claude-forge`)— 项目级
28
- - `cli/init/hook-manager.ts:34`(substring 匹配字符串,非路径拼接)
29
- - `error-handler.ts` 内所有 `~/.claude-forge/...` 是**面向用户的提示文本**,建议保留字符串字面量(用户阅读),但 `forge.sock` 与代码中 `daemon.sock` 不一致 → 顺手修一下
30
- - `claudemd-generator.ts:751` 与 `:211` 是模板内嵌字符串
31
-
32
- ## FORGE_PATHS 扩展设计
33
-
34
- ```ts
35
- export const FORGE_PATHS = {
36
- home: () => FORGE_HOME,
37
- config: () => join(FORGE_HOME, 'config.yaml'),
38
- database: () => join(FORGE_HOME, 'data.db'),
39
- logs: () => join(FORGE_HOME, 'logs'),
40
-
41
- // ── Daemon runtime files ────────────────────────────────
42
- daemonSocket: () => join(FORGE_HOME, 'daemon.sock'),
43
- daemonPid: () => join(FORGE_HOME, 'daemon.pid'),
44
- daemonToken: () => join(FORGE_HOME, 'daemon.token'),
45
- daemonLog: () => join(FORGE_HOME, 'daemon.log'),
46
- daemonStdout: () => join(FORGE_HOME, 'daemon-stdout.log'),
47
- daemonStderr: () => join(FORGE_HOME, 'daemon-stderr.log'),
48
-
49
- // ── Subdirs ─────────────────────────────────────────────
50
- hooks: () => join(FORGE_HOME, 'hooks'),
51
- queue: () => join(FORGE_HOME, 'queue'),
52
- queueDead: () => join(FORGE_HOME, 'queue', 'dead'),
53
-
54
- // ── Patchable targets ───────────────────────────────────
55
- routingYaml: () => join(FORGE_HOME, 'routing.yaml'),
56
- backups: (kind: 'skills' | 'routing') => join(FORGE_HOME, 'backups', kind),
57
- } as const;
58
- ```
59
-
60
- ### 关键决策
61
-
62
- 1. **`backups(kind)` 参数化 vs 分开**:选**参数化**。理由:`backups` 的两个子目录有共同语义(patch 系统的备份根),且 `resolvePatchTarget` 内已经按 `targetType` 分支。`kind` 用字面量联合类型,越界编译期就报错。
63
- 2. **`daemonLog`/`daemonStdout`/`daemonStderr` 三个独立方法 vs 一个 `daemonLog(channel)`**:选**独立方法**。理由:三者在调用点完全分离(stdout/stderr 仅用于 launchd 重定向,daemon.log 是 logger 输出),不存在动态选择场景。
64
- 3. **动态参数(sessionId 等)不纳入**:`history-exporter` 是 `project_path` 拼接,**不属于** `~/.claude-forge`,本次范围外。
65
- 4. **`error-handler.ts` 的字符串字面量**:保留 `~/.claude-forge/...` 字符串(面向用户阅读),但把 `forge.sock` 改成 `daemon.sock` 与代码一致(顺手修,1 行)。
66
-
67
- ## 改造范围(按文件)
68
-
69
- | 文件 | 改动点 | 影响行数 |
70
- |---|---|---|
71
- | `src/core/constants.ts` | 扩展 FORGE_PATHS(11 个新方法)| +12 |
72
- | `src/daemon/lifecycle.ts` | TOKEN_FILE/PID_FILE 改 FORGE_PATHS;getSocketPath 复用 daemonSocket | ~5 |
73
- | `src/cli/commands/daemon.ts` | PID_FILE/STDOUT_LOG/STDERR_LOG + line 115 logFile | 4 |
74
- | `src/cli/commands/status.ts` | PID_FILE(注意:与 lifecycle.ts 重复,可考虑后续从 lifecycle 复用,但本次保持就地替换)| 1 |
75
- | `src/cli/commands/mcp.ts` | tokenPath:45, pid:86 | 2 |
76
- | `src/cli/commands/stats.ts` | dbPath:21 改 `FORGE_PATHS.database()` | 1 |
77
- | `src/cli/init/hook-manager.ts` | HOOKS_DIR 改 `FORGE_PATHS.hooks()` | 1 |
78
- | `src/core/queue/index.ts` | FORGE_DIR/QUEUE_DIR/DEAD_DIR | 3 |
79
- | `src/web/auth-middleware.ts` | TOKEN_FILE | 1 |
80
- | `src/web/routes/types.ts` | resolvePatchTarget 4 处路径 | 4 |
81
- | `src/web/routes/skills.ts` | backupDir × 4 处 | 4 |
82
- | `src/core/utils/error-handler.ts` | `forge.sock` → `daemon.sock`(一致性修复)| 1 |
83
-
84
- **合计:约 39 处替换、12 文件**。无字符串模板 `${homedir()}/.claude-forge/...` 形式(已用 grep 验证)。所有调用点都是 `path.join(homedir(), '.claude-forge', ...)`,机械替换安全。
85
-
86
- ## 测试策略
87
-
88
- 1. **新增** `tests/unit/core/forge-paths.test.ts`:
89
- - 每个方法返回值以 `FORGE_HOME` 为前缀
90
- - `backups('skills')` / `backups('routing')` 返回正确子路径
91
- - 类型层面(编译期)拒绝 `backups('invalid')`
92
- 2. **回归**:
93
- - `tests/unit/core/queue/*`(queue 模块已有测试)
94
- - 单元测试全量 `npx vitest run`
95
- - `npx tsc --noEmit`
96
- 3. **手测**:`./scripts/dev-daemon.sh restart` 验证 pid/token/socket 文件生成
97
-
98
- ## 风险与回滚
99
-
100
- - **路径值不变**:FORGE_PATHS 只是函数封装,运行时返回值与原硬编码完全一致 → 已运行的 daemon、已存在的 token/pid/db 文件不受影响
101
- - **回滚**:单次 PR、git revert 即可
102
- - **测试覆盖**:daemon/handlers 部分零测试(CLAUDE.md 提示),本次不修改 handler 逻辑,仅替换路径常量,风险面小;但**因为涉及 `src/daemon/lifecycle.ts`(无单元测试)和 `src/web/routes/`(中等覆盖)**,按 CLAUDE.md「工作流升级判定」表,建议走 `refactor-safe`(safety-net 阶段先补 `forge-paths.test.ts` + 跑现有 queue/storage 测试作为安全网)
103
- - **launchd plist**:未涉及 plist 模板路径(plist 是绝对路径生成时拼接,不在 FORGE_PATHS 范围)
104
-
105
- ## 实施顺序(给 coder agent)
106
-
107
- 1. **safety-net**:新增 `tests/unit/core/forge-paths.test.ts`(先写好测试,让其通过当前 FORGE_PATHS);跑一遍 `npx vitest run tests/unit/core` 与 `npx tsc --noEmit` 作为基线
108
- 2. **扩展 FORGE_PATHS**:编辑 `src/core/constants.ts` 添加 11 个方法;补全 forge-paths.test.ts 对新方法的断言
109
- 3. **分组替换**(每组完成后跑 `npx tsc --noEmit`):
110
- - Group A:daemon 运行时文件(lifecycle / daemon / status / mcp / auth-middleware)
111
- - Group B:queue(core/queue/index.ts)
112
- - Group C:hooks(hook-manager.ts)
113
- - Group D:web patch(types.ts + skills.ts × 4)
114
- - Group E:stats.ts + error-handler.ts 文案修复
115
- 4. **全量验证**:`npm test` + `npm run build` + `./scripts/dev-daemon.sh restart` 验证 daemon 正常起停
116
-
117
- ## 命名遵循
118
-
119
- - 方法名 camelCase:`daemonSocket`, `daemonPid`, `routingYaml`, `queueDead` ✓(与现有 `home/config/database/logs` 一致)
120
- - 常量名 UPPER_SNAKE_CASE:`FORGE_PATHS`, `FORGE_HOME` ✓
121
- - 测试文件位置:`tests/unit/core/forge-paths.test.ts`