@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,322 +0,0 @@
1
- /**
2
- * RoutingOperations — routing_events + experiment_assignments 读写
3
- *
4
- * 拆分自 sqlite.ts。
5
- *
6
- * 注意:experiment_assignments 表在 base.ts 的 deprecated 列表里被 DROP 了,
7
- * 但保留访问方法以维持 API 向后兼容(旧库残留 / 不同 schema 版本)。
8
- */
9
-
10
- import type Database from 'better-sqlite3';
11
-
12
- export interface RoutingEventRecord {
13
- id?: number;
14
- session_id: string;
15
- route_request_id?: string | null;
16
- project_path: string;
17
- ts: number;
18
- prompt: string;
19
- intent_json: string;
20
- routed_to_type?: 'agent' | 'skill' | 'none' | null;
21
- routed_to_name?: string | null;
22
- is_forced?: number;
23
- obeyed?: number | null;
24
- classification_ms?: number | null;
25
- fallback_used?: number;
26
- refusal_reason?: string | null;
27
- first_tool_name?: string | null;
28
- first_tool_ts?: number | null;
29
- completed_ts?: number | null;
30
- total_execution_ms?: number | null;
31
- completion_reason?: string | null;
32
- downstream_task_chain?: string | null;
33
- injection_version?: string | null;
34
- experiment_id?: string | null;
35
- experiment_group?: string | null;
36
- skill_confidence?: number | null;
37
- skill_source?: 'auto' | 'slash_command' | 'agent_dependency' | null;
38
- }
39
-
40
- export interface RoutingEventRow extends RoutingEventRecord {
41
- id: number;
42
- created_at: string;
43
- }
44
-
45
- export class RoutingOperations {
46
- constructor(private db: Database.Database) {}
47
-
48
- writeRoutingEvent(record: RoutingEventRecord): number {
49
- const result = this.db.prepare(`
50
- INSERT INTO routing_events (
51
- session_id, route_request_id, project_path, ts, prompt, intent_json,
52
- routed_to_type, routed_to_name, is_forced, obeyed,
53
- classification_ms, fallback_used, refusal_reason,
54
- first_tool_name, first_tool_ts, completed_ts,
55
- total_execution_ms, completion_reason, downstream_task_chain,
56
- injection_version, experiment_id, experiment_group
57
- ) VALUES (
58
- @session_id, @route_request_id, @project_path, @ts, @prompt, @intent_json,
59
- @routed_to_type, @routed_to_name, @is_forced, @obeyed,
60
- @classification_ms, @fallback_used, @refusal_reason,
61
- @first_tool_name, @first_tool_ts, @completed_ts,
62
- @total_execution_ms, @completion_reason, @downstream_task_chain,
63
- @injection_version, @experiment_id, @experiment_group
64
- )
65
- `).run({
66
- session_id: record.session_id,
67
- route_request_id: record.route_request_id ?? null,
68
- project_path: record.project_path,
69
- ts: record.ts,
70
- prompt: record.prompt,
71
- intent_json: record.intent_json,
72
- routed_to_type: record.routed_to_type ?? null,
73
- routed_to_name: record.routed_to_name ?? null,
74
- is_forced: record.is_forced ?? 0,
75
- obeyed: record.obeyed ?? null,
76
- classification_ms: record.classification_ms ?? null,
77
- fallback_used: record.fallback_used ?? 0,
78
- refusal_reason: record.refusal_reason ?? null,
79
- first_tool_name: record.first_tool_name ?? null,
80
- first_tool_ts: record.first_tool_ts ?? null,
81
- completed_ts: record.completed_ts ?? null,
82
- total_execution_ms: record.total_execution_ms ?? null,
83
- completion_reason: record.completion_reason ?? null,
84
- downstream_task_chain: record.downstream_task_chain ?? null,
85
- injection_version: record.injection_version ?? null,
86
- experiment_id: record.experiment_id ?? null,
87
- experiment_group: record.experiment_group ?? null,
88
- });
89
- return Number(result.lastInsertRowid);
90
- }
91
-
92
- updateRoutingEvent(id: number, patch: Partial<RoutingEventRecord>): void {
93
- const fields = Object.keys(patch).filter((k) => k !== 'id');
94
- if (fields.length === 0) return;
95
- const setClause = fields.map((f) => `${f} = @${f}`).join(', ');
96
- this.db.prepare(`UPDATE routing_events SET ${setClause} WHERE id = @id`).run({
97
- ...patch,
98
- id,
99
- });
100
- }
101
-
102
- queryRoutingEvents(filter: {
103
- session_id?: string;
104
- project_path?: string;
105
- since_ts?: number;
106
- routed_to_name?: string;
107
- obeyed?: number | null;
108
- limit?: number;
109
- } = {}): RoutingEventRow[] {
110
- const conds: string[] = [];
111
- const params: Record<string, unknown> = {};
112
- if (filter.session_id) { conds.push('session_id = @session_id'); params.session_id = filter.session_id; }
113
- if (filter.project_path) { conds.push('project_path = @project_path'); params.project_path = filter.project_path; }
114
- if (filter.since_ts !== undefined) { conds.push('ts >= @since_ts'); params.since_ts = filter.since_ts; }
115
- if (filter.routed_to_name) { conds.push('routed_to_name = @routed_to_name'); params.routed_to_name = filter.routed_to_name; }
116
- if (filter.obeyed !== undefined) {
117
- if (filter.obeyed === null) conds.push('obeyed IS NULL');
118
- else { conds.push('obeyed = @obeyed'); params.obeyed = filter.obeyed; }
119
- }
120
- const where = conds.length > 0 ? `WHERE ${conds.join(' AND ')}` : '';
121
- const limit = filter.limit ?? 100;
122
- params.limit = limit;
123
- const rows = this.db.prepare(
124
- `SELECT * FROM routing_events ${where} ORDER BY ts DESC LIMIT @limit`
125
- ).all(params) as RoutingEventRow[];
126
- return rows;
127
- }
128
-
129
- /** Pending events with NULL obeyed within the last N seconds; used by daemon restart recovery. */
130
- queryPendingRoutingEvents(ageMs: number): RoutingEventRow[] {
131
- const cutoff = Date.now() - ageMs;
132
- return this.db.prepare(
133
- `SELECT * FROM routing_events WHERE obeyed IS NULL AND ts >= ? ORDER BY ts DESC`
134
- ).all(cutoff) as RoutingEventRow[];
135
- }
136
-
137
- /** Get the most recent routing_event for a session (used by Agent observation). */
138
- getRecentRoutingEvent(sessionId: string): { id: number } | null {
139
- const row = this.db.prepare(`
140
- SELECT id FROM routing_events
141
- WHERE session_id = ?
142
- ORDER BY ts DESC
143
- LIMIT 1
144
- `).get(sessionId) as { id: number } | undefined;
145
- return row ?? null;
146
- }
147
-
148
- /**
149
- * Get the most recent PENDING routing_event for a session (obeyed IS NULL).
150
- *
151
- * Used by PostToolUseHandler to associate Agent invocations with the
152
- * still-unfilled routing_event from the current user prompt. Returning only
153
- * pending rows prevents the handler from re-overwriting an already-completed
154
- * event (e.g. when 2+ Agents fire within the same prompt, or when an old
155
- * obeyed=1 row leaks past a missed UserPromptSubmit).
156
- *
157
- * Trade-off: in the "same-prompt multi-Agent" case, the 2nd+ Agent will not
158
- * find a pending row and will be silently skipped. Recording every Agent
159
- * call is M7 out-of-scope (would require INSERT in PostToolUse rather than
160
- * UPDATE).
161
- */
162
- getRecentPendingRoutingEvent(sessionId: string): { id: number } | null {
163
- const row = this.db.prepare(`
164
- SELECT id FROM routing_events
165
- WHERE session_id = ? AND obeyed IS NULL
166
- ORDER BY ts DESC
167
- LIMIT 1
168
- `).get(sessionId) as { id: number } | undefined;
169
- return row ?? null;
170
- }
171
-
172
- // ── Experiment Assignments ──────────────────────────────────────────────
173
-
174
- getExperimentAssignment(sessionId: string, experimentId: string): string | null {
175
- const row = this.db.prepare(
176
- `SELECT group_id FROM experiment_assignments WHERE session_id = ? AND experiment_id = ?`
177
- ).get(sessionId, experimentId) as { group_id: string } | undefined;
178
- return row ? row.group_id : null;
179
- }
180
-
181
- setExperimentAssignment(sessionId: string, experimentId: string, groupId: string): void {
182
- this.db.prepare(
183
- `INSERT OR IGNORE INTO experiment_assignments (session_id, experiment_id, group_id)
184
- VALUES (?, ?, ?)`
185
- ).run(sessionId, experimentId, groupId);
186
- }
187
-
188
- // ── Aggregates (H1: SQL-side GROUP BY for routes/rules/skill-stats) ───
189
- //
190
- // 这些 aggregate* 方法把原本 routes 层做的"全表 SELECT + JS reduce"下沉到
191
- // SQL 端,避免单进程内存放大。命名约定(spec H1 固化):
192
- // - aggregate* —— SQL 端 GROUP BY / COUNT,返回小结果
193
- // - query* —— 原始行返回(保留旧 API)
194
- //
195
- // 注意:所有方法都用 `ts > 0` 兜底,防止 strftime 在 ts<=0 时返回 NULL。
196
-
197
- /**
198
- * 一次性返回 rules + skill-stats 共用的 routing 汇总(4 个独立聚合,
199
- * 各走自己的索引)。不走 UNION ALL(SQLite 无 GROUPING SETS)。
200
- */
201
- aggregateRoutingStats(filter: { since_ts: number; project_path?: string }): {
202
- total: number;
203
- obeyed: number;
204
- refused: number;
205
- unknown: number;
206
- by_type: Array<{ type: 'agent' | 'skill' | 'none'; count: number }>;
207
- by_agent: Array<{ agent: string; count: number }>;
208
- by_skill_routed: Array<{ skill: string; count: number }>;
209
- } {
210
- const projectCond = filter.project_path ? 'AND project_path = @project' : '';
211
- const params = {
212
- since: filter.since_ts,
213
- project: filter.project_path ?? null,
214
- };
215
-
216
- const totalRow = this.db.prepare(`
217
- SELECT COUNT(*) AS total,
218
- SUM(CASE WHEN obeyed=1 THEN 1 ELSE 0 END) AS obeyed,
219
- SUM(CASE WHEN obeyed=0 THEN 1 ELSE 0 END) AS refused,
220
- SUM(CASE WHEN obeyed IS NULL THEN 1 ELSE 0 END) AS unknown
221
- FROM routing_events
222
- WHERE ts > 0 AND ts >= @since ${projectCond}
223
- `).get(params) as {
224
- total: number | null;
225
- obeyed: number | null;
226
- refused: number | null;
227
- unknown: number | null;
228
- };
229
-
230
- const byTypeRows = this.db.prepare(`
231
- SELECT COALESCE(routed_to_type, 'none') AS type, COUNT(*) AS count
232
- FROM routing_events
233
- WHERE ts > 0 AND ts >= @since ${projectCond}
234
- GROUP BY COALESCE(routed_to_type, 'none')
235
- ORDER BY count DESC
236
- `).all(params) as Array<{ type: 'agent' | 'skill' | 'none'; count: number }>;
237
-
238
- const byAgentRows = this.db.prepare(`
239
- SELECT routed_to_name AS agent, COUNT(*) AS count
240
- FROM routing_events
241
- WHERE ts > 0 AND ts >= @since AND obeyed = 1 AND routed_to_name IS NOT NULL ${projectCond}
242
- GROUP BY routed_to_name
243
- ORDER BY count DESC
244
- `).all(params) as Array<{ agent: string; count: number }>;
245
-
246
- const bySkillRoutedRows = this.db.prepare(`
247
- SELECT routed_to_name AS skill, COUNT(*) AS count
248
- FROM routing_events
249
- WHERE ts > 0 AND ts >= @since AND routed_to_type = 'skill' AND routed_to_name IS NOT NULL ${projectCond}
250
- GROUP BY routed_to_name
251
- ORDER BY count DESC
252
- `).all(params) as Array<{ skill: string; count: number }>;
253
-
254
- return {
255
- total: totalRow.total ?? 0,
256
- obeyed: totalRow.obeyed ?? 0,
257
- refused: totalRow.refused ?? 0,
258
- unknown: totalRow.unknown ?? 0,
259
- by_type: byTypeRows,
260
- by_agent: byAgentRows,
261
- by_skill_routed: bySkillRoutedRows,
262
- };
263
- }
264
-
265
- /**
266
- * 按天聚合 routing 事件,用于 skill-stats trend chart。
267
- * 时区固定 UTC(strftime + unixepoch),与旧实现的 `new Date(ts).toISOString().split('T')[0]` 一致。
268
- */
269
- aggregateRoutingTrendByDay(filter: { since_ts: number }): Array<{
270
- day: string;
271
- total: number;
272
- skill: number;
273
- }> {
274
- const rows = this.db.prepare(`
275
- SELECT strftime('%Y-%m-%d', ts / 1000, 'unixepoch') AS day,
276
- COUNT(*) AS total,
277
- SUM(CASE WHEN routed_to_type = 'skill' THEN 1 ELSE 0 END) AS skill
278
- FROM routing_events
279
- WHERE ts > 0 AND ts >= @since
280
- GROUP BY day
281
- ORDER BY day ASC
282
- `).all({ since: filter.since_ts }) as Array<{
283
- day: string | null;
284
- total: number;
285
- skill: number | null;
286
- }>;
287
- return rows
288
- .filter(r => r.day !== null)
289
- .map(r => ({ day: r.day as string, total: r.total, skill: r.skill ?? 0 }));
290
- }
291
-
292
- queryExperimentStats(experimentId: string): Array<{
293
- group_id: string;
294
- total: number;
295
- obeyed: number;
296
- refused: number;
297
- unknown: number;
298
- avg_classification_ms: number | null;
299
- }> {
300
- const rows = this.db.prepare(`
301
- SELECT
302
- experiment_group AS group_id,
303
- COUNT(*) AS total,
304
- SUM(CASE WHEN obeyed = 1 THEN 1 ELSE 0 END) AS obeyed,
305
- SUM(CASE WHEN obeyed = 0 THEN 1 ELSE 0 END) AS refused,
306
- SUM(CASE WHEN obeyed IS NULL THEN 1 ELSE 0 END) AS unknown,
307
- AVG(classification_ms) AS avg_classification_ms
308
- FROM routing_events
309
- WHERE experiment_id = ? AND experiment_group IS NOT NULL
310
- GROUP BY experiment_group
311
- ORDER BY experiment_group ASC
312
- `).all(experimentId) as Array<{
313
- group_id: string;
314
- total: number;
315
- obeyed: number;
316
- refused: number;
317
- unknown: number;
318
- avg_classification_ms: number | null;
319
- }>;
320
- return rows;
321
- }
322
- }
@@ -1,112 +0,0 @@
1
- /**
2
- * 数据库行的 TypeScript 类型定义。
3
- *
4
- * 每个 interface 对应一张表的查询结果行(shape 与 schema.sql + runMigrations 后
5
- * 的最终结构一致)。sqlite.ts 的所有 get/all 返回值都应该用这些类型而非 any,
6
- * 以确保 schema 变动能在编译期而不是运行期暴露。
7
- *
8
- * 约定:
9
- * - 字段可空性严格对齐 schema.sql 的 NOT NULL / DEFAULT NULL / 外键约束
10
- * - enum 字段(status / mode / trigger_type 等)使用 string literal union
11
- * - timestamp 字段按实际存储类型:文本时间戳 → string,Unix 毫秒数 → number
12
- */
13
-
14
- // ── events ────────────────────────────────────────────────────────────────
15
-
16
- export interface EventRow {
17
- event_id: string;
18
- session_id: string;
19
- project_path: string;
20
- timestamp: string;
21
- hook_type: 'PreToolUse' | 'PostToolUse' | 'UserPromptSubmit' | 'Notification' | 'Stop';
22
- tool_name: string | null;
23
- tool_input: string | null; // JSON string
24
- tool_output: string | null; // JSON string
25
- user_prompt: string | null;
26
- ai_response: string | null;
27
- created_at: string;
28
- }
29
-
30
- // ── sessions ──────────────────────────────────────────────────────────────
31
-
32
- export interface SessionRow {
33
- session_id: string;
34
- project_path: string;
35
- status: 'active' | 'completed' | 'interrupted' | 'resumed' | 'abandoned';
36
- first_prompt: string | null;
37
- start_time: string;
38
- end_time: string | null;
39
- last_event_time: string | null;
40
- event_count: number;
41
- created_at: string;
42
- updated_at: string;
43
- }
44
-
45
- // ── injections ────────────────────────────────────────────────────────────
46
-
47
- export interface InjectionRow {
48
- id: string;
49
- event_id: string | null;
50
- session_id: string;
51
- timestamp: string;
52
- source_handler: string;
53
- injection_type: 'systemMessage' | 'additionalContext' | 'reason';
54
- content: string;
55
- created_at: string;
56
- }
57
-
58
- // ── tasks ─────────────────────────────────────────────────────────────────
59
-
60
- export interface TaskRow {
61
- id: string;
62
- session_id: string;
63
- title: string;
64
- description: string | null;
65
- start_time: string;
66
- end_time: string | null;
67
- status: 'active' | 'completed' | 'abandoned';
68
- event_count: number;
69
- created_at: string;
70
- }
71
-
72
- // ── token_usage ───────────────────────────────────────────────────────────
73
-
74
- export interface TokenUsageRow {
75
- id: number;
76
- session_id: string;
77
- timestamp: number;
78
- input_tokens: number;
79
- output_tokens: number;
80
- total_tokens: number;
81
- model: string | null;
82
- tool_name: string | null;
83
- created_at: string;
84
- }
85
-
86
- // ── skill_invocations ─────────────────────────────────────────────────────
87
- // Skill 调用链路追踪:Agent 动态调用 Skill 的每一次记录。
88
- // invocation_type 区分静态依赖(agent frontmatter 声明)、动态调用(MCP 工具 `skill_invoke`)、
89
- // 以及 slash_command(用户直接通过 /skill-xxx 触发)。
90
-
91
- export interface SkillInvocationRow {
92
- id: string;
93
- route_request_id: string | null;
94
- session_id: string;
95
- agent_id: string | null;
96
- skill_id: string;
97
- invocation_type: 'static' | 'dynamic' | 'slash_command';
98
- reason: string | null;
99
-
100
- // 工作流追踪字段(v8.38+):从 reason 字段解析的 <workflow>/<phase>[:feature-slug] 元信息。
101
- // 解析失败或非工作流调用时所有字段为 null,以保持向后兼容。
102
- workflow: string | null; // 'bmad' / 'harness' / 其他工作流标识
103
- phase: string | null; // 'analyze' / 'design' / 'safety-net' 等
104
- feature_slug: string | null; // 可选,关联同一 feature 的多次调用
105
- artifact_path: string | null; // 可选,调用产出的文档路径
106
-
107
- depth: number;
108
- success: number; // SQLite 存储为 INTEGER (0 | 1)
109
- error: string | null;
110
- timestamp: number;
111
- created_at: string;
112
- }
@@ -1,224 +0,0 @@
1
- -- Claude Forge SQLite Schema (core tables)
2
- -- Active tables: events, sessions, injections, tasks, task_events,
3
- -- routing_events, token_usage, skill_invocations
4
- --
5
- -- ── Table Relationships ──────────────────────────────────────────────────────
6
- --
7
- -- events (core fact table)
8
- -- └─ sessions.session_id — aggregated from events (app-layer, no FK)
9
- -- └─ injections.event_id — FK ON DELETE CASCADE
10
- -- └─ task_events.event_id — FK ON DELETE CASCADE
11
- --
12
- -- routing_events (agent routing decisions)
13
- -- └─ routing_events.session_id → events.session_id (logical, no FK)
14
- -- └─ skill_invocations.route_request_id → routing_events.route_request_id (logical, no FK)
15
- --
16
- -- skill_invocations (skill execution records)
17
- -- └─ skill_invocations.session_id → events.session_id (logical, no FK)
18
- -- └─ skill_invocations.route_request_id → routing_events.route_request_id (logical, no FK)
19
- --
20
- -- token_usage (LLM token accounting)
21
- -- └─ token_usage.session_id → events.session_id (logical, no FK)
22
- --
23
- -- Why no FK on routing_events / skill_invocations / token_usage:
24
- -- 1. routing_events.route_request_id is nullable and not UNIQUE — cannot be FK target
25
- -- 2. Write order is not guaranteed: skill_invocations may be written before routing_events
26
- -- 3. session_id references are maintained by application logic; sessions is an aggregate
27
- -- table that may lag behind event writes
28
- -- 4. Indexes on join columns provide equivalent query performance to FK indexes
29
- --
30
-
31
- -- ── Events & Sessions ─────────────────────────────────────────────────────
32
-
33
- CREATE TABLE IF NOT EXISTS events (
34
- event_id TEXT PRIMARY KEY,
35
- session_id TEXT NOT NULL,
36
- project_path TEXT NOT NULL,
37
- timestamp TEXT NOT NULL,
38
- hook_type TEXT NOT NULL CHECK(hook_type IN ('PreToolUse', 'PostToolUse', 'UserPromptSubmit', 'Notification', 'Stop')),
39
- tool_name TEXT,
40
- tool_input TEXT,
41
- tool_output TEXT,
42
- user_prompt TEXT,
43
- ai_response TEXT,
44
- distilled INTEGER DEFAULT 0,
45
- created_at TEXT DEFAULT (datetime('now'))
46
- );
47
-
48
- CREATE INDEX IF NOT EXISTS idx_events_session ON events(session_id);
49
- CREATE INDEX IF NOT EXISTS idx_events_project ON events(project_path);
50
- CREATE INDEX IF NOT EXISTS idx_events_timestamp ON events(timestamp DESC);
51
- CREATE INDEX IF NOT EXISTS idx_events_distilled ON events(distilled);
52
- CREATE INDEX IF NOT EXISTS idx_events_hook_type ON events(hook_type);
53
-
54
- CREATE TABLE IF NOT EXISTS sessions (
55
- session_id TEXT PRIMARY KEY,
56
- project_path TEXT NOT NULL,
57
- status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'completed', 'interrupted', 'resumed', 'abandoned')),
58
- first_prompt TEXT,
59
- start_time TEXT NOT NULL,
60
- end_time TEXT,
61
- last_event_time TEXT,
62
- event_count INTEGER DEFAULT 0,
63
- created_at TEXT DEFAULT (datetime('now')),
64
- updated_at TEXT DEFAULT (datetime('now'))
65
- );
66
-
67
- CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_path);
68
- CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
69
- CREATE INDEX IF NOT EXISTS idx_sessions_start_time ON sessions(start_time DESC);
70
-
71
- -- ── Injections ─────────────────────────────────────────────────────
72
-
73
- CREATE TABLE IF NOT EXISTS injections (
74
- id TEXT PRIMARY KEY,
75
- event_id TEXT,
76
- session_id TEXT NOT NULL,
77
- timestamp TEXT NOT NULL,
78
- source_handler TEXT NOT NULL,
79
- injection_type TEXT NOT NULL CHECK(injection_type IN ('systemMessage', 'additionalContext', 'reason')),
80
- content TEXT NOT NULL,
81
- created_at TEXT DEFAULT (datetime('now')),
82
- FOREIGN KEY (event_id) REFERENCES events(event_id) ON DELETE CASCADE
83
- );
84
-
85
- CREATE INDEX IF NOT EXISTS idx_injections_session ON injections(session_id);
86
- CREATE INDEX IF NOT EXISTS idx_injections_event ON injections(event_id);
87
- CREATE INDEX IF NOT EXISTS idx_injections_timestamp ON injections(timestamp DESC);
88
-
89
- -- ── Tasks ──────────────────────────────────────────────────────────
90
-
91
- CREATE TABLE IF NOT EXISTS tasks (
92
- id TEXT PRIMARY KEY,
93
- session_id TEXT NOT NULL,
94
- title TEXT NOT NULL,
95
- description TEXT,
96
- start_time TEXT NOT NULL,
97
- end_time TEXT,
98
- status TEXT DEFAULT 'active' CHECK(status IN ('active', 'completed', 'abandoned')),
99
- event_count INTEGER DEFAULT 0,
100
- created_at TEXT DEFAULT (datetime('now'))
101
- );
102
-
103
- CREATE TABLE IF NOT EXISTS task_events (
104
- task_id TEXT NOT NULL,
105
- event_id TEXT NOT NULL,
106
- PRIMARY KEY (task_id, event_id),
107
- FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE,
108
- FOREIGN KEY (event_id) REFERENCES events(event_id) ON DELETE CASCADE
109
- );
110
-
111
- CREATE INDEX IF NOT EXISTS idx_tasks_session ON tasks(session_id);
112
- CREATE INDEX IF NOT EXISTS idx_tasks_start_time ON tasks(start_time DESC);
113
- CREATE INDEX IF NOT EXISTS idx_task_events_task ON task_events(task_id);
114
- CREATE INDEX IF NOT EXISTS idx_task_events_event ON task_events(event_id);
115
-
116
- -- ── Routing Events (agent routing observability) ─────────────────────────
117
-
118
- CREATE TABLE IF NOT EXISTS routing_events (
119
- id INTEGER PRIMARY KEY AUTOINCREMENT,
120
- session_id TEXT NOT NULL,
121
- route_request_id TEXT,
122
- project_path TEXT NOT NULL,
123
- ts INTEGER NOT NULL,
124
- prompt TEXT NOT NULL,
125
- intent_json TEXT NOT NULL,
126
- routed_to_type TEXT,
127
- routed_to_name TEXT,
128
- is_forced INTEGER DEFAULT 0,
129
- obeyed INTEGER,
130
- classification_ms INTEGER,
131
- fallback_used INTEGER DEFAULT 0,
132
- refusal_reason TEXT,
133
- first_tool_name TEXT,
134
- first_tool_ts INTEGER,
135
- completed_ts INTEGER,
136
- total_execution_ms INTEGER,
137
- completion_reason TEXT,
138
- downstream_task_chain TEXT,
139
- injection_version TEXT,
140
- experiment_id TEXT,
141
- experiment_group TEXT,
142
- skill_confidence REAL,
143
- skill_source TEXT,
144
- created_at TEXT DEFAULT (datetime('now'))
145
- );
146
-
147
- CREATE INDEX IF NOT EXISTS idx_routing_events_session ON routing_events(session_id);
148
- CREATE INDEX IF NOT EXISTS idx_routing_events_route_request ON routing_events(route_request_id);
149
- CREATE INDEX IF NOT EXISTS idx_routing_events_ts ON routing_events(ts DESC);
150
- CREATE INDEX IF NOT EXISTS idx_routing_events_agent ON routing_events(routed_to_name, obeyed);
151
- CREATE INDEX IF NOT EXISTS idx_routing_events_obeyed ON routing_events(obeyed);
152
- CREATE INDEX IF NOT EXISTS idx_routing_events_experiment ON routing_events(experiment_id, experiment_group);
153
-
154
- -- ── Token Usage ──────────────────────────────────────────────────────
155
-
156
- CREATE TABLE IF NOT EXISTS token_usage (
157
- id INTEGER PRIMARY KEY AUTOINCREMENT,
158
- session_id TEXT NOT NULL, -- logical ref → events.session_id; no FK due to write-order race (sessions is aggregate, may lag)
159
- timestamp INTEGER NOT NULL,
160
- input_tokens INTEGER NOT NULL,
161
- output_tokens INTEGER NOT NULL,
162
- total_tokens INTEGER NOT NULL,
163
- model TEXT,
164
- tool_name TEXT,
165
- created_at TEXT DEFAULT (datetime('now'))
166
- );
167
-
168
- CREATE INDEX IF NOT EXISTS idx_token_usage_session ON token_usage(session_id);
169
- CREATE INDEX IF NOT EXISTS idx_token_usage_timestamp ON token_usage(timestamp DESC);
170
-
171
- -- ── Skill Invocations ─────────────────────────────────────────────────
172
-
173
- CREATE TABLE IF NOT EXISTS skill_invocations (
174
- id TEXT PRIMARY KEY,
175
- route_request_id TEXT,
176
- session_id TEXT NOT NULL,
177
- agent_id TEXT,
178
- skill_id TEXT NOT NULL,
179
- invocation_type TEXT NOT NULL,
180
- reason TEXT,
181
- workflow TEXT,
182
- phase TEXT,
183
- feature_slug TEXT,
184
- artifact_path TEXT,
185
- depth INTEGER DEFAULT 0,
186
- success INTEGER DEFAULT 1,
187
- error TEXT,
188
- timestamp INTEGER NOT NULL,
189
- created_at TEXT DEFAULT (datetime('now'))
190
- );
191
-
192
- CREATE INDEX IF NOT EXISTS idx_skill_invocations_route_request ON skill_invocations(route_request_id);
193
- CREATE INDEX IF NOT EXISTS idx_skill_invocations_session ON skill_invocations(session_id);
194
- CREATE INDEX IF NOT EXISTS idx_skill_invocations_skill ON skill_invocations(skill_id);
195
- CREATE INDEX IF NOT EXISTS idx_skill_invocations_timestamp ON skill_invocations(timestamp DESC);
196
-
197
- -- ── Composite Indexes (high-frequency query optimization) ─────────────────────
198
- -- These cover session-scoped queries that filter by session_id then sort by time.
199
- -- Existing single-column indexes are retained for other query paths.
200
-
201
- CREATE INDEX IF NOT EXISTS idx_events_session_ts ON events(session_id, timestamp DESC);
202
- CREATE INDEX IF NOT EXISTS idx_routing_events_session_ts ON routing_events(session_id, ts DESC);
203
- CREATE INDEX IF NOT EXISTS idx_skill_invocations_session_ts ON skill_invocations(session_id, timestamp DESC);
204
-
205
- -- ── Additional Performance Indexes (Phase 1 Refactor) ─────────────────────
206
-
207
- -- routing_events: optimize obeyed flag queries with time sorting
208
- CREATE INDEX IF NOT EXISTS idx_routing_events_obeyed_ts ON routing_events(obeyed, ts DESC);
209
-
210
- -- tasks: optimize filter+sort queries (start_time range filter + session join)
211
- CREATE INDEX IF NOT EXISTS idx_tasks_start_time_session ON tasks(start_time DESC, session_id);
212
-
213
- -- events: optimize session + hook_type composite queries
214
- CREATE INDEX IF NOT EXISTS idx_events_session_hook ON events(session_id, hook_type, timestamp DESC);
215
-
216
- -- injections: optimize session + handler composite queries
217
- CREATE INDEX IF NOT EXISTS idx_injections_session_handler ON injections(session_id, source_handler);
218
-
219
- -- routing_events: optimize routed_to_type distribution (H1 aggregate path)
220
- CREATE INDEX IF NOT EXISTS idx_routing_events_type_ts ON routing_events(routed_to_type, ts DESC);
221
-
222
- -- skill_invocations: optimize workflow/phase and feature_slug queries (H4 dedup: previously migration-only)
223
- CREATE INDEX IF NOT EXISTS idx_skill_invocations_workflow ON skill_invocations(workflow, phase);
224
- CREATE INDEX IF NOT EXISTS idx_skill_invocations_feature ON skill_invocations(feature_slug);