@winspan/claude-forge 8.53.2 → 8.54.4

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 (394) 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/official/official-openspec.md +89 -0
  42. package/dist/skills/official-skills.d.ts.map +1 -1
  43. package/dist/skills/official-skills.js +1 -0
  44. package/dist/skills/official-skills.js.map +1 -1
  45. package/dist/skills/registry.d.ts.map +1 -1
  46. package/dist/skills/registry.js +13 -2
  47. package/dist/skills/registry.js.map +1 -1
  48. package/dist/skills/semantic-matcher.d.ts +2 -2
  49. package/dist/skills/semantic-matcher.d.ts.map +1 -1
  50. package/dist/skills/semantic-matcher.js +14 -19
  51. package/dist/skills/semantic-matcher.js.map +1 -1
  52. package/dist/skills/upgrade-engine.d.ts +3 -1
  53. package/dist/skills/upgrade-engine.d.ts.map +1 -1
  54. package/dist/skills/upgrade-engine.js +25 -14
  55. package/dist/skills/upgrade-engine.js.map +1 -1
  56. package/dist/web/analytics/weekly-report.d.ts.map +1 -1
  57. package/dist/web/analytics/weekly-report.js +21 -29
  58. package/dist/web/analytics/weekly-report.js.map +1 -1
  59. package/dist/web/routes/patch.d.ts.map +1 -1
  60. package/dist/web/routes/patch.js +32 -2
  61. package/dist/web/routes/patch.js.map +1 -1
  62. package/dist/web/routes/sessions.d.ts.map +1 -1
  63. package/dist/web/routes/sessions.js +9 -7
  64. package/dist/web/routes/sessions.js.map +1 -1
  65. package/dist/web/routes/trace.d.ts.map +1 -1
  66. package/dist/web/routes/trace.js +2 -3
  67. package/dist/web/routes/trace.js.map +1 -1
  68. package/dist/web/server.d.ts.map +1 -1
  69. package/dist/web/server.js +3 -2
  70. package/dist/web/server.js.map +1 -1
  71. package/package.json +12 -2
  72. package/scripts/postinstall.cjs +21 -0
  73. package/.claude/CLAUDE.md +0 -17
  74. package/.eslintrc.js +0 -23
  75. package/.prettierrc +0 -8
  76. package/ARCHITECTURE_ISSUES.md +0 -249
  77. package/CLAUDE.md +0 -265
  78. package/CLAUDE.md.backup +0 -488
  79. package/docs/concurrent-agents.md +0 -129
  80. package/docs/design/architecture-review-20260516.md +0 -232
  81. package/docs/design/fix-skills-data-and-set-leak-spec-20260516-1300.md +0 -219
  82. package/docs/design/h1-storage-aggregation-spec-20260518-1121.md +0 -299
  83. package/docs/design/h2-getdatabase-encapsulation-spec-20260518-1450.md +0 -191
  84. package/docs/design/h3-fallback-removal-spec-20260518-1245.md +0 -76
  85. package/docs/design/h4-index-dedup-spec-20260518-1230.md +0 -109
  86. package/docs/design/h6-services-migration-spec-20260518-1355.md +0 -82
  87. package/docs/design/hook-failure-queue-spec-20260516-1530.md +0 -204
  88. package/docs/design/l1-swarm-protocol-extract-spec-20260518-1605.md +0 -106
  89. package/docs/design/m10-forge-paths-spec-20260518-1320.md +0 -121
  90. package/docs/design/m2-m3-tool-input-spec-20260518-1425.md +0 -131
  91. package/docs/design/m7-routing-event-association-spec-20260518-1545.md +0 -103
  92. package/docs/design/project-path-gitroot-spec-20260518-1715.md +0 -134
  93. package/docs/design/refactor-phase1-spec-20260515-1600.md +0 -543
  94. package/docs/design/refactor-phase2-spec-20260515-1700.md +0 -424
  95. package/docs/design/skill-ai-upgrade-spec-20260518-1930.md +0 -297
  96. package/docs/design/task-active-gc-spec-20260518-1745.md +0 -146
  97. package/docs/design/tasks-list-filter-pagination-spec-20260518-0930.md +0 -208
  98. package/docs/implementation/daemon-skill-sync-changelog-20260518-2000.md +0 -22
  99. package/docs/implementation/fix-skills-data-and-set-leak-changelog-20260516-1300.md +0 -104
  100. package/docs/implementation/h1-storage-aggregation-changelog-20260518-1121.md +0 -82
  101. package/docs/implementation/h2-final-changelog-20260518-1530.md +0 -61
  102. package/docs/implementation/h2-phase1-safety-net-changelog-20260518-1450.md +0 -70
  103. package/docs/implementation/h2-phase2-operations-changelog-20260518-1450.md +0 -120
  104. package/docs/implementation/h2-phase3-callsites-changelog-20260518-1450.md +0 -71
  105. package/docs/implementation/h3-fallback-removal-changelog-20260518-1245.md +0 -71
  106. package/docs/implementation/h4-index-dedup-changelog-20260518-1230.md +0 -60
  107. package/docs/implementation/h6-services-migration-changelog-20260518-1355.md +0 -46
  108. package/docs/implementation/h7-m9-defaults-changelog-20260518-1300.md +0 -46
  109. package/docs/implementation/hook-failure-queue-changelog-20260516-1530.md +0 -196
  110. package/docs/implementation/hotfix-daemon-event-reject-20260516-1430.md +0 -56
  111. package/docs/implementation/l1-swarm-protocol-extract-changelog-20260518-1605.md +0 -45
  112. package/docs/implementation/l3-l4-daemon-perf-changelog-20260518-1410.md +0 -63
  113. package/docs/implementation/l6-l8-final-cleanup-changelog-20260518-1640.md +0 -38
  114. package/docs/implementation/m1-m4-m5-l7-cleanup-changelog-20260518-1310.md +0 -58
  115. package/docs/implementation/m10-forge-paths-changelog-20260518-1320.md +0 -60
  116. package/docs/implementation/m2-m3-tool-input-changelog-20260518-1425.md +0 -43
  117. package/docs/implementation/m6-m8-naming-shutdown-changelog-20260518-1340.md +0 -56
  118. package/docs/implementation/m7-routing-association-changelog-20260518-1545.md +0 -69
  119. package/docs/implementation/project-path-gitroot-changelog-20260518-1715.md +0 -63
  120. package/docs/implementation/refactor-phase1-changelog-20260515-1630.md +0 -354
  121. package/docs/implementation/refactor-phase2-changelog-20260515-1705.md +0 -421
  122. package/docs/implementation/skill-ai-upgrade-changelog-20260518-1930.md +0 -49
  123. package/docs/implementation/task-active-gc-changelog-20260518-1745.md +0 -35
  124. package/docs/implementation/task-title-summary-changelog-20260518-1130.md +0 -39
  125. package/docs/implementation/tasks-detail-back-loses-filters-changelog-20260518-1100.md +0 -22
  126. package/docs/implementation/tasks-list-filter-pagination-changelog-20260518-0930.md +0 -72
  127. package/docs/implementation/tasks-page-white-screen-hotfix-changelog-20260518-1015.md +0 -56
  128. package/docs/reviews/claudemd-template-sync.md +0 -54
  129. package/docs/reviews/task-title-summary.md +0 -92
  130. package/docs/reviews/tasks-detail-back-loses-filters.md +0 -58
  131. package/docs/reviews/tasks-filter-pagination.md +0 -80
  132. package/docs/reviews/tasks-page-white-screen-hotfix.md +0 -126
  133. package/docs/ruflo-learning-strategy.md +0 -322
  134. package/docs/skills-deduplication-analysis.md +0 -83
  135. package/docs/skills-multiformat-support.md +0 -177
  136. package/docs/skills-third-party.md +0 -183
  137. package/docs/testing/tasks-filter-pagination-test-report.md +0 -86
  138. package/forge +0 -321
  139. package/playwright.config.ts +0 -40
  140. package/scripts/demo-v2.ts +0 -91
  141. package/scripts/dev-daemon.sh +0 -232
  142. package/scripts/dev-web.ts +0 -109
  143. package/scripts/e2e-mcp-link.ts +0 -423
  144. package/scripts/e2e-methodology-quality.ts +0 -253
  145. package/scripts/e2e-routing.ts +0 -456
  146. package/scripts/e2e-user-methodology.ts +0 -326
  147. package/scripts/e2e-web-workflows.ts +0 -299
  148. package/scripts/migrate-legacy-to-dynamic.sql +0 -108
  149. package/scripts/regenerate-execution-docs.ts +0 -116
  150. package/scripts/sync-agent-skills.ts +0 -193
  151. package/scripts/test-hook.sh +0 -71
  152. package/scripts/verify-skill-loading.ts +0 -62
  153. package/src/claudemd/claudemd-generator.ts +0 -568
  154. package/src/claudemd/convention-extractor.ts +0 -69
  155. package/src/claudemd/index.ts +0 -35
  156. package/src/claudemd/persona-manager.ts +0 -88
  157. package/src/claudemd/resume-manager.ts +0 -236
  158. package/src/claudemd/tech-detector.ts +0 -220
  159. package/src/claudemd/templates/swarm-protocol.md +0 -222
  160. package/src/cli/commands/claudemd.ts +0 -84
  161. package/src/cli/commands/config.ts +0 -46
  162. package/src/cli/commands/daemon.ts +0 -310
  163. package/src/cli/commands/executions.ts +0 -115
  164. package/src/cli/commands/init.ts +0 -204
  165. package/src/cli/commands/logs.ts +0 -181
  166. package/src/cli/commands/mcp.ts +0 -242
  167. package/src/cli/commands/menu.ts +0 -357
  168. package/src/cli/commands/skills.ts +0 -328
  169. package/src/cli/commands/stats.ts +0 -73
  170. package/src/cli/commands/status.ts +0 -69
  171. package/src/cli/commands/template.ts +0 -77
  172. package/src/cli/commands/trace.ts +0 -148
  173. package/src/cli/index.ts +0 -42
  174. package/src/cli/init/hook-manager.ts +0 -132
  175. package/src/core/ai/provider.ts +0 -308
  176. package/src/core/ai/types.ts +0 -51
  177. package/src/core/config.ts +0 -124
  178. package/src/core/constants.ts +0 -67
  179. package/src/core/event-fields.ts +0 -32
  180. package/src/core/queue/index.ts +0 -192
  181. package/src/core/storage/base.ts +0 -302
  182. package/src/core/storage/events.ts +0 -434
  183. package/src/core/storage/injections.ts +0 -78
  184. package/src/core/storage/maintenance.ts +0 -59
  185. package/src/core/storage/migrations/002_add_skill_tracking.sql +0 -6
  186. package/src/core/storage/migrations/003_add_skill_invocations.sql +0 -23
  187. package/src/core/storage/performance-indexes.sql +0 -23
  188. package/src/core/storage/routing.ts +0 -322
  189. package/src/core/storage/rows.ts +0 -112
  190. package/src/core/storage/schema.sql +0 -224
  191. package/src/core/storage/sessions.ts +0 -168
  192. package/src/core/storage/skills.ts +0 -233
  193. package/src/core/storage/sqlite.ts +0 -293
  194. package/src/core/storage/tasks.ts +0 -318
  195. package/src/core/storage/token-usage.ts +0 -93
  196. package/src/core/types.ts +0 -181
  197. package/src/core/utils/error-handler.ts +0 -257
  198. package/src/core/utils/forge-resume-block.ts +0 -74
  199. package/src/core/utils/format.ts +0 -69
  200. package/src/core/utils/git.ts +0 -23
  201. package/src/core/utils/logger.ts +0 -134
  202. package/src/core/utils/lru-cache.ts +0 -54
  203. package/src/core/utils/path.ts +0 -19
  204. package/src/core/utils/session.ts +0 -26
  205. package/src/core/utils/time.ts +0 -37
  206. package/src/core/utils/token-tracker.ts +0 -97
  207. package/src/daemon/event-parser.ts +0 -36
  208. package/src/daemon/handlers/history-exporter.ts +0 -117
  209. package/src/daemon/handlers/post-tool-use.ts +0 -54
  210. package/src/daemon/handlers/stop.ts +0 -208
  211. package/src/daemon/handlers/user-prompt.ts +0 -178
  212. package/src/daemon/hook-sync.ts +0 -91
  213. package/src/daemon/index.ts +0 -312
  214. package/src/daemon/launchd/com.claude-forge.daemon.plist.template +0 -47
  215. package/src/daemon/launchd-installer.ts +0 -260
  216. package/src/daemon/lifecycle.ts +0 -128
  217. package/src/daemon/router.ts +0 -40
  218. package/src/daemon/server.ts +0 -196
  219. package/src/daemon/services/task-segmenter.ts +0 -112
  220. package/src/daemon/skill-sync.ts +0 -88
  221. package/src/hooks/hook-lib.sh +0 -118
  222. package/src/hooks/notification.sh +0 -35
  223. package/src/hooks/post-tool-use.sh +0 -61
  224. package/src/hooks/pre-tool-use.sh +0 -63
  225. package/src/hooks/stop.sh +0 -43
  226. package/src/hooks/user-prompt-submit.sh +0 -69
  227. package/src/mcp/server.ts +0 -322
  228. package/src/skills/index.ts +0 -2
  229. package/src/skills/invocation-guard.ts +0 -177
  230. package/src/skills/matcher.ts +0 -148
  231. package/src/skills/official/code-simplifier.md +0 -52
  232. package/src/skills/official/find-skills.md +0 -142
  233. package/src/skills/official/official-api-design.md +0 -30
  234. package/src/skills/official/official-architecture-decision.md +0 -41
  235. package/src/skills/official/official-bmad.md +0 -118
  236. package/src/skills/official/official-db-schema-design.md +0 -34
  237. package/src/skills/official/official-debug.md +0 -25
  238. package/src/skills/official/official-doc-driven.md +0 -31
  239. package/src/skills/official/official-harness-engineering.md +0 -108
  240. package/src/skills/official/official-performance-optimization.md +0 -30
  241. package/src/skills/official/official-pr-review.md +0 -35
  242. package/src/skills/official/official-release-checklist.md +0 -30
  243. package/src/skills/official/official-security-hardening.md +0 -32
  244. package/src/skills/official/official-spec-driven-design.md +0 -31
  245. package/src/skills/official/planning-with-files.md +0 -241
  246. package/src/skills/official/ui-ux-pro-max.md +0 -105
  247. package/src/skills/official/webapp-testing.md +0 -96
  248. package/src/skills/official-skills.ts +0 -89
  249. package/src/skills/registry.ts +0 -355
  250. package/src/skills/semantic-matcher.ts +0 -234
  251. package/src/skills/tools/pipeline-suggest.ts +0 -226
  252. package/src/skills/tools/skill-invoke.ts +0 -168
  253. package/src/skills/tools/skill-list.ts +0 -59
  254. package/src/skills/upgrade-engine.ts +0 -541
  255. package/src/skills/upgrade-prompt.ts +0 -84
  256. package/src/templates/go.yaml +0 -53
  257. package/src/templates/python.yaml +0 -59
  258. package/src/templates/react.yaml +0 -55
  259. package/src/templates/template-manager.ts +0 -170
  260. package/src/web/analytics/anti-pattern-detector.ts +0 -367
  261. package/src/web/analytics/drift-detector.ts +0 -219
  262. package/src/web/analytics/weekly-report.ts +0 -431
  263. package/src/web/auth-middleware.ts +0 -54
  264. package/src/web/routes/_helpers.ts +0 -34
  265. package/src/web/routes/ai.ts +0 -204
  266. package/src/web/routes/auth.ts +0 -22
  267. package/src/web/routes/drift.ts +0 -25
  268. package/src/web/routes/error-handler.ts +0 -120
  269. package/src/web/routes/events.ts +0 -47
  270. package/src/web/routes/insights.ts +0 -43
  271. package/src/web/routes/patch.ts +0 -117
  272. package/src/web/routes/reports.ts +0 -34
  273. package/src/web/routes/rules.ts +0 -76
  274. package/src/web/routes/sessions.ts +0 -250
  275. package/src/web/routes/skill-stats.ts +0 -92
  276. package/src/web/routes/skills.ts +0 -350
  277. package/src/web/routes/static.ts +0 -67
  278. package/src/web/routes/stats.ts +0 -50
  279. package/src/web/routes/status.ts +0 -30
  280. package/src/web/routes/tasks.ts +0 -193
  281. package/src/web/routes/token-usage.ts +0 -20
  282. package/src/web/routes/trace.ts +0 -126
  283. package/src/web/routes/types.ts +0 -57
  284. package/src/web/server.ts +0 -134
  285. package/src/web/ssrf-guard.ts +0 -112
  286. package/src/web/static/index.html +0 -3251
  287. package/src/web/static/vendor/chart.umd.min.js +0 -20
  288. package/tests/e2e/dashboard.spec.ts +0 -205
  289. package/tests/e2e/routing-skill-e2e.test.ts +0 -39
  290. package/tests/helpers/mock-ai.ts +0 -92
  291. package/tests/helpers/mock-storage.ts +0 -159
  292. package/tests/integration/claudemd-generator.test.ts +0 -90
  293. package/tests/integration/queue-replay.integration.test.ts +0 -193
  294. package/tests/integration/tasks-filter.integration.test.ts +0 -154
  295. package/tests/integration/web-analytics.integration.test.ts +0 -133
  296. package/tests/integration/web-stats.integration.test.ts +0 -135
  297. package/tests/integration/web-trace.integration.test.ts +0 -175
  298. package/tests/performance/database.benchmark.ts +0 -161
  299. package/tests/semantic-matcher.test.ts +0 -99
  300. package/tests/skill-matcher.test.ts +0 -110
  301. package/tests/unit/ai-provider-retry.test.ts +0 -194
  302. package/tests/unit/ai-provider-vision.test.ts +0 -224
  303. package/tests/unit/claudemd-generator.test.ts +0 -68
  304. package/tests/unit/cli-mcp.test.ts +0 -141
  305. package/tests/unit/core/forge-paths.test.ts +0 -99
  306. package/tests/unit/daemon/hook-sync.test.ts +0 -71
  307. package/tests/unit/daemon/post-tool-use.test.ts +0 -121
  308. package/tests/unit/daemon/skill-sync.test.ts +0 -75
  309. package/tests/unit/daemon/stop-handler-behavior-summary.test.ts +0 -202
  310. package/tests/unit/daemon/task-segmenter-recover.test.ts +0 -84
  311. package/tests/unit/event-fields.test.ts +0 -88
  312. package/tests/unit/event-parser.test.ts +0 -55
  313. package/tests/unit/handlers.test.ts +0 -171
  314. package/tests/unit/hooks/resolve-project-path.test.ts +0 -122
  315. package/tests/unit/invocation-guard.test.ts +0 -125
  316. package/tests/unit/queue.test.ts +0 -272
  317. package/tests/unit/router.test.ts +0 -138
  318. package/tests/unit/security.test.ts +0 -128
  319. package/tests/unit/skill-invocations-workflow.test.ts +0 -495
  320. package/tests/unit/skill-registry.test.ts +0 -94
  321. package/tests/unit/skills/invocation-guard-ttl.test.ts +0 -211
  322. package/tests/unit/skills/official-skills-loader.test.ts +0 -126
  323. package/tests/unit/skills/registry-multiformat.test.ts +0 -92
  324. package/tests/unit/skills/upgrade-engine-parse.test.ts +0 -138
  325. package/tests/unit/skills/upgrade-engine.test.ts +0 -401
  326. package/tests/unit/skills/upgrade-prompt.test.ts +0 -89
  327. package/tests/unit/socket-server.test.ts +0 -183
  328. package/tests/unit/storage/event-operations-aggregates.test.ts +0 -342
  329. package/tests/unit/storage/migration-idempotent.test.ts +0 -304
  330. package/tests/unit/storage/routing-aggregates.test.ts +0 -276
  331. package/tests/unit/storage/routing.test.ts +0 -117
  332. package/tests/unit/storage/schema-missing.test.ts +0 -81
  333. package/tests/unit/storage/session-operations-aggregates.test.ts +0 -120
  334. package/tests/unit/storage/sessions-aggregate.test.ts +0 -435
  335. package/tests/unit/storage/skill-operations-counts.test.ts +0 -106
  336. package/tests/unit/storage/skills-aggregates.test.ts +0 -104
  337. package/tests/unit/storage/sqlite-refactor-harness.test.ts +0 -314
  338. package/tests/unit/storage/task-operations-counts.test.ts +0 -46
  339. package/tests/unit/storage/tasks-getById.test.ts +0 -343
  340. package/tests/unit/storage/tasks-stale-gc.test.ts +0 -86
  341. package/tests/unit/storage.test.ts +0 -172
  342. package/tests/unit/token-usage.test.ts +0 -144
  343. package/tests/unit/type-guards.test.ts +0 -201
  344. package/tests/unit/utils/format.test.ts +0 -189
  345. package/tests/unit/utils/session.test.ts +0 -89
  346. package/tests/unit/utils/time.test.ts +0 -112
  347. package/tests/unit/web/navigation-back-contract.test.ts +0 -134
  348. package/tests/unit/web/routes-auth.test.ts +0 -93
  349. package/tests/unit/web/routes-events.test.ts +0 -101
  350. package/tests/unit/web/routes-rules.test.ts +0 -182
  351. package/tests/unit/web/routes-sessions.test.ts +0 -181
  352. package/tests/unit/web/routes-skill-stats.test.ts +0 -179
  353. package/tests/unit/web/routes-stats.test.ts +0 -92
  354. package/tests/unit/web/routes-tasks.test.ts +0 -385
  355. package/tests/unit/web/task-title-contract.test.ts +0 -210
  356. package/tests/unit/web/tasks-component-contract.test.ts +0 -179
  357. package/tsconfig.json +0 -22
  358. package/vitest.config.ts +0 -21
  359. package/vitest.integration.config.ts +0 -16
  360. package/web/CLAUDE.md +0 -20
  361. package/web/index.html +0 -13
  362. package/web/package-lock.json +0 -4854
  363. package/web/package.json +0 -35
  364. package/web/postcss.config.js +0 -6
  365. package/web/src/App.tsx +0 -110
  366. package/web/src/components/CodeBlock.tsx +0 -31
  367. package/web/src/components/Confirm.tsx +0 -96
  368. package/web/src/components/Drawer.tsx +0 -60
  369. package/web/src/components/Layout.tsx +0 -145
  370. package/web/src/components/MarkdownRenderer.tsx +0 -77
  371. package/web/src/components/SearchInput.tsx +0 -31
  372. package/web/src/components/SessionDetailContent.tsx +0 -157
  373. package/web/src/components/Toast.tsx +0 -92
  374. package/web/src/index.css +0 -19
  375. package/web/src/main.tsx +0 -31
  376. package/web/src/pages/AIConfig.tsx +0 -233
  377. package/web/src/pages/Dashboard.tsx +0 -572
  378. package/web/src/pages/Events.tsx +0 -271
  379. package/web/src/pages/Reports.tsx +0 -428
  380. package/web/src/pages/SessionDetail.tsx +0 -162
  381. package/web/src/pages/Sessions.tsx +0 -205
  382. package/web/src/pages/Skills.tsx +0 -180
  383. package/web/src/pages/TaskDetail.tsx +0 -515
  384. package/web/src/pages/Tasks.tsx +0 -415
  385. package/web/src/utils/auth.ts +0 -59
  386. package/web/src/utils/export.ts +0 -54
  387. package/web/src/utils/navigation.ts +0 -25
  388. package/web/src/utils/task-title.ts +0 -49
  389. package/web/src/utils/time.ts +0 -13
  390. package/web/tailwind.config.js +0 -11
  391. package/web/tsconfig.json +0 -21
  392. package/web/tsconfig.node.json +0 -10
  393. package/web/vite.config.ts +0 -76
  394. package/winspan-claude-forge-8.43.0.tgz +0 -0
@@ -1,131 +0,0 @@
1
- # M2 + M3: event tool_input 类型契约 Spec
2
-
3
- ## 目标
4
- 为 `ForgeEvent.tool_input` 建立可选字段类型契约消除 `as any` 泛滥;同时让 `event_id` 在 parser 层尊重外部传入,为 hook 端端到端去重铺路。
5
-
6
- ## 调研结果
7
-
8
- ### M2 使用统计(30 处含 `as any` 与 `as Record<string,unknown>`)
9
-
10
- | 工具 | 字段 | 使用点 |
11
- |---|---|---|
12
- | Bash | `command` | `web/routes/sessions.ts:95,97,223,225`; `anti-pattern-detector.ts:256,363`; `cli/commands/logs.ts:44`; `history-exporter.ts:103` |
13
- | Edit/Write | `file_path` | `sessions.ts:90,91,232,233`; `tasks.ts:161,163`; `anti-pattern-detector.ts:140,356`; `resume-manager.ts:118`; `cli/commands/logs.ts:45`; `weekly-report.ts:274` |
14
- | UserPromptSubmit fallback | `user_prompt` | `sessions.ts:82,83,159,164`; `tasks.ts:168,171`; `daemon/index.ts:161`; `storage/base.ts:253,257` |
15
- | Agent/Task | `subagent_type`, `name`, `prompt` | `web/routes/tasks.ts:125–129`; `daemon/handlers/post-tool-use.ts:29` |
16
- | Notebook | `notebook_path` | `weekly-report.ts:274` |
17
-
18
- ### 使用模式
19
- **几乎全部是防御访问**:`(e.tool_input as any)?.command || ''`、`?.file_path`、`?? input?.command`。零处做 strict assert。
20
- 真正窄化的两处(`post-tool-use.ts:29`、`web/routes/tasks.ts:111-131`)也是 `?` 容忍。
21
-
22
- ### M3 event_id 流向
23
- - **Hook 端**:`pre-tool-use.sh`、`post-tool-use.sh` 等当前**不产生** `event_id`;payload 里无该字段。
24
- - **Queue 层**:`core/queue/index.ts:83` 已经写了 `event.event_id ?? randomUUID()`,文件名也依赖之。
25
- - **Storage 层**:`core/storage/events.ts:21` schema 已 `event_id: z.string().uuid().optional()`,`writeEvent` 也是 `event.event_id || randomUUID()`。**唯一断点**:`daemon/event-parser.ts:23` 无条件 `randomUUID()`,先于 storage,外部传入永远被覆盖。
26
-
27
- ## 方案选择
28
-
29
- ### M2:方案 B(lenient bag)+ 辅助 getter
30
- 理由:
31
- 1. 30+ 处使用全是 undefined-friendly,方案 A 需要给每个站点加 type guard,改动大且收益低(hook event 名不等于 tool 名,`Edit`/`Write`/`Bash` 都来自 `event.tool_name`,不是 `hook_type` discriminator)。
32
- 2. Claude Code 的 tool 集合是开放的(未来还可能新增),union 难以穷举;bag + index signature 兼容前向。
33
- 3. 已有 `anti-pattern-detector.ts:354-365` 的 `extractFilePath`/`extractBashCommand` 范式,扩展即可。
34
-
35
- ### M3:保留 `event_id` 可选透传
36
- `event-parser.ts` 改为 `event_id: validated.event_id ?? randomUUID()`,schema 加 `event_id: z.string().uuid().optional()`。**不强制 hook 端立即生成**。
37
-
38
- ## 类型设计
39
-
40
- ```ts
41
- // core/types.ts 追加
42
- export interface ToolInputFields {
43
- // Bash
44
- command?: string;
45
- description?: string;
46
- // Edit / Write / Read / NotebookEdit
47
- file_path?: string;
48
- notebook_path?: string;
49
- old_string?: string;
50
- new_string?: string;
51
- content?: string;
52
- // Agent / Task
53
- subagent_type?: string;
54
- name?: string;
55
- prompt?: string;
56
- // UserPromptSubmit fallback envelope
57
- user_prompt?: string;
58
- // 兼容未来未知字段
59
- [key: string]: unknown;
60
- }
61
-
62
- export interface ForgeEvent {
63
- // ...
64
- tool_input?: ToolInputFields;
65
- tool_output?: Record<string, unknown>;
66
- event_id?: string;
67
- }
68
-
69
- // helpers(放 core/event-fields.ts)
70
- export function getCommand(e: ForgeEvent): string | undefined {
71
- const c = e.tool_input?.command;
72
- return typeof c === 'string' ? c : undefined;
73
- }
74
- export function getFilePath(e: ForgeEvent): string | undefined {
75
- const fp = e.tool_input?.file_path ?? e.tool_input?.notebook_path;
76
- return typeof fp === 'string' && fp.length > 0 ? fp : undefined;
77
- }
78
- export function getUserPrompt(e: ForgeEvent): string | undefined {
79
- return e.user_prompt ?? (typeof e.tool_input?.user_prompt === 'string' ? e.tool_input.user_prompt : undefined);
80
- }
81
- export function getSubagentType(e: ForgeEvent): string | undefined {
82
- const s = e.tool_input?.subagent_type;
83
- return typeof s === 'string' ? s : undefined;
84
- }
85
- ```
86
-
87
- ## 改造范围
88
-
89
- | 文件 | 改动点 | 行数 |
90
- |---|---|---|
91
- | `src/core/types.ts` | 加 `ToolInputFields`;改 `ForgeEvent.tool_input` 类型 | +25 |
92
- | `src/core/event-fields.ts`(新建)| 4 个 getter | +30 |
93
- | `src/daemon/event-parser.ts` | schema 加 `event_id.optional()`;`event_id ?? randomUUID()`;`tool_input as ToolInputFields` | ~4 |
94
- | `src/daemon/index.ts:161` | 改 `getUserPrompt(event)` | 1 |
95
- | `src/web/routes/sessions.ts` | 8 处 `(tool_input as any)?.X` → getter | ~10 |
96
- | `src/web/routes/tasks.ts` | 5 处 | ~6 |
97
- | `src/cli/commands/logs.ts:42-46` | 直接用 `e.tool_input?.command` 等 | 4 |
98
- | `src/web/analytics/anti-pattern-detector.ts` | `extractFilePath/Command` 内联或调 getter | 2 |
99
- | `src/daemon/handlers/post-tool-use.ts:29` | `getSubagentType(event)` | 1 |
100
- | `src/daemon/handlers/history-exporter.ts:102-103` | 直接 `.file_path / .command` | 2 |
101
- | `src/claudemd/resume-manager.ts:118` | 已经接近规范,去 `as string` | 1 |
102
- | `src/core/storage/events.ts` | `tool_input` 反序列化 cast 调整 | 1 |
103
- | `src/core/storage/tasks.ts:233` | 同上 | 1 |
104
- | `src/core/storage/base.ts:253,257` | SQL 不变(已用 json_extract);无代码改动 | 0 |
105
-
106
- ## 测试策略
107
- - **新增** `src/tests/event-fields.test.ts`:4 个 getter × {undefined, wrong type, valid} 共约 12 case。
108
- - **新增** `src/tests/event-parser.test.ts`:
109
- - 无 `event_id` → 自动生成 UUID
110
- - 传入 `event_id` (合法 UUID) → 透传
111
- - `tool_input` 含 `command/file_path` → 落到 `ToolInputFields`
112
- - **回归**:`src/tests/events.test.ts`(若存在)补一条 `writeEvent` + parser 端到端 event_id 透传 + 重放 UNIQUE 拒收。
113
- - **集成**:现有 `tests/integration/*` 跑完无回归。
114
-
115
- ## 风险与回滚
116
- - **风险 1**:`ToolInputFields` 加 `[key:string]: unknown` 等于半放弃严格性 — 接受,因为目标是消 `as any` 与统一访问入口,而非全量窄化。
117
- - **风险 2**:M3 让外部 event_id 入库后,若 hook 端误用非 UUID 字符串,zod `.uuid()` 会抛 → 由 parser 抛错入 daemon error 路径,与现有 schema 失败同语义。回滚:parser 单行还原 `randomUUID()`。
118
- - **回滚成本**:M2 是纯类型 + getter 替换,git revert 即可;M3 仅 2 行。
119
-
120
- ## 实施顺序
121
- 1. 新增 `core/types.ts` 类型 + `core/event-fields.ts` getter,先跑 `tsc --noEmit`(此时旧 `as any` 仍有效,无破坏)。
122
- 2. 改 `daemon/event-parser.ts`(M3 + tool_input cast);加 parser 测试。
123
- 3. 逐文件替换 `as any`:`daemon/index.ts` → `cli/logs.ts` → `daemon/handlers/*` → `web/routes/sessions.ts` → `web/routes/tasks.ts` → `web/analytics/*` → `claudemd/resume-manager.ts`。每改一个跑 `tsc --noEmit`。
124
- 4. 跑 `npm test`,确认 0 回归。
125
- 5. 抓 hook 端 event_id 预生成作为后续 follow-up(**本 spec 不实施**)。
126
-
127
- ## 命名遵循
128
- - Getter 用 `get*` 前缀(符合「获取单个资源用 `get`」约定)。
129
- - 类型用 PascalCase:`ToolInputFields`。
130
- - 文件 kebab-case:`event-fields.ts`。
131
- - 字段名沿用 hook 原始命名 (`file_path` / `command` / `subagent_type`),不改 snake_case。
@@ -1,103 +0,0 @@
1
- # M7: post-tool-use routing_event 关联修复 Spec
2
-
3
- ## 目标
4
-
5
- 修复 `PostToolUseHandler` 将 Agent 调用错误关联到已完成(`obeyed` 已填)的 routing_event 的时序错配 bug:把"最近一条"语义收紧为"最近一条 pending(`obeyed IS NULL`)"。
6
-
7
- ## 数据流分析
8
-
9
- ### routing_event 生命周期
10
-
11
- | T | 触发 | 操作 | 状态 |
12
- |---|---|---|---|
13
- | T0 | user prompt P1 | `UserPromptHandler` 写 routing_event#1 | `obeyed=NULL` |
14
- | T1 | Agent 调用 | `PostToolUseHandler` 取 most-recent → #1,update | `#1.obeyed=1` |
15
- | T2 | 普通工具(Read/Bash)| 不写 routing_event | `#1.obeyed=1` |
16
- | T3 | user prompt P2 | 写 routing_event#2 | `#2.obeyed=NULL`,#1 仍 obeyed=1 |
17
- | T4 | Agent 调用 | 取 most-recent → #2 | 正常 |
18
-
19
- ### 现有读写点(routing_events)
20
-
21
- | 调用方 | 操作 | 方法 |
22
- |---|---|---|
23
- | `user-prompt.ts:120` | 每次 prompt insert,`obeyed=null` | `writeRoutingEvent` |
24
- | `post-tool-use.ts:33` | 取最近一条 | `getRecentRoutingEvent(sessionId)` |
25
- | `post-tool-use.ts:35` | 更新 obeyed/routed_to_* | `updateRoutingEvent(id, patch)` |
26
- | daemon 恢复 | 拉 pending(项目级) | `queryPendingRoutingEvents(ageMs)` |
27
- | 统计/聚合 | 只读 | `queryRoutingEvents`、`aggregate*` |
28
-
29
- ## Bug 复现路径
30
-
31
- **真实错配场景**:同一 user prompt 内连续 2+ 个 Agent 调用。
32
-
33
- ```
34
- T0 prompt P1 → write #1 (obeyed=NULL)
35
- T1 Agent#a 完成 → PostToolUse → getRecent → #1 → update {obeyed=1, routed_to_name='a'}
36
- T2 Agent#b 完成 → PostToolUse → getRecent → 仍是 #1 → update {obeyed=1, routed_to_name='b'}
37
- ```
38
-
39
- 后果:#1 的 `routed_to_name`、`first_tool_ts` 被第二个 Agent **覆盖**;第二个 Agent 调用**没有自己的归属 routing_event**,统计层缺数。
40
-
41
- **第二种错配**:跨 prompt 但中间 prompt 未走 UserPromptHandler(如 hook 失败 / daemon 重启后 buffer 丢失),下一个 Agent 仍会误关联到旧的 obeyed=1 的事件并把它再次覆盖。
42
-
43
- > review 描述的"覆盖未来不相关"其实是"覆盖过去已完成"语义,效果一致——丢失上次填充结果且当前调用无新行。
44
-
45
- ## 方案对比
46
-
47
- | 维度 | A: `obeyed IS NULL` 过滤 | B: sessionKey in-mem cache | C: A + B 组合 |
48
- |---|---|---|---|
49
- | 实现复杂度 | 低(1 个 SQL 改/加方法)| 中(cache + 失效)| 中高 |
50
- | 跨进程/重启鲁棒 | 强(DB 真源)| 弱(cache 丢)| 强 |
51
- | 同 prompt 多 Agent 行为 | 第 2 个 Agent 找不到 pending → 跳过更新(数据丢失)| 同上,cache 也指向同一 id | 同上 |
52
- | 时序正确性 | 强 | 强(cache 命中时)| 强 |
53
- | 风险 | 同 prompt 多 Agent 漏记需另案 | daemon crash 丢 cache | 复杂度高于必要 |
54
-
55
- **推荐:方案 A**。理由:
56
- 1. DB 是单一真源,无 cache 一致性问题。
57
- 2. 同 prompt 多 Agent 场景下,方案 A 与 B 行为一致(都只命中一次),不构成 B 的优势。
58
- 3. "同 prompt 多 Agent 都要记录"是 M7 范围外的功能扩展(应该在 PostToolUse 里 **insert** 新 routing_event 而非 update),不在此次修复内。
59
-
60
- ## 改造点
61
-
62
- | 文件 | 改动 |
63
- |---|---|
64
- | `src/core/storage/routing.ts` | `getRecentRoutingEvent(sessionId)` SQL 加 `AND obeyed IS NULL`;或保留旧方法 + 新增 `getRecentPendingRoutingEvent(sessionId)`(推荐后者,向后兼容) |
65
- | `src/daemon/handlers/post-tool-use.ts:33` | 调用新方法 `getRecentPendingRoutingEvent` |
66
- | `src/core/storage/sqlite.ts` | facade 透传新方法 |
67
- | `tests/unit/storage/routing.test.ts`(如缺则新建)| 单测:3 个时序 case |
68
- | `tests/unit/daemon/post-tool-use.test.ts`(如缺则新建)| handler 行为测试 |
69
-
70
- ## 测试策略
71
-
72
- **Storage 单测**(routing.test.ts):
73
- - `getRecentPendingRoutingEvent` 返回最近 `obeyed IS NULL` 的行
74
- - 已存在 obeyed=1 在前 + 新 pending 在后 → 返回新 pending
75
- - 全部 obeyed 已填 → 返回 null(不误返)
76
- - 不同 session 隔离
77
-
78
- **Handler 单测**(post-tool-use.test.ts,新增):
79
- - 时序 case 1(同 prompt 第 2 个 Agent):第 1 个 update 成功,第 2 个找不到 pending → silently skip(assert:原 routing_event 不被二次覆盖)
80
- - 时序 case 2(跨 prompt):每个 prompt 的 Agent 关联到自己的 event
81
- - 时序 case 3(无 routing_event):handler 不抛错
82
-
83
- 不需要集成测试(daemon 端到端已被 daemon 集成测试覆盖)。
84
-
85
- ## 风险与回滚
86
-
87
- - **风险 1**:同 prompt 多 Agent 漏记 → 文档化为已知限制(M7 范围外);后续可改为 PostToolUse insert 新行。
88
- - **风险 2**:旧库残留 obeyed=NULL 的 stale 行可能被新 prompt 的 Agent 错关 → 因为 ORDER BY ts DESC 限制 + session_id 过滤,最多影响"在该 session 内有非常老的孤儿 pending"的极端情况;可接受。
89
- - **回滚**:单 commit revert;新方法可保留无害。
90
-
91
- ## 实施顺序
92
-
93
- 1. routing.ts 新增 `getRecentPendingRoutingEvent`(SQL 加 `AND obeyed IS NULL`)
94
- 2. sqlite.ts facade 透传
95
- 3. routing.test.ts 加单测
96
- 4. post-tool-use.ts 切换调用
97
- 5. post-tool-use.test.ts 加 handler 单测
98
- 6. `npx tsc --noEmit` + 相关 vitest
99
-
100
- ## 命名遵循
101
-
102
- - `getRecentPendingRoutingEvent`(get 前缀,单个资源;与现有 `getRecentRoutingEvent`、`getExperimentAssignment` 对齐)
103
- - 不用 `queryRecentPending*`(query 前缀留给返回行集合的方法)
@@ -1,134 +0,0 @@
1
- # project-path git root 修复 Spec
2
-
3
- ## 目标
4
- 让 5 个 hook 在 IDE 调用时把 `cwd`(可能是任意子目录)上溯为 git 仓库根目录后再发给 daemon,从根上阻止子目录被生成 `.claude-forge/`。
5
-
6
- ## 调研结果
7
-
8
- | 位置 | 现状 | 改造需求 |
9
- |---|---|---|
10
- | `src/hooks/pre-tool-use.sh:15-16` | `PROJECT_PATH=$(jq -r '.cwd'); fallback $PWD` | 套上 `resolve_project_path` |
11
- | `src/hooks/post-tool-use.sh:17-18` | 同上 | 同上 |
12
- | `src/hooks/user-prompt-submit.sh:15-16` | 同上 | 同上 |
13
- | `src/hooks/stop.sh:11-12` | 同上 + 未引用 hook-lib.sh | 先 source hook-lib.sh 再用函数 |
14
- | `src/hooks/notification.sh:13-14` | 同上 | 同上 |
15
- | `src/hooks/hook-lib.sh` | 已有 `send_event_or_enqueue` 公共函数 | **新增 `resolve_project_path`** |
16
- | `src/daemon/handlers/history-exporter.ts:24` | `path.join(project_path,'.claude-forge','history')` | 不动(hook 端已传 git root) |
17
- | `src/cli/commands/executions.ts:16,53,85` | `process.cwd()` 拼 `.claude-forge` | 新增 `resolveGitRoot()` helper |
18
- | `src/templates/template-manager.ts:82,89` | `initProject(_, projectPath)` 由调用方传入 | 调用方传 git root 即可(init CLI 自身改) |
19
-
20
- 观察:`hook-lib.sh` 已存在公共函数集,`stop.sh` 是唯一未 source 它的 hook(手写 nc + socket),改造时顺手补齐一致性。
21
-
22
- ## 方案选择
23
-
24
- | | A. Hook 端解析 git root | B. Daemon 端解析 | C. 完全消除目录 | D. 混合 hash |
25
- |---|---|---|---|---|
26
- | 改动面 | 5 hook + lib + CLI | 1 处 | 涉及多模块迁移 | A+ 存储改造 |
27
- | 性能 | bash 上溯(O(深度),无子进程)| 每次 spawn `git` | 同 A | 同 A |
28
- | 下游受益 | 全部 | 仅 history-exporter | 全部但破坏可见性 | 全部 |
29
- | 老数据 | 兼容(新数据用新值)| 兼容 | 需迁移 | 需迁移 |
30
- | 风险 | 0 测试 hook 改动 | 子进程开销 | discoverability 破坏 | 引入新维度 |
31
-
32
- **推荐 A**:根因解决 + 保留用户在项目根 `ls` 即可看到 history 的可见性 + 不引入子进程开销。bash `while` 上溯零依赖,daemon / CLI 自动受益。
33
-
34
- ## 改造范围(约 70 行)
35
-
36
- | 文件 | 行数 | 说明 |
37
- |---|---|---|
38
- | `src/hooks/hook-lib.sh` | +25 | 新增 `resolve_project_path` |
39
- | `src/hooks/pre-tool-use.sh` | -2 +1 | 替换两行 |
40
- | `src/hooks/post-tool-use.sh` | -2 +1 | 同上 |
41
- | `src/hooks/user-prompt-submit.sh` | -2 +1 | 同上 |
42
- | `src/hooks/stop.sh` | -2 +2 | 先 source hook-lib.sh,再用函数 |
43
- | `src/hooks/notification.sh` | -2 +1 | 同上 |
44
- | `src/cli/commands/executions.ts` | +8 | 新增 `resolveGitRoot()` 替换 3 处 `process.cwd()` |
45
- | `src/cli/commands/init.ts`(调用 template-manager 处,需 grep 确认)| +2 | 把传给 `initProject` 的 `projectPath` 改成 git root |
46
- | 新增 `tests/unit/hooks/resolve-project-path.test.sh`(或 vitest 调 bash)| ~40 | safety-net |
47
- | 新增 `tests/integration/hook-gitroot.integration.test.ts` | ~50 | 端到端 |
48
-
49
- ## hook-lib.sh 公共函数设计
50
-
51
- ```bash
52
- # resolve_project_path <input_cwd>
53
- # 从 input_cwd 上溯查找最近的 .git 目录,输出 git root。
54
- # 非 git 项目 / 上溯到根 / 输入为空 → 回退到 input_cwd(再回退到 $PWD)。
55
- # 防御:最多上溯 64 层,避免符号链接环。
56
- resolve_project_path() {
57
- local dir="${1:-$PWD}"
58
- [ -z "$dir" ] && dir="$PWD"
59
-
60
- # 规整为绝对路径(不依赖 realpath)
61
- case "$dir" in
62
- /*) ;;
63
- *) dir="$PWD/$dir" ;;
64
- esac
65
-
66
- local guard=0
67
- while [ "$dir" != "/" ] && [ "$dir" != "." ] && [ $guard -lt 64 ]; do
68
- if [ -d "$dir/.git" ] || [ -f "$dir/.git" ]; then # 后者兼容 git worktree
69
- printf '%s' "$dir"
70
- return 0
71
- fi
72
- dir=$(dirname "$dir")
73
- guard=$((guard + 1))
74
- done
75
-
76
- # 未找到 → 回退到原 cwd
77
- printf '%s' "${1:-$PWD}"
78
- }
79
- ```
80
-
81
- 调用方一行替换:
82
- ```bash
83
- RAW_CWD=$(echo "$INPUT" | jq -r '.cwd // ""')
84
- PROJECT_PATH=$(resolve_project_path "${RAW_CWD:-$PWD}")
85
- ```
86
-
87
- ## CLI / daemon 端兼容
88
-
89
- **daemon 端**:不改。`history-exporter.ts:24` 信任传入的 `event.project_path`(hook 端已是 git root)。
90
-
91
- **CLI 端 `executions.ts`**:新增 helper(放 `src/core/utils/git.ts`):
92
- ```typescript
93
- export function resolveGitRoot(start = process.cwd()): string {
94
- try {
95
- return execSync('git rev-parse --show-toplevel', { cwd: start, stdio: ['ignore', 'pipe', 'ignore'] })
96
- .toString().trim() || start;
97
- } catch { return start; }
98
- }
99
- ```
100
- 三处 `path.join(process.cwd(), '.claude-forge', ...)` → `path.join(resolveGitRoot(), '.claude-forge', ...)`。
101
-
102
- **template-manager.ts**:函数本身签名不变(接收 `projectPath`),改 init 命令调用侧。
103
-
104
- ## 测试策略
105
-
106
- - **safety-net (单测 bash 函数)**:构造 fixture `/tmp/forge-test/repo/.git/`,对 `resolve_project_path /tmp/forge-test/repo/a/b/c` 断言返回 git root;非 git 目录断言回退;空输入断言回退到 `$PWD`。
107
- - **集成**:vitest 起一个 daemon,构造 `cwd=fixture/sub/dir` 的 INPUT,跑 `pre-tool-use.sh`,从 daemon storage queryEvents 断言 `project_path === fixture` 而非子目录。
108
- - **回归**:现有 daemon 集成测试不需要改(hook 端透明改造)。
109
- - **CLI 端**:单测 `resolveGitRoot()` 在 git 仓 / 非 git 仓两种 cwd 下的返回值。
110
-
111
- ## 风险与回滚
112
-
113
- - **`.git` 是文件(worktree)场景**:`[ -f "$dir/.git" ]` 已兼容。
114
- - **非 git 项目**:fallback 原 cwd,行为不变。
115
- - **monorepo 子模块各自 .git**:返回最近的 git root,符合预期。
116
- - **历史数据**:旧 sessions.project_path 仍是子目录路径,不做迁移;可选清单:列出 sessions 表去重 project_path,提供 `cf admin remap-project-path` 工具(非本次范围)。
117
- - **bash on Linux/macOS 差异**:用 POSIX 内建(`dirname` / `case`),不依赖 `realpath`。
118
- - **回滚**:还原 6 个文件即可,无 schema 变更。
119
-
120
- ## 实施顺序(refactor-safe)
121
-
122
- 1. **safety-net 阶段**:先写 `tests/unit/hooks/resolve-project-path.test.sh`(或 vitest 用 `child_process.execSync('bash -c "source hook-lib.sh && resolve_project_path ..."')`)和 `tests/integration/hook-gitroot.integration.test.ts`(先红)
123
- 2. **lib 阶段**:在 `hook-lib.sh` 新增 `resolve_project_path` → 单测转绿
124
- 3. **hook 改造**:5 个 hook 替换两行;`stop.sh` 同时改为 `source hook-lib.sh`(顺手补一致性)→ 集成测试转绿
125
- 4. **CLI 阶段**:新增 `src/core/utils/git.ts::resolveGitRoot`,改 `executions.ts` 3 处 + `init` 调用侧
126
- 5. **验证**:`npx tsc --noEmit` + `npm test` + 手工到 fixture 子目录跑 `cf executions list` 确认走 git root
127
- 6. **release**:bump patch 版本,changelog 注明"hooks 解析 git root,不再在子目录生成 .claude-forge"
128
-
129
- ## 命名遵循
130
-
131
- - bash 函数:`resolve_project_path`(snake_case,与 hook-lib 现有 `send_event_or_enqueue` / `_enqueue_event_bg` 一致)
132
- - TS 工具函数:`resolveGitRoot`(camelCase,`get` 前缀不适用因为这是计算非查询)
133
- - 新文件:`src/core/utils/git.ts`(kebab 化已为单词,遵循现有 `time.ts` / `session.ts`)
134
- - 测试文件:`tests/unit/hooks/resolve-project-path.test.sh` 或 `.test.ts`、`tests/integration/hook-gitroot.integration.test.ts`