@winspan/claude-forge 8.51.1 → 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 (409) 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 +121 -2
  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/constants.d.ts +2 -0
  11. package/dist/core/constants.d.ts.map +1 -1
  12. package/dist/core/constants.js +4 -0
  13. package/dist/core/constants.js.map +1 -1
  14. package/dist/core/storage/events.d.ts.map +1 -1
  15. package/dist/core/storage/events.js +0 -1
  16. package/dist/core/storage/events.js.map +1 -1
  17. package/dist/core/storage/maintenance.d.ts +25 -3
  18. package/dist/core/storage/maintenance.d.ts.map +1 -1
  19. package/dist/core/storage/maintenance.js +33 -4
  20. package/dist/core/storage/maintenance.js.map +1 -1
  21. package/dist/core/storage/routing.d.ts +4 -0
  22. package/dist/core/storage/routing.d.ts.map +1 -1
  23. package/dist/core/storage/routing.js +10 -4
  24. package/dist/core/storage/routing.js.map +1 -1
  25. package/dist/core/storage/sessions.d.ts +17 -0
  26. package/dist/core/storage/sessions.d.ts.map +1 -1
  27. package/dist/core/storage/sessions.js +64 -0
  28. package/dist/core/storage/sessions.js.map +1 -1
  29. package/dist/core/storage/skills.d.ts +4 -0
  30. package/dist/core/storage/skills.d.ts.map +1 -1
  31. package/dist/core/storage/skills.js +10 -2
  32. package/dist/core/storage/skills.js.map +1 -1
  33. package/dist/core/storage/sqlite.d.ts +5 -0
  34. package/dist/core/storage/sqlite.d.ts.map +1 -1
  35. package/dist/core/storage/sqlite.js +6 -0
  36. package/dist/core/storage/sqlite.js.map +1 -1
  37. package/dist/core/storage/tasks.d.ts.map +1 -1
  38. package/dist/core/storage/tasks.js +2 -0
  39. package/dist/core/storage/tasks.js.map +1 -1
  40. package/dist/core/types.d.ts +7 -0
  41. package/dist/core/types.d.ts.map +1 -1
  42. package/dist/daemon/index.d.ts.map +1 -1
  43. package/dist/daemon/index.js +30 -5
  44. package/dist/daemon/index.js.map +1 -1
  45. package/dist/daemon/skill-sync.d.ts +21 -0
  46. package/dist/daemon/skill-sync.d.ts.map +1 -0
  47. package/dist/daemon/skill-sync.js +75 -0
  48. package/dist/daemon/skill-sync.js.map +1 -0
  49. package/dist/hooks/notification.sh +1 -1
  50. package/dist/hooks/post-tool-use.sh +1 -1
  51. package/dist/hooks/pre-tool-use.sh +1 -1
  52. package/dist/hooks/stop.sh +1 -1
  53. package/dist/hooks/user-prompt-submit.sh +1 -1
  54. package/dist/skills/official/code-simplifier.md +37 -1
  55. package/dist/skills/official/find-skills.md +120 -1
  56. package/dist/skills/official/official-api-design.md +14 -1
  57. package/dist/skills/official/official-architecture-decision.md +22 -1
  58. package/dist/skills/official/official-db-schema-design.md +19 -1
  59. package/dist/skills/official/official-debug.md +9 -1
  60. package/dist/skills/official/official-pr-review.md +1 -1
  61. package/dist/skills/official/official-security-hardening.md +7 -1
  62. package/dist/skills/official/planning-with-files.md +206 -2
  63. package/dist/skills/official/ui-ux-pro-max.md +88 -1
  64. package/dist/skills/official/webapp-testing.md +85 -1
  65. package/dist/skills/registry.d.ts +1 -1
  66. package/dist/skills/registry.d.ts.map +1 -1
  67. package/dist/skills/registry.js +15 -4
  68. package/dist/skills/registry.js.map +1 -1
  69. package/dist/skills/semantic-matcher.d.ts +4 -3
  70. package/dist/skills/semantic-matcher.d.ts.map +1 -1
  71. package/dist/skills/semantic-matcher.js +20 -22
  72. package/dist/skills/semantic-matcher.js.map +1 -1
  73. package/dist/skills/upgrade-engine.d.ts +93 -0
  74. package/dist/skills/upgrade-engine.d.ts.map +1 -0
  75. package/dist/skills/upgrade-engine.js +447 -0
  76. package/dist/skills/upgrade-engine.js.map +1 -0
  77. package/dist/skills/upgrade-prompt.d.ts +20 -0
  78. package/dist/skills/upgrade-prompt.d.ts.map +1 -0
  79. package/dist/skills/upgrade-prompt.js +75 -0
  80. package/dist/skills/upgrade-prompt.js.map +1 -0
  81. package/dist/web/analytics/weekly-report.d.ts.map +1 -1
  82. package/dist/web/analytics/weekly-report.js +21 -29
  83. package/dist/web/analytics/weekly-report.js.map +1 -1
  84. package/dist/web/routes/patch.d.ts.map +1 -1
  85. package/dist/web/routes/patch.js +32 -2
  86. package/dist/web/routes/patch.js.map +1 -1
  87. package/dist/web/routes/sessions.d.ts.map +1 -1
  88. package/dist/web/routes/sessions.js +9 -7
  89. package/dist/web/routes/sessions.js.map +1 -1
  90. package/dist/web/routes/trace.d.ts.map +1 -1
  91. package/dist/web/routes/trace.js +2 -3
  92. package/dist/web/routes/trace.js.map +1 -1
  93. package/dist/web/server.d.ts.map +1 -1
  94. package/dist/web/server.js +3 -2
  95. package/dist/web/server.js.map +1 -1
  96. package/package.json +12 -2
  97. package/scripts/postinstall.cjs +21 -0
  98. package/.claude/CLAUDE.md +0 -17
  99. package/.eslintrc.js +0 -23
  100. package/.prettierrc +0 -8
  101. package/ARCHITECTURE_ISSUES.md +0 -249
  102. package/CLAUDE.md +0 -265
  103. package/CLAUDE.md.backup +0 -488
  104. package/docs/concurrent-agents.md +0 -129
  105. package/docs/design/architecture-review-20260516.md +0 -232
  106. package/docs/design/fix-skills-data-and-set-leak-spec-20260516-1300.md +0 -219
  107. package/docs/design/h1-storage-aggregation-spec-20260518-1121.md +0 -299
  108. package/docs/design/h2-getdatabase-encapsulation-spec-20260518-1450.md +0 -191
  109. package/docs/design/h3-fallback-removal-spec-20260518-1245.md +0 -76
  110. package/docs/design/h4-index-dedup-spec-20260518-1230.md +0 -109
  111. package/docs/design/h6-services-migration-spec-20260518-1355.md +0 -82
  112. package/docs/design/hook-failure-queue-spec-20260516-1530.md +0 -204
  113. package/docs/design/l1-swarm-protocol-extract-spec-20260518-1605.md +0 -106
  114. package/docs/design/m10-forge-paths-spec-20260518-1320.md +0 -121
  115. package/docs/design/m2-m3-tool-input-spec-20260518-1425.md +0 -131
  116. package/docs/design/m7-routing-event-association-spec-20260518-1545.md +0 -103
  117. package/docs/design/project-path-gitroot-spec-20260518-1715.md +0 -134
  118. package/docs/design/refactor-phase1-spec-20260515-1600.md +0 -543
  119. package/docs/design/refactor-phase2-spec-20260515-1700.md +0 -424
  120. package/docs/design/task-active-gc-spec-20260518-1745.md +0 -146
  121. package/docs/design/tasks-list-filter-pagination-spec-20260518-0930.md +0 -208
  122. package/docs/implementation/fix-skills-data-and-set-leak-changelog-20260516-1300.md +0 -104
  123. package/docs/implementation/h1-storage-aggregation-changelog-20260518-1121.md +0 -82
  124. package/docs/implementation/h2-final-changelog-20260518-1530.md +0 -61
  125. package/docs/implementation/h2-phase1-safety-net-changelog-20260518-1450.md +0 -70
  126. package/docs/implementation/h2-phase2-operations-changelog-20260518-1450.md +0 -120
  127. package/docs/implementation/h2-phase3-callsites-changelog-20260518-1450.md +0 -71
  128. package/docs/implementation/h3-fallback-removal-changelog-20260518-1245.md +0 -71
  129. package/docs/implementation/h4-index-dedup-changelog-20260518-1230.md +0 -60
  130. package/docs/implementation/h6-services-migration-changelog-20260518-1355.md +0 -46
  131. package/docs/implementation/h7-m9-defaults-changelog-20260518-1300.md +0 -46
  132. package/docs/implementation/hook-failure-queue-changelog-20260516-1530.md +0 -196
  133. package/docs/implementation/hotfix-daemon-event-reject-20260516-1430.md +0 -56
  134. package/docs/implementation/l1-swarm-protocol-extract-changelog-20260518-1605.md +0 -45
  135. package/docs/implementation/l3-l4-daemon-perf-changelog-20260518-1410.md +0 -63
  136. package/docs/implementation/l6-l8-final-cleanup-changelog-20260518-1640.md +0 -38
  137. package/docs/implementation/m1-m4-m5-l7-cleanup-changelog-20260518-1310.md +0 -58
  138. package/docs/implementation/m10-forge-paths-changelog-20260518-1320.md +0 -60
  139. package/docs/implementation/m2-m3-tool-input-changelog-20260518-1425.md +0 -43
  140. package/docs/implementation/m6-m8-naming-shutdown-changelog-20260518-1340.md +0 -56
  141. package/docs/implementation/m7-routing-association-changelog-20260518-1545.md +0 -69
  142. package/docs/implementation/project-path-gitroot-changelog-20260518-1715.md +0 -63
  143. package/docs/implementation/refactor-phase1-changelog-20260515-1630.md +0 -354
  144. package/docs/implementation/refactor-phase2-changelog-20260515-1705.md +0 -421
  145. package/docs/implementation/task-active-gc-changelog-20260518-1745.md +0 -35
  146. package/docs/implementation/task-title-summary-changelog-20260518-1130.md +0 -39
  147. package/docs/implementation/tasks-detail-back-loses-filters-changelog-20260518-1100.md +0 -22
  148. package/docs/implementation/tasks-list-filter-pagination-changelog-20260518-0930.md +0 -72
  149. package/docs/implementation/tasks-page-white-screen-hotfix-changelog-20260518-1015.md +0 -56
  150. package/docs/reviews/claudemd-template-sync.md +0 -54
  151. package/docs/reviews/task-title-summary.md +0 -92
  152. package/docs/reviews/tasks-detail-back-loses-filters.md +0 -58
  153. package/docs/reviews/tasks-filter-pagination.md +0 -80
  154. package/docs/reviews/tasks-page-white-screen-hotfix.md +0 -126
  155. package/docs/ruflo-learning-strategy.md +0 -322
  156. package/docs/skills-deduplication-analysis.md +0 -83
  157. package/docs/skills-multiformat-support.md +0 -177
  158. package/docs/skills-third-party.md +0 -183
  159. package/docs/testing/tasks-filter-pagination-test-report.md +0 -86
  160. package/forge +0 -321
  161. package/playwright.config.ts +0 -40
  162. package/scripts/demo-v2.ts +0 -91
  163. package/scripts/dev-daemon.sh +0 -232
  164. package/scripts/dev-web.ts +0 -109
  165. package/scripts/e2e-mcp-link.ts +0 -423
  166. package/scripts/e2e-methodology-quality.ts +0 -253
  167. package/scripts/e2e-routing.ts +0 -456
  168. package/scripts/e2e-user-methodology.ts +0 -326
  169. package/scripts/e2e-web-workflows.ts +0 -299
  170. package/scripts/migrate-legacy-to-dynamic.sql +0 -108
  171. package/scripts/regenerate-execution-docs.ts +0 -116
  172. package/scripts/sync-agent-skills.ts +0 -193
  173. package/scripts/test-hook.sh +0 -71
  174. package/scripts/verify-skill-loading.ts +0 -62
  175. package/src/claudemd/claudemd-generator.ts +0 -568
  176. package/src/claudemd/convention-extractor.ts +0 -69
  177. package/src/claudemd/index.ts +0 -35
  178. package/src/claudemd/persona-manager.ts +0 -88
  179. package/src/claudemd/resume-manager.ts +0 -236
  180. package/src/claudemd/tech-detector.ts +0 -220
  181. package/src/claudemd/templates/swarm-protocol.md +0 -222
  182. package/src/cli/commands/claudemd.ts +0 -84
  183. package/src/cli/commands/config.ts +0 -46
  184. package/src/cli/commands/daemon.ts +0 -310
  185. package/src/cli/commands/executions.ts +0 -115
  186. package/src/cli/commands/init.ts +0 -204
  187. package/src/cli/commands/logs.ts +0 -181
  188. package/src/cli/commands/mcp.ts +0 -242
  189. package/src/cli/commands/menu.ts +0 -357
  190. package/src/cli/commands/skills.ts +0 -185
  191. package/src/cli/commands/stats.ts +0 -73
  192. package/src/cli/commands/status.ts +0 -69
  193. package/src/cli/commands/template.ts +0 -77
  194. package/src/cli/commands/trace.ts +0 -148
  195. package/src/cli/index.ts +0 -42
  196. package/src/cli/init/hook-manager.ts +0 -132
  197. package/src/core/ai/provider.ts +0 -308
  198. package/src/core/ai/types.ts +0 -51
  199. package/src/core/config.ts +0 -124
  200. package/src/core/constants.ts +0 -62
  201. package/src/core/event-fields.ts +0 -32
  202. package/src/core/queue/index.ts +0 -192
  203. package/src/core/storage/base.ts +0 -302
  204. package/src/core/storage/events.ts +0 -434
  205. package/src/core/storage/injections.ts +0 -78
  206. package/src/core/storage/maintenance.ts +0 -59
  207. package/src/core/storage/migrations/002_add_skill_tracking.sql +0 -6
  208. package/src/core/storage/migrations/003_add_skill_invocations.sql +0 -23
  209. package/src/core/storage/performance-indexes.sql +0 -23
  210. package/src/core/storage/routing.ts +0 -322
  211. package/src/core/storage/rows.ts +0 -112
  212. package/src/core/storage/schema.sql +0 -224
  213. package/src/core/storage/sessions.ts +0 -168
  214. package/src/core/storage/skills.ts +0 -233
  215. package/src/core/storage/sqlite.ts +0 -293
  216. package/src/core/storage/tasks.ts +0 -318
  217. package/src/core/storage/token-usage.ts +0 -93
  218. package/src/core/types.ts +0 -181
  219. package/src/core/utils/error-handler.ts +0 -257
  220. package/src/core/utils/forge-resume-block.ts +0 -74
  221. package/src/core/utils/format.ts +0 -69
  222. package/src/core/utils/git.ts +0 -23
  223. package/src/core/utils/logger.ts +0 -134
  224. package/src/core/utils/lru-cache.ts +0 -54
  225. package/src/core/utils/path.ts +0 -19
  226. package/src/core/utils/session.ts +0 -26
  227. package/src/core/utils/time.ts +0 -37
  228. package/src/core/utils/token-tracker.ts +0 -97
  229. package/src/daemon/event-parser.ts +0 -36
  230. package/src/daemon/handlers/history-exporter.ts +0 -117
  231. package/src/daemon/handlers/post-tool-use.ts +0 -54
  232. package/src/daemon/handlers/stop.ts +0 -208
  233. package/src/daemon/handlers/user-prompt.ts +0 -178
  234. package/src/daemon/hook-sync.ts +0 -91
  235. package/src/daemon/index.ts +0 -302
  236. package/src/daemon/launchd/com.claude-forge.daemon.plist.template +0 -47
  237. package/src/daemon/launchd-installer.ts +0 -260
  238. package/src/daemon/lifecycle.ts +0 -128
  239. package/src/daemon/router.ts +0 -40
  240. package/src/daemon/server.ts +0 -196
  241. package/src/daemon/services/task-segmenter.ts +0 -112
  242. package/src/hooks/hook-lib.sh +0 -118
  243. package/src/hooks/notification.sh +0 -35
  244. package/src/hooks/post-tool-use.sh +0 -61
  245. package/src/hooks/pre-tool-use.sh +0 -63
  246. package/src/hooks/stop.sh +0 -43
  247. package/src/hooks/user-prompt-submit.sh +0 -69
  248. package/src/mcp/server.ts +0 -322
  249. package/src/skills/index.ts +0 -2
  250. package/src/skills/invocation-guard.ts +0 -177
  251. package/src/skills/matcher.ts +0 -148
  252. package/src/skills/official/code-simplifier.md +0 -16
  253. package/src/skills/official/find-skills.md +0 -23
  254. package/src/skills/official/official-api-design.md +0 -17
  255. package/src/skills/official/official-architecture-decision.md +0 -20
  256. package/src/skills/official/official-bmad.md +0 -118
  257. package/src/skills/official/official-db-schema-design.md +0 -16
  258. package/src/skills/official/official-debug.md +0 -17
  259. package/src/skills/official/official-doc-driven.md +0 -31
  260. package/src/skills/official/official-harness-engineering.md +0 -108
  261. package/src/skills/official/official-performance-optimization.md +0 -30
  262. package/src/skills/official/official-pr-review.md +0 -35
  263. package/src/skills/official/official-release-checklist.md +0 -30
  264. package/src/skills/official/official-security-hardening.md +0 -26
  265. package/src/skills/official/official-spec-driven-design.md +0 -31
  266. package/src/skills/official/planning-with-files.md +0 -37
  267. package/src/skills/official/ui-ux-pro-max.md +0 -18
  268. package/src/skills/official/webapp-testing.md +0 -12
  269. package/src/skills/official-skills.ts +0 -89
  270. package/src/skills/registry.ts +0 -355
  271. package/src/skills/semantic-matcher.ts +0 -231
  272. package/src/skills/tools/pipeline-suggest.ts +0 -226
  273. package/src/skills/tools/skill-invoke.ts +0 -168
  274. package/src/skills/tools/skill-list.ts +0 -59
  275. package/src/templates/go.yaml +0 -53
  276. package/src/templates/python.yaml +0 -59
  277. package/src/templates/react.yaml +0 -55
  278. package/src/templates/template-manager.ts +0 -170
  279. package/src/web/analytics/anti-pattern-detector.ts +0 -367
  280. package/src/web/analytics/drift-detector.ts +0 -219
  281. package/src/web/analytics/weekly-report.ts +0 -431
  282. package/src/web/auth-middleware.ts +0 -54
  283. package/src/web/routes/_helpers.ts +0 -34
  284. package/src/web/routes/ai.ts +0 -204
  285. package/src/web/routes/auth.ts +0 -22
  286. package/src/web/routes/drift.ts +0 -25
  287. package/src/web/routes/error-handler.ts +0 -120
  288. package/src/web/routes/events.ts +0 -47
  289. package/src/web/routes/insights.ts +0 -43
  290. package/src/web/routes/patch.ts +0 -117
  291. package/src/web/routes/reports.ts +0 -34
  292. package/src/web/routes/rules.ts +0 -76
  293. package/src/web/routes/sessions.ts +0 -250
  294. package/src/web/routes/skill-stats.ts +0 -92
  295. package/src/web/routes/skills.ts +0 -350
  296. package/src/web/routes/static.ts +0 -67
  297. package/src/web/routes/stats.ts +0 -50
  298. package/src/web/routes/status.ts +0 -30
  299. package/src/web/routes/tasks.ts +0 -193
  300. package/src/web/routes/token-usage.ts +0 -20
  301. package/src/web/routes/trace.ts +0 -126
  302. package/src/web/routes/types.ts +0 -57
  303. package/src/web/server.ts +0 -134
  304. package/src/web/ssrf-guard.ts +0 -112
  305. package/src/web/static/index.html +0 -3251
  306. package/src/web/static/vendor/chart.umd.min.js +0 -20
  307. package/tests/e2e/dashboard.spec.ts +0 -205
  308. package/tests/e2e/routing-skill-e2e.test.ts +0 -39
  309. package/tests/helpers/mock-ai.ts +0 -92
  310. package/tests/helpers/mock-storage.ts +0 -159
  311. package/tests/integration/claudemd-generator.test.ts +0 -90
  312. package/tests/integration/queue-replay.integration.test.ts +0 -193
  313. package/tests/integration/tasks-filter.integration.test.ts +0 -154
  314. package/tests/integration/web-analytics.integration.test.ts +0 -133
  315. package/tests/integration/web-stats.integration.test.ts +0 -135
  316. package/tests/integration/web-trace.integration.test.ts +0 -175
  317. package/tests/performance/database.benchmark.ts +0 -161
  318. package/tests/semantic-matcher.test.ts +0 -99
  319. package/tests/skill-matcher.test.ts +0 -110
  320. package/tests/unit/ai-provider-retry.test.ts +0 -194
  321. package/tests/unit/ai-provider-vision.test.ts +0 -224
  322. package/tests/unit/claudemd-generator.test.ts +0 -68
  323. package/tests/unit/cli-mcp.test.ts +0 -141
  324. package/tests/unit/core/forge-paths.test.ts +0 -99
  325. package/tests/unit/daemon/hook-sync.test.ts +0 -71
  326. package/tests/unit/daemon/post-tool-use.test.ts +0 -121
  327. package/tests/unit/daemon/stop-handler-behavior-summary.test.ts +0 -202
  328. package/tests/unit/daemon/task-segmenter-recover.test.ts +0 -84
  329. package/tests/unit/event-fields.test.ts +0 -88
  330. package/tests/unit/event-parser.test.ts +0 -55
  331. package/tests/unit/handlers.test.ts +0 -171
  332. package/tests/unit/hooks/resolve-project-path.test.ts +0 -122
  333. package/tests/unit/invocation-guard.test.ts +0 -125
  334. package/tests/unit/queue.test.ts +0 -272
  335. package/tests/unit/router.test.ts +0 -138
  336. package/tests/unit/security.test.ts +0 -128
  337. package/tests/unit/skill-invocations-workflow.test.ts +0 -495
  338. package/tests/unit/skill-registry.test.ts +0 -94
  339. package/tests/unit/skills/invocation-guard-ttl.test.ts +0 -211
  340. package/tests/unit/skills/official-skills-loader.test.ts +0 -126
  341. package/tests/unit/skills/registry-multiformat.test.ts +0 -92
  342. package/tests/unit/socket-server.test.ts +0 -183
  343. package/tests/unit/storage/event-operations-aggregates.test.ts +0 -342
  344. package/tests/unit/storage/migration-idempotent.test.ts +0 -304
  345. package/tests/unit/storage/routing-aggregates.test.ts +0 -276
  346. package/tests/unit/storage/routing.test.ts +0 -117
  347. package/tests/unit/storage/schema-missing.test.ts +0 -81
  348. package/tests/unit/storage/session-operations-aggregates.test.ts +0 -120
  349. package/tests/unit/storage/sessions-aggregate.test.ts +0 -435
  350. package/tests/unit/storage/skill-operations-counts.test.ts +0 -106
  351. package/tests/unit/storage/skills-aggregates.test.ts +0 -104
  352. package/tests/unit/storage/sqlite-refactor-harness.test.ts +0 -314
  353. package/tests/unit/storage/task-operations-counts.test.ts +0 -46
  354. package/tests/unit/storage/tasks-getById.test.ts +0 -343
  355. package/tests/unit/storage/tasks-stale-gc.test.ts +0 -86
  356. package/tests/unit/storage.test.ts +0 -172
  357. package/tests/unit/token-usage.test.ts +0 -144
  358. package/tests/unit/type-guards.test.ts +0 -201
  359. package/tests/unit/utils/format.test.ts +0 -189
  360. package/tests/unit/utils/session.test.ts +0 -89
  361. package/tests/unit/utils/time.test.ts +0 -112
  362. package/tests/unit/web/navigation-back-contract.test.ts +0 -134
  363. package/tests/unit/web/routes-auth.test.ts +0 -93
  364. package/tests/unit/web/routes-events.test.ts +0 -101
  365. package/tests/unit/web/routes-rules.test.ts +0 -182
  366. package/tests/unit/web/routes-sessions.test.ts +0 -181
  367. package/tests/unit/web/routes-skill-stats.test.ts +0 -179
  368. package/tests/unit/web/routes-stats.test.ts +0 -92
  369. package/tests/unit/web/routes-tasks.test.ts +0 -385
  370. package/tests/unit/web/task-title-contract.test.ts +0 -210
  371. package/tests/unit/web/tasks-component-contract.test.ts +0 -179
  372. package/tsconfig.json +0 -22
  373. package/vitest.config.ts +0 -21
  374. package/vitest.integration.config.ts +0 -16
  375. package/web/CLAUDE.md +0 -20
  376. package/web/index.html +0 -13
  377. package/web/package-lock.json +0 -4854
  378. package/web/package.json +0 -35
  379. package/web/postcss.config.js +0 -6
  380. package/web/src/App.tsx +0 -110
  381. package/web/src/components/CodeBlock.tsx +0 -31
  382. package/web/src/components/Confirm.tsx +0 -96
  383. package/web/src/components/Drawer.tsx +0 -60
  384. package/web/src/components/Layout.tsx +0 -145
  385. package/web/src/components/MarkdownRenderer.tsx +0 -77
  386. package/web/src/components/SearchInput.tsx +0 -31
  387. package/web/src/components/SessionDetailContent.tsx +0 -157
  388. package/web/src/components/Toast.tsx +0 -92
  389. package/web/src/index.css +0 -19
  390. package/web/src/main.tsx +0 -31
  391. package/web/src/pages/AIConfig.tsx +0 -233
  392. package/web/src/pages/Dashboard.tsx +0 -572
  393. package/web/src/pages/Events.tsx +0 -271
  394. package/web/src/pages/Reports.tsx +0 -428
  395. package/web/src/pages/SessionDetail.tsx +0 -162
  396. package/web/src/pages/Sessions.tsx +0 -205
  397. package/web/src/pages/Skills.tsx +0 -180
  398. package/web/src/pages/TaskDetail.tsx +0 -515
  399. package/web/src/pages/Tasks.tsx +0 -415
  400. package/web/src/utils/auth.ts +0 -59
  401. package/web/src/utils/export.ts +0 -54
  402. package/web/src/utils/navigation.ts +0 -25
  403. package/web/src/utils/task-title.ts +0 -49
  404. package/web/src/utils/time.ts +0 -13
  405. package/web/tailwind.config.js +0 -11
  406. package/web/tsconfig.json +0 -21
  407. package/web/tsconfig.node.json +0 -10
  408. package/web/vite.config.ts +0 -76
  409. package/winspan-claude-forge-8.43.0.tgz +0 -0
@@ -1,86 +0,0 @@
1
- /**
2
- * 单测:completeStaleActiveTasks
3
- *
4
- * 覆盖:
5
- * - 空表返回 0
6
- * - 1 idle 超阈值 + 1 未超:只关超的那条
7
- * - status='completed' 的 task 不被改动
8
- * - end_time IS NULL 的 task 不被纳入 GC
9
- */
10
-
11
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
12
- import { mkdtempSync, rmSync } from 'node:fs';
13
- import { tmpdir } from 'node:os';
14
- import { join } from 'node:path';
15
- import { SQLiteStorage } from '../../../src/core/storage/sqlite.js';
16
-
17
- const SESSION = 'sess-gc-test';
18
-
19
- function openStorage(tmp: string): SQLiteStorage {
20
- return new SQLiteStorage(join(tmp, 'data.db'));
21
- }
22
-
23
- describe('completeStaleActiveTasks', () => {
24
- let tmp: string;
25
- let storage: SQLiteStorage;
26
-
27
- beforeEach(() => {
28
- tmp = mkdtempSync(join(tmpdir(), 'forge-stale-gc-'));
29
- storage = openStorage(tmp);
30
- });
31
-
32
- afterEach(() => {
33
- try { storage.close(); } catch { /* ignore */ }
34
- rmSync(tmp, { recursive: true, force: true });
35
- });
36
-
37
- it('空表返回 0', () => {
38
- expect(storage.completeStaleActiveTasks(10)).toBe(0);
39
- });
40
-
41
- it('1 idle 超阈值 + 1 未超:只关超的那条', () => {
42
- // 写 2 条 active task
43
- storage.writeTask({ id: 'old-task', session_id: SESSION, title: 'old', start_time: '2026-01-01T00:00:00.000Z' });
44
- storage.writeTask({ id: 'new-task', session_id: SESSION, title: 'new', start_time: '2026-01-01T01:00:00.000Z' });
45
-
46
- // 用 DB 直接操作设置 end_time,让 old-task idle 15 分钟前,new-task 仅 3 分钟前
47
- const db = storage.getDatabase();
48
- db.prepare(`UPDATE tasks SET end_time = datetime('now', '-15 minutes') WHERE id = ?`).run('old-task');
49
- db.prepare(`UPDATE tasks SET end_time = datetime('now', '-3 minutes') WHERE id = ?`).run('new-task');
50
-
51
- const changed = storage.completeStaleActiveTasks(10);
52
- expect(changed).toBe(1);
53
-
54
- const oldTask = storage.getTask('old-task');
55
- expect(oldTask?.status).toBe('completed');
56
-
57
- const newTask = storage.getTask('new-task');
58
- expect(newTask?.status).toBe('active');
59
- });
60
-
61
- it('status=completed 的 task 不被改动', () => {
62
- storage.writeTask({ id: 'done-task', session_id: SESSION, title: 'done', start_time: '2026-01-01T00:00:00.000Z' });
63
- storage.updateTask('done-task', { status: 'completed' });
64
-
65
- // 设置很久以前的 end_time
66
- const db = storage.getDatabase();
67
- db.prepare(`UPDATE tasks SET end_time = datetime('now', '-60 minutes') WHERE id = ?`).run('done-task');
68
-
69
- const changed = storage.completeStaleActiveTasks(10);
70
- expect(changed).toBe(0);
71
-
72
- const task = storage.getTask('done-task');
73
- expect(task?.status).toBe('completed');
74
- });
75
-
76
- it('end_time IS NULL 的 task 不被纳入 GC', () => {
77
- // 写 active task,end_time 保持 NULL(从未 linkEventToTask)
78
- storage.writeTask({ id: 'null-end', session_id: SESSION, title: 'null-end', start_time: '2026-01-01T00:00:00.000Z' });
79
-
80
- const changed = storage.completeStaleActiveTasks(10);
81
- expect(changed).toBe(0);
82
-
83
- const task = storage.getTask('null-end');
84
- expect(task?.status).toBe('active');
85
- });
86
- });
@@ -1,172 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { SQLiteStorage } from '../../src/core/storage/sqlite.js';
3
- import type { ForgeEvent } from '../../src/core/types.js';
4
- import { mkdtempSync, rmSync } from 'node:fs';
5
- import { tmpdir } from 'node:os';
6
- import { join } from 'node:path';
7
-
8
- describe('SQLiteStorage', () => {
9
- let storage: SQLiteStorage;
10
- let tempDir: string;
11
- let dbPath: string;
12
-
13
- beforeEach(() => {
14
- tempDir = mkdtempSync(join(tmpdir(), 'forge-test-'));
15
- dbPath = join(tempDir, 'test.db');
16
- storage = new SQLiteStorage(dbPath);
17
- });
18
-
19
- afterEach(() => {
20
- storage.close();
21
- rmSync(tempDir, { recursive: true, force: true });
22
- });
23
-
24
- describe('writeEvent', () => {
25
- it('stores an event', () => {
26
- const event: ForgeEvent = {
27
- session_id: 'test-session',
28
- project_path: '/test/project',
29
- timestamp: new Date().toISOString(),
30
- hook_type: 'PreToolUse',
31
- tool_name: 'Bash',
32
- tool_input: { command: 'ls' },
33
- };
34
-
35
- storage.writeEvent(event);
36
-
37
- const events = storage.queryEvents({ session_id: 'test-session' });
38
- expect(events).toHaveLength(1);
39
- expect(events[0].tool_name).toBe('Bash');
40
- });
41
- });
42
-
43
- describe('queryEvents', () => {
44
- beforeEach(() => {
45
- storage.writeEvent({
46
- session_id: 'session-1',
47
- project_path: '/project-a',
48
- timestamp: new Date().toISOString(),
49
- hook_type: 'PreToolUse',
50
- });
51
- storage.writeEvent({
52
- session_id: 'session-2',
53
- project_path: '/project-a',
54
- timestamp: new Date().toISOString(),
55
- hook_type: 'PostToolUse',
56
- });
57
- });
58
-
59
- it('retrieves events by session_id', () => {
60
- const events = storage.queryEvents({ session_id: 'session-1' });
61
- expect(events).toHaveLength(1);
62
- expect(events[0].session_id).toBe('session-1');
63
- });
64
-
65
- it('retrieves events by project_path', () => {
66
- const events = storage.queryEvents({ project_path: '/project-a' });
67
- expect(events).toHaveLength(2);
68
- });
69
- });
70
-
71
- describe('countEvents', () => {
72
- it('counts total events', () => {
73
- storage.writeEvent({
74
- session_id: 'test',
75
- project_path: '/test',
76
- timestamp: new Date().toISOString(),
77
- hook_type: 'PreToolUse',
78
- });
79
- expect(storage.countEvents({})).toBe(1);
80
- });
81
- });
82
-
83
- describe('searchEvents', () => {
84
- beforeEach(() => {
85
- storage.writeEvent({
86
- session_id: 'search-session',
87
- project_path: '/test',
88
- timestamp: new Date().toISOString(),
89
- hook_type: 'UserPromptSubmit',
90
- user_prompt: 'fix the authentication bug',
91
- });
92
- storage.writeEvent({
93
- session_id: 'search-session',
94
- project_path: '/test',
95
- timestamp: new Date().toISOString(),
96
- hook_type: 'UserPromptSubmit',
97
- user_prompt: 'add new feature',
98
- });
99
- });
100
-
101
- it('should search events by query string', () => {
102
- const events = storage.searchEvents({
103
- session_id: 'search-session',
104
- query: 'authentication',
105
- });
106
- expect(events).toHaveLength(1);
107
- expect(events[0].user_prompt).toContain('authentication');
108
- });
109
-
110
- it('should return empty array when no match', () => {
111
- const events = storage.searchEvents({
112
- session_id: 'search-session',
113
- query: 'nonexistent',
114
- });
115
- expect(events).toHaveLength(0);
116
- });
117
- });
118
-
119
- describe('session management', () => {
120
- it('should create session from events', () => {
121
- storage.writeEvent({
122
- session_id: 'new-session',
123
- project_path: '/test',
124
- timestamp: new Date().toISOString(),
125
- hook_type: 'UserPromptSubmit',
126
- user_prompt: 'first prompt',
127
- });
128
-
129
- const sessions = storage.querySessions({ limit: 10 });
130
- const session = sessions.find(s => s.session_id === 'new-session');
131
- expect(session).toBeDefined();
132
- expect(session?.first_prompt).toContain('first prompt');
133
- });
134
-
135
- it('should update session event count', () => {
136
- storage.writeEvent({
137
- session_id: 'count-session',
138
- project_path: '/test',
139
- timestamp: new Date().toISOString(),
140
- hook_type: 'UserPromptSubmit',
141
- });
142
- storage.writeEvent({
143
- session_id: 'count-session',
144
- project_path: '/test',
145
- timestamp: new Date().toISOString(),
146
- hook_type: 'PreToolUse',
147
- });
148
-
149
- const sessions = storage.querySessions({ limit: 10 });
150
- const session = sessions.find(s => s.session_id === 'count-session');
151
- expect(session?.event_count).toBeGreaterThanOrEqual(2);
152
- });
153
- });
154
-
155
- describe('error handling', () => {
156
- it('should handle invalid event data gracefully', () => {
157
- const invalidEvent = {
158
- session_id: '',
159
- project_path: '/test',
160
- timestamp: 'invalid-timestamp',
161
- hook_type: 'InvalidType',
162
- } as unknown as ForgeEvent;
163
-
164
- expect(() => storage.writeEvent(invalidEvent)).toThrow();
165
- });
166
-
167
- it('should handle database query errors', () => {
168
- storage.close();
169
- expect(() => storage.queryEvents({ session_id: 'test' })).toThrow();
170
- });
171
- });
172
- });
@@ -1,144 +0,0 @@
1
- /**
2
- * Token usage tracking tests
3
- */
4
-
5
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
6
- import { SQLiteStorage } from '../../src/core/storage/sqlite.js';
7
- import { TokenTracker } from '../../src/core/utils/token-tracker.js';
8
- import { mkdtempSync, rmSync } from 'node:fs';
9
- import { tmpdir } from 'node:os';
10
- import { join } from 'node:path';
11
-
12
- describe('Token Usage Tracking', () => {
13
- let storage: SQLiteStorage;
14
- let tracker: TokenTracker;
15
- let tempDir: string;
16
-
17
- beforeEach(() => {
18
- tempDir = mkdtempSync(join(tmpdir(), 'forge-test-'));
19
- storage = new SQLiteStorage(join(tempDir, 'test.db'));
20
- tracker = new TokenTracker(storage, {
21
- budgetPerSession: 10000,
22
- warningThreshold: 0.8,
23
- });
24
- });
25
-
26
- afterEach(() => {
27
- storage.close();
28
- rmSync(tempDir, { recursive: true, force: true });
29
- });
30
-
31
- it('should record token usage', () => {
32
- storage.writeTokenUsage({
33
- session_id: 'test-session-1',
34
- input_tokens: 100,
35
- output_tokens: 200,
36
- model: 'claude-opus-4-7',
37
- tool_name: 'Task',
38
- });
39
-
40
- const usage = storage.getTokenUsageBySession('test-session-1');
41
- expect(usage.input_tokens).toBe(100);
42
- expect(usage.output_tokens).toBe(200);
43
- expect(usage.total_tokens).toBe(300);
44
- });
45
-
46
- it('should accumulate token usage across multiple calls', () => {
47
- const sessionId = 'test-session-2';
48
-
49
- storage.writeTokenUsage({
50
- session_id: sessionId,
51
- input_tokens: 100,
52
- output_tokens: 200,
53
- });
54
-
55
- storage.writeTokenUsage({
56
- session_id: sessionId,
57
- input_tokens: 50,
58
- output_tokens: 100,
59
- });
60
-
61
- const usage = storage.getTokenUsageBySession(sessionId);
62
- expect(usage.input_tokens).toBe(150);
63
- expect(usage.output_tokens).toBe(300);
64
- expect(usage.total_tokens).toBe(450);
65
- });
66
-
67
- it('should list token usage records', () => {
68
- const sessionId = 'test-session-4';
69
-
70
- storage.writeTokenUsage({
71
- session_id: sessionId,
72
- input_tokens: 100,
73
- output_tokens: 200,
74
- model: 'claude-opus-4-7',
75
- tool_name: 'Task',
76
- });
77
-
78
- storage.writeTokenUsage({
79
- session_id: sessionId,
80
- input_tokens: 50,
81
- output_tokens: 100,
82
- model: 'claude-sonnet-4',
83
- tool_name: 'classify',
84
- });
85
-
86
- const records = storage.listTokenUsage({ session_id: sessionId });
87
- expect(records).toHaveLength(2);
88
- // Verify both records exist (order may vary due to timestamp precision)
89
- const toolNames = records.map(r => r.tool_name);
90
- expect(toolNames).toContain('Task');
91
- expect(toolNames).toContain('classify');
92
- });
93
-
94
- it('should handle token tracker recording', () => {
95
- const sessionId = 'test-session-5';
96
-
97
- tracker.record({
98
- session_id: sessionId,
99
- usage: { input_tokens: 100, output_tokens: 200 },
100
- model: 'claude-opus-4-7',
101
- tool_name: 'Task',
102
- });
103
-
104
- const usage = tracker.getSessionUsage(sessionId);
105
- expect(usage.total_tokens).toBe(300);
106
- expect(usage.budget).toBe(10000);
107
- expect(usage.usage_ratio).toBeCloseTo(0.03);
108
- });
109
-
110
- it('should not throw on budget check', () => {
111
- const sessionId = 'test-session-6';
112
-
113
- // Record usage exceeding budget
114
- tracker.record({
115
- session_id: sessionId,
116
- usage: { input_tokens: 8000, output_tokens: 3000 },
117
- });
118
-
119
- // Should not throw, just log warning
120
- const usage = tracker.getSessionUsage(sessionId);
121
- expect(usage.total_tokens).toBe(11000);
122
- expect(usage.usage_ratio).toBeGreaterThan(1.0);
123
- });
124
-
125
- it('should handle missing methodology_execution_id', () => {
126
- const sessionId = 'test-session-7';
127
-
128
- storage.writeTokenUsage({
129
- session_id: sessionId,
130
- input_tokens: 100,
131
- output_tokens: 200,
132
- });
133
-
134
- const usage = storage.getTokenUsageBySession(sessionId);
135
- expect(usage.total_tokens).toBe(300);
136
- });
137
-
138
- it('should return zero for non-existent session', () => {
139
- const usage = storage.getTokenUsageBySession('non-existent');
140
- expect(usage.total_tokens).toBe(0);
141
- expect(usage.input_tokens).toBe(0);
142
- expect(usage.output_tokens).toBe(0);
143
- });
144
- });
@@ -1,201 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import Database from 'better-sqlite3';
3
- import { EventEmitter } from 'node:events';
4
- import { EventOperations } from '../../src/core/storage/events.js';
5
- import type { ForgeEvent } from '../../src/core/types.js';
6
- import fs from 'node:fs';
7
- import path from 'node:path';
8
- import { tmpdir } from 'node:os';
9
-
10
- describe('Type Guards - EventOperations', () => {
11
- let db: Database.Database;
12
- let emitter: EventEmitter & { upsertSession: (event: ForgeEvent) => void };
13
- let eventOps: EventOperations;
14
- let dbPath: string;
15
-
16
- beforeEach(() => {
17
- // Create temporary database
18
- dbPath = path.join(tmpdir(), `test-${Date.now()}.db`);
19
- db = new Database(dbPath);
20
-
21
- // Create events table
22
- db.exec(`
23
- CREATE TABLE IF NOT EXISTS events (
24
- event_id TEXT PRIMARY KEY,
25
- session_id TEXT NOT NULL,
26
- project_path TEXT NOT NULL,
27
- timestamp TEXT NOT NULL,
28
- hook_type TEXT NOT NULL,
29
- tool_name TEXT,
30
- tool_input TEXT,
31
- tool_output TEXT,
32
- user_prompt TEXT,
33
- ai_response TEXT,
34
- distilled INTEGER DEFAULT 0
35
- )
36
- `);
37
-
38
- // Create mock emitter
39
- emitter = Object.assign(new EventEmitter(), {
40
- upsertSession: () => {},
41
- });
42
-
43
- eventOps = new EventOperations(db, emitter);
44
- });
45
-
46
- afterEach(() => {
47
- db.close();
48
- if (fs.existsSync(dbPath)) {
49
- fs.unlinkSync(dbPath);
50
- }
51
- });
52
-
53
- describe('writeEvent validation', () => {
54
- it('should accept valid event', () => {
55
- const validEvent: ForgeEvent = {
56
- session_id: 'test-session',
57
- project_path: '/test/project',
58
- timestamp: new Date().toISOString(),
59
- hook_type: 'UserPromptSubmit',
60
- user_prompt: 'test prompt',
61
- };
62
-
63
- expect(() => eventOps.writeEvent(validEvent)).not.toThrow();
64
- });
65
-
66
- it('should reject event with missing session_id', () => {
67
- const invalidEvent = {
68
- project_path: '/test/project',
69
- timestamp: new Date().toISOString(),
70
- hook_type: 'UserPromptSubmit',
71
- } as unknown as ForgeEvent;
72
-
73
- expect(() => eventOps.writeEvent(invalidEvent)).toThrow('Invalid event data');
74
- });
75
-
76
- it('should reject event with empty session_id', () => {
77
- const invalidEvent: ForgeEvent = {
78
- session_id: '',
79
- project_path: '/test/project',
80
- timestamp: new Date().toISOString(),
81
- hook_type: 'UserPromptSubmit',
82
- };
83
-
84
- expect(() => eventOps.writeEvent(invalidEvent)).toThrow('Invalid event data');
85
- });
86
-
87
- it('should reject event with missing project_path', () => {
88
- const invalidEvent = {
89
- session_id: 'test-session',
90
- timestamp: new Date().toISOString(),
91
- hook_type: 'UserPromptSubmit',
92
- } as unknown as ForgeEvent;
93
-
94
- expect(() => eventOps.writeEvent(invalidEvent)).toThrow('Invalid event data');
95
- });
96
-
97
- it('should reject event with empty timestamp', () => {
98
- const invalidEvent = {
99
- session_id: 'test-session',
100
- project_path: '/test/project',
101
- timestamp: '',
102
- hook_type: 'UserPromptSubmit',
103
- } as unknown as ForgeEvent;
104
-
105
- expect(() => eventOps.writeEvent(invalidEvent)).toThrow('Invalid event data');
106
- });
107
-
108
- it('should reject event with invalid hook_type', () => {
109
- const invalidEvent = {
110
- session_id: 'test-session',
111
- project_path: '/test/project',
112
- timestamp: new Date().toISOString(),
113
- hook_type: 'InvalidHookType',
114
- } as unknown as ForgeEvent;
115
-
116
- expect(() => eventOps.writeEvent(invalidEvent)).toThrow('Invalid event data');
117
- });
118
-
119
- it('should accept event with optional fields', () => {
120
- const validEvent: ForgeEvent = {
121
- session_id: 'test-session',
122
- project_path: '/test/project',
123
- timestamp: new Date().toISOString(),
124
- hook_type: 'PreToolUse',
125
- tool_name: 'TestTool',
126
- tool_input: { param: 'value' },
127
- tool_output: { result: 'success' },
128
- };
129
-
130
- expect(() => eventOps.writeEvent(validEvent)).not.toThrow();
131
- });
132
- });
133
-
134
- describe('rowToEvent validation', () => {
135
- it('should handle valid database row', () => {
136
- const validRow = {
137
- event_id: 'test-event-id',
138
- session_id: 'test-session',
139
- project_path: '/test/project',
140
- timestamp: new Date().toISOString(),
141
- hook_type: 'UserPromptSubmit',
142
- tool_name: null,
143
- tool_input: null,
144
- tool_output: null,
145
- user_prompt: 'test prompt',
146
- ai_response: null,
147
- };
148
-
149
- const event = eventOps.rowToEvent(validRow);
150
- expect(event.event_id).toBe('test-event-id');
151
- expect(event.session_id).toBe('test-session');
152
- expect(event.hook_type).toBe('UserPromptSubmit');
153
- });
154
-
155
- it('should handle row with JSON fields', () => {
156
- const validRow = {
157
- event_id: 'test-event-id',
158
- session_id: 'test-session',
159
- project_path: '/test/project',
160
- timestamp: new Date().toISOString(),
161
- hook_type: 'PreToolUse',
162
- tool_name: 'TestTool',
163
- tool_input: JSON.stringify({ param: 'value' }),
164
- tool_output: JSON.stringify({ result: 'success' }),
165
- user_prompt: null,
166
- ai_response: null,
167
- };
168
-
169
- const event = eventOps.rowToEvent(validRow);
170
- expect(event.tool_name).toBe('TestTool');
171
- expect(event.tool_input).toEqual({ param: 'value' });
172
- expect(event.tool_output).toEqual({ result: 'success' });
173
- });
174
-
175
- it('should return safe fallback for invalid row', () => {
176
- const invalidRow = {
177
- event_id: 123, // Should be string
178
- session_id: null, // Should be string
179
- project_path: undefined,
180
- timestamp: 'invalid',
181
- hook_type: 'InvalidType',
182
- };
183
-
184
- const event = eventOps.rowToEvent(invalidRow);
185
- // Should not throw, but return safe defaults
186
- expect(event.session_id).toBe('unknown');
187
- expect(event.hook_type).toBe('UserPromptSubmit');
188
- });
189
-
190
- it('should handle missing fields gracefully', () => {
191
- const incompleteRow = {
192
- event_id: 'test-id',
193
- };
194
-
195
- const event = eventOps.rowToEvent(incompleteRow);
196
- // Should return safe fallback
197
- expect(event.event_id).toBeDefined();
198
- expect(event.session_id).toBeDefined();
199
- });
200
- });
201
- });