@winspan/claude-forge 8.41.0 → 8.51.0
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.
- package/.claude/CLAUDE.md +17 -0
- package/.eslintrc.js +23 -0
- package/.prettierrc +8 -0
- package/ARCHITECTURE_ISSUES.md +249 -0
- package/CLAUDE.md +265 -0
- package/CLAUDE.md.backup +488 -0
- package/DEVELOPMENT.md +310 -0
- package/dist/claudemd/claudemd-generator.d.ts +38 -3
- package/dist/claudemd/claudemd-generator.d.ts.map +1 -1
- package/dist/claudemd/claudemd-generator.js +420 -12
- package/dist/claudemd/claudemd-generator.js.map +1 -1
- package/dist/claudemd/index.d.ts +2 -2
- package/dist/claudemd/index.d.ts.map +1 -1
- package/dist/claudemd/index.js.map +1 -1
- package/dist/claudemd/resume-manager.d.ts.map +1 -1
- package/dist/claudemd/resume-manager.js +6 -3
- package/dist/claudemd/resume-manager.js.map +1 -1
- package/dist/claudemd/tech-detector.d.ts +1 -0
- package/dist/claudemd/tech-detector.d.ts.map +1 -1
- package/dist/claudemd/tech-detector.js +53 -0
- package/dist/claudemd/tech-detector.js.map +1 -1
- package/dist/claudemd/templates/swarm-protocol.md +222 -0
- package/dist/cli/commands/claudemd.js +2 -2
- package/dist/cli/commands/claudemd.js.map +1 -1
- package/dist/cli/commands/daemon.d.ts +28 -0
- package/dist/cli/commands/daemon.d.ts.map +1 -1
- package/dist/cli/commands/daemon.js +204 -12
- package/dist/cli/commands/daemon.js.map +1 -1
- package/dist/cli/commands/executions.d.ts.map +1 -1
- package/dist/cli/commands/executions.js +4 -3
- package/dist/cli/commands/executions.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +5 -37
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/logs.js.map +1 -1
- package/dist/cli/commands/mcp.d.ts.map +1 -1
- package/dist/cli/commands/mcp.js +3 -5
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/menu.d.ts.map +1 -1
- package/dist/cli/commands/menu.js +14 -13
- package/dist/cli/commands/menu.js.map +1 -1
- package/dist/cli/commands/skills.d.ts.map +1 -1
- package/dist/cli/commands/skills.js +8 -2
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/commands/stats.d.ts.map +1 -1
- package/dist/cli/commands/stats.js +2 -20
- package/dist/cli/commands/stats.js.map +1 -1
- package/dist/cli/commands/status.js +2 -2
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/trace.d.ts +9 -0
- package/dist/cli/commands/trace.d.ts.map +1 -0
- package/dist/cli/commands/trace.js +125 -0
- package/dist/cli/commands/trace.js.map +1 -0
- package/dist/cli/index.js +2 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init/hook-manager.d.ts.map +1 -1
- package/dist/cli/init/hook-manager.js +2 -2
- package/dist/cli/init/hook-manager.js.map +1 -1
- package/dist/core/ai/provider.d.ts +10 -2
- package/dist/core/ai/provider.d.ts.map +1 -1
- package/dist/core/ai/provider.js +2 -2
- package/dist/core/ai/provider.js.map +1 -1
- package/dist/core/ai/types.d.ts +1 -19
- package/dist/core/ai/types.d.ts.map +1 -1
- package/dist/core/ai/types.js +1 -1
- package/dist/core/config.d.ts +2 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +23 -6
- package/dist/core/config.js.map +1 -1
- package/dist/core/constants.d.ts +14 -3
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +17 -3
- package/dist/core/constants.js.map +1 -1
- package/dist/core/event-fields.d.ts +16 -0
- package/dist/core/event-fields.d.ts.map +1 -0
- package/dist/core/event-fields.js +19 -0
- package/dist/core/event-fields.js.map +1 -0
- package/dist/core/queue/index.d.ts +52 -0
- package/dist/core/queue/index.d.ts.map +1 -0
- package/dist/core/queue/index.js +175 -0
- package/dist/core/queue/index.js.map +1 -0
- package/dist/core/storage/base.d.ts +66 -0
- package/dist/core/storage/base.d.ts.map +1 -0
- package/dist/core/storage/base.js +254 -0
- package/dist/core/storage/base.js.map +1 -0
- package/dist/core/storage/events.d.ts +141 -0
- package/dist/core/storage/events.d.ts.map +1 -0
- package/dist/core/storage/events.js +348 -0
- package/dist/core/storage/events.js.map +1 -0
- package/dist/core/storage/injections.d.ts +27 -0
- package/dist/core/storage/injections.d.ts.map +1 -0
- package/dist/core/storage/injections.js +51 -0
- package/dist/core/storage/injections.js.map +1 -0
- package/dist/core/storage/maintenance.d.ts +21 -0
- package/dist/core/storage/maintenance.d.ts.map +1 -0
- package/dist/core/storage/maintenance.js +52 -0
- package/dist/core/storage/maintenance.js.map +1 -0
- package/dist/core/storage/routing.d.ts +124 -0
- package/dist/core/storage/routing.d.ts.map +1 -0
- package/dist/core/storage/routing.js +239 -0
- package/dist/core/storage/routing.js.map +1 -0
- package/dist/core/storage/rows.d.ts +0 -47
- package/dist/core/storage/rows.d.ts.map +1 -1
- package/dist/core/storage/schema.sql +85 -137
- package/dist/core/storage/sessions.d.ts +54 -0
- package/dist/core/storage/sessions.d.ts.map +1 -0
- package/dist/core/storage/sessions.js +137 -0
- package/dist/core/storage/sessions.js.map +1 -0
- package/dist/core/storage/skills.d.ts +63 -0
- package/dist/core/storage/skills.d.ts.map +1 -0
- package/dist/core/storage/skills.js +154 -0
- package/dist/core/storage/skills.js.map +1 -0
- package/dist/core/storage/sqlite.d.ts +97 -266
- package/dist/core/storage/sqlite.d.ts.map +1 -1
- package/dist/core/storage/sqlite.js +196 -764
- package/dist/core/storage/sqlite.js.map +1 -1
- package/dist/core/storage/tasks.d.ts +113 -0
- package/dist/core/storage/tasks.d.ts.map +1 -0
- package/dist/core/storage/tasks.js +276 -0
- package/dist/core/storage/tasks.js.map +1 -0
- package/dist/core/storage/token-usage.d.ts +36 -0
- package/dist/core/storage/token-usage.d.ts.map +1 -0
- package/dist/core/storage/token-usage.js +59 -0
- package/dist/core/storage/token-usage.js.map +1 -0
- package/dist/core/types.d.ts +83 -6
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +24 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/utils/error-handler.d.ts.map +1 -1
- package/dist/core/utils/error-handler.js +3 -2
- package/dist/core/utils/error-handler.js.map +1 -1
- package/dist/core/utils/format.d.ts +28 -0
- package/dist/core/utils/format.d.ts.map +1 -0
- package/dist/core/utils/format.js +68 -0
- package/dist/core/utils/format.js.map +1 -0
- package/dist/core/utils/git.d.ts +10 -0
- package/dist/core/utils/git.d.ts.map +1 -0
- package/dist/core/utils/git.js +24 -0
- package/dist/core/utils/git.js.map +1 -0
- package/dist/core/utils/logger.d.ts +6 -1
- package/dist/core/utils/logger.d.ts.map +1 -1
- package/dist/core/utils/logger.js +87 -3
- package/dist/core/utils/logger.js.map +1 -1
- package/dist/core/utils/lru-cache.d.ts +1 -0
- package/dist/core/utils/lru-cache.d.ts.map +1 -1
- package/dist/core/utils/lru-cache.js +3 -0
- package/dist/core/utils/lru-cache.js.map +1 -1
- package/dist/core/utils/session.d.ts +16 -0
- package/dist/core/utils/session.d.ts.map +1 -0
- package/dist/core/utils/session.js +25 -0
- package/dist/core/utils/session.js.map +1 -0
- package/dist/core/utils/time.d.ts +22 -0
- package/dist/core/utils/time.d.ts.map +1 -0
- package/dist/core/utils/time.js +38 -0
- package/dist/core/utils/time.js.map +1 -0
- package/dist/core/utils/token-tracker.js +1 -1
- package/dist/core/utils/token-tracker.js.map +1 -1
- package/dist/daemon/event-parser.d.ts.map +1 -1
- package/dist/daemon/event-parser.js +2 -1
- package/dist/daemon/event-parser.js.map +1 -1
- package/dist/daemon/handlers/history-exporter.d.ts.map +1 -1
- package/dist/daemon/handlers/history-exporter.js +6 -4
- package/dist/daemon/handlers/history-exporter.js.map +1 -1
- package/dist/daemon/handlers/post-tool-use.d.ts +5 -12
- package/dist/daemon/handlers/post-tool-use.d.ts.map +1 -1
- package/dist/daemon/handlers/post-tool-use.js +25 -79
- package/dist/daemon/handlers/post-tool-use.js.map +1 -1
- package/dist/daemon/handlers/stop.d.ts +28 -12
- package/dist/daemon/handlers/stop.d.ts.map +1 -1
- package/dist/daemon/handlers/stop.js +129 -42
- package/dist/daemon/handlers/stop.js.map +1 -1
- package/dist/daemon/handlers/user-prompt.d.ts +18 -19
- package/dist/daemon/handlers/user-prompt.d.ts.map +1 -1
- package/dist/daemon/handlers/user-prompt.js +93 -227
- package/dist/daemon/handlers/user-prompt.js.map +1 -1
- package/dist/daemon/index.d.ts +6 -2
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +97 -127
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/launchd/com.claude-forge.daemon.plist.template +47 -0
- package/dist/daemon/launchd-installer.d.ts +61 -0
- package/dist/daemon/launchd-installer.d.ts.map +1 -0
- package/dist/daemon/launchd-installer.js +182 -0
- package/dist/daemon/launchd-installer.js.map +1 -0
- package/dist/daemon/lifecycle.d.ts +11 -0
- package/dist/daemon/lifecycle.d.ts.map +1 -1
- package/dist/daemon/lifecycle.js +47 -4
- package/dist/daemon/lifecycle.js.map +1 -1
- package/dist/daemon/router.d.ts +9 -2
- package/dist/daemon/router.d.ts.map +1 -1
- package/dist/daemon/router.js +27 -3
- package/dist/daemon/router.js.map +1 -1
- package/dist/daemon/server.d.ts +6 -4
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +80 -88
- package/dist/daemon/server.js.map +1 -1
- package/dist/{intelligence → daemon/services}/task-segmenter.d.ts +7 -1
- package/dist/daemon/services/task-segmenter.d.ts.map +1 -0
- package/dist/{intelligence → daemon/services}/task-segmenter.js +30 -7
- package/dist/daemon/services/task-segmenter.js.map +1 -0
- package/dist/hooks/hook-lib.sh +118 -0
- package/dist/hooks/notification.sh +9 -5
- package/dist/hooks/post-tool-use.sh +10 -6
- package/dist/hooks/pre-tool-use.sh +9 -6
- package/dist/hooks/stop.sh +10 -7
- package/dist/hooks/user-prompt-submit.sh +10 -11
- package/dist/mcp/server.d.ts +2 -2
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +71 -11
- package/dist/mcp/server.js.map +1 -1
- package/dist/skills/invocation-guard.d.ts +20 -0
- package/dist/skills/invocation-guard.d.ts.map +1 -1
- package/dist/skills/invocation-guard.js +63 -0
- package/dist/skills/invocation-guard.js.map +1 -1
- package/dist/skills/matcher.d.ts.map +1 -1
- package/dist/skills/matcher.js +12 -3
- package/dist/skills/matcher.js.map +1 -1
- package/dist/skills/official/code-simplifier.md +16 -0
- package/dist/skills/official/find-skills.md +23 -0
- package/dist/skills/official/official-api-design.md +17 -0
- package/dist/skills/official/official-architecture-decision.md +20 -0
- package/dist/skills/official/official-bmad.md +118 -0
- package/dist/skills/official/official-db-schema-design.md +16 -0
- package/dist/skills/official/official-debug.md +17 -0
- package/dist/skills/official/official-doc-driven.md +31 -0
- package/dist/skills/official/official-harness-engineering.md +108 -0
- package/dist/skills/official/official-performance-optimization.md +30 -0
- package/dist/skills/official/official-pr-review.md +35 -0
- package/dist/skills/official/official-release-checklist.md +30 -0
- package/dist/skills/official/official-security-hardening.md +26 -0
- package/dist/skills/official/official-spec-driven-design.md +31 -0
- package/dist/skills/official/planning-with-files.md +37 -0
- package/dist/skills/official/ui-ux-pro-max.md +18 -0
- package/dist/skills/official/webapp-testing.md +12 -0
- package/dist/skills/official-skills.d.ts +8 -4
- package/dist/skills/official-skills.d.ts.map +1 -1
- package/dist/skills/official-skills.js +48 -704
- package/dist/skills/official-skills.js.map +1 -1
- package/dist/skills/registry.d.ts +5 -0
- package/dist/skills/registry.d.ts.map +1 -1
- package/dist/skills/registry.js +48 -15
- package/dist/skills/registry.js.map +1 -1
- package/dist/skills/tools/pipeline-suggest.d.ts +30 -0
- package/dist/skills/tools/pipeline-suggest.d.ts.map +1 -0
- package/dist/skills/tools/pipeline-suggest.js +178 -0
- package/dist/skills/tools/pipeline-suggest.js.map +1 -0
- package/dist/web/analytics/anti-pattern-detector.d.ts +49 -0
- package/dist/web/analytics/anti-pattern-detector.d.ts.map +1 -0
- package/dist/web/analytics/anti-pattern-detector.js +318 -0
- package/dist/web/analytics/anti-pattern-detector.js.map +1 -0
- package/dist/web/analytics/drift-detector.d.ts +64 -0
- package/dist/web/analytics/drift-detector.d.ts.map +1 -0
- package/dist/web/analytics/drift-detector.js +198 -0
- package/dist/web/analytics/drift-detector.js.map +1 -0
- package/dist/web/analytics/weekly-report.d.ts +91 -0
- package/dist/web/analytics/weekly-report.d.ts.map +1 -0
- package/dist/web/analytics/weekly-report.js +328 -0
- package/dist/web/analytics/weekly-report.js.map +1 -0
- package/dist/web/auth-middleware.d.ts.map +1 -1
- package/dist/web/auth-middleware.js +1 -2
- package/dist/web/auth-middleware.js.map +1 -1
- package/dist/web/routes/_helpers.d.ts +16 -0
- package/dist/web/routes/_helpers.d.ts.map +1 -0
- package/dist/web/routes/_helpers.js +32 -0
- package/dist/web/routes/_helpers.js.map +1 -0
- package/dist/web/routes/ai.d.ts.map +1 -1
- package/dist/web/routes/ai.js +16 -22
- package/dist/web/routes/ai.js.map +1 -1
- package/dist/web/routes/drift.d.ts +10 -0
- package/dist/web/routes/drift.d.ts.map +1 -0
- package/dist/web/routes/drift.js +21 -0
- package/dist/web/routes/drift.js.map +1 -0
- package/dist/web/routes/error-handler.d.ts +43 -0
- package/dist/web/routes/error-handler.d.ts.map +1 -0
- package/dist/web/routes/error-handler.js +99 -0
- package/dist/web/routes/error-handler.js.map +1 -0
- package/dist/web/routes/insights.d.ts +9 -0
- package/dist/web/routes/insights.d.ts.map +1 -0
- package/dist/web/routes/insights.js +34 -0
- package/dist/web/routes/insights.js.map +1 -0
- package/dist/web/routes/patch.js +2 -2
- package/dist/web/routes/patch.js.map +1 -1
- package/dist/web/routes/reports.d.ts +10 -0
- package/dist/web/routes/reports.d.ts.map +1 -0
- package/dist/web/routes/reports.js +27 -0
- package/dist/web/routes/reports.js.map +1 -0
- package/dist/web/routes/rules.d.ts +13 -3
- package/dist/web/routes/rules.d.ts.map +1 -1
- package/dist/web/routes/rules.js +58 -97
- package/dist/web/routes/rules.js.map +1 -1
- package/dist/web/routes/sessions.d.ts +1 -2
- package/dist/web/routes/sessions.d.ts.map +1 -1
- package/dist/web/routes/sessions.js +43 -69
- package/dist/web/routes/sessions.js.map +1 -1
- package/dist/web/routes/skill-stats.d.ts +2 -0
- package/dist/web/routes/skill-stats.d.ts.map +1 -1
- package/dist/web/routes/skill-stats.js +41 -39
- package/dist/web/routes/skill-stats.js.map +1 -1
- package/dist/web/routes/skills.d.ts.map +1 -1
- package/dist/web/routes/skills.js +39 -4
- package/dist/web/routes/skills.js.map +1 -1
- package/dist/web/routes/stats.d.ts +11 -0
- package/dist/web/routes/stats.d.ts.map +1 -0
- package/dist/web/routes/stats.js +42 -0
- package/dist/web/routes/stats.js.map +1 -0
- package/dist/web/routes/status.js +1 -1
- package/dist/web/routes/status.js.map +1 -1
- package/dist/web/routes/tasks.d.ts +4 -0
- package/dist/web/routes/tasks.d.ts.map +1 -0
- package/dist/web/routes/tasks.js +156 -0
- package/dist/web/routes/tasks.js.map +1 -0
- package/dist/web/routes/trace.d.ts +10 -0
- package/dist/web/routes/trace.d.ts.map +1 -0
- package/dist/web/routes/trace.js +113 -0
- package/dist/web/routes/trace.js.map +1 -0
- package/dist/web/routes/types.d.ts +1 -14
- package/dist/web/routes/types.d.ts.map +1 -1
- package/dist/web/routes/types.js +12 -20
- package/dist/web/routes/types.js.map +1 -1
- package/dist/web/server.d.ts +1 -9
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +28 -28
- package/dist/web/server.js.map +1 -1
- package/dist/web/static/assets/AIConfig-CdDWzJyO.js +2 -0
- package/dist/web/static/assets/AIConfig-CdDWzJyO.js.map +1 -0
- package/dist/web/static/assets/Dashboard-CoEmmIDt.js +2 -0
- package/dist/web/static/assets/Dashboard-CoEmmIDt.js.map +1 -0
- package/dist/web/static/assets/{Drawer-DcU3ln98.js → Drawer-DdRTzlLB.js} +2 -2
- package/dist/web/static/assets/{Drawer-DcU3ln98.js.map → Drawer-DdRTzlLB.js.map} +1 -1
- package/dist/web/static/assets/Events-DrIq1SUS.js +2 -0
- package/dist/web/static/assets/Events-DrIq1SUS.js.map +1 -0
- package/dist/web/static/assets/Reports-DFBM3MDK.js +2 -0
- package/dist/web/static/assets/Reports-DFBM3MDK.js.map +1 -0
- package/dist/web/static/assets/SearchInput-qCj_jAcf.js +2 -0
- package/dist/web/static/assets/SearchInput-qCj_jAcf.js.map +1 -0
- package/dist/web/static/assets/SessionDetail-CCzwdoT7.js +2 -0
- package/dist/web/static/assets/SessionDetail-CCzwdoT7.js.map +1 -0
- package/dist/web/static/assets/Sessions-FfLYkAw9.js +2 -0
- package/dist/web/static/assets/Sessions-FfLYkAw9.js.map +1 -0
- package/dist/web/static/assets/Skills-C8Gvs3Qa.js +2 -0
- package/dist/web/static/assets/Skills-C8Gvs3Qa.js.map +1 -0
- package/dist/web/static/assets/TaskDetail-BS8pYhaR.js +2 -0
- package/dist/web/static/assets/TaskDetail-BS8pYhaR.js.map +1 -0
- package/dist/web/static/assets/Tasks-CyuhizG8.js +2 -0
- package/dist/web/static/assets/Tasks-CyuhizG8.js.map +1 -0
- package/dist/web/static/assets/export-L_VBD2p1.js +4 -0
- package/dist/web/static/assets/export-L_VBD2p1.js.map +1 -0
- package/dist/web/static/assets/index-CBX47X8l.js +3 -0
- package/dist/web/static/assets/index-CBX47X8l.js.map +1 -0
- package/dist/web/static/assets/index-DjIoMdoR.css +1 -0
- package/dist/web/static/assets/{lucide-53bR2rki.js → lucide-Bs_edTLa.js} +73 -38
- package/dist/web/static/assets/lucide-Bs_edTLa.js.map +1 -0
- package/dist/web/static/assets/react-router-r79dBVy4.js +20 -0
- package/dist/web/static/assets/{react-router-I-HqunH7.js.map → react-router-r79dBVy4.js.map} +1 -1
- package/dist/web/static/assets/task-title-BhOcemuR.js +2 -0
- package/dist/web/static/assets/task-title-BhOcemuR.js.map +1 -0
- package/dist/web/static/assets/time-Bxuk0M-C.js +2 -0
- package/dist/web/static/assets/time-Bxuk0M-C.js.map +1 -0
- package/dist/web/static/index.html +4 -4
- package/docs/concurrent-agents.md +129 -0
- package/docs/design/architecture-review-20260516.md +232 -0
- package/docs/design/fix-skills-data-and-set-leak-spec-20260516-1300.md +219 -0
- package/docs/design/h1-storage-aggregation-spec-20260518-1121.md +299 -0
- package/docs/design/h2-getdatabase-encapsulation-spec-20260518-1450.md +191 -0
- package/docs/design/h3-fallback-removal-spec-20260518-1245.md +76 -0
- package/docs/design/h4-index-dedup-spec-20260518-1230.md +109 -0
- package/docs/design/h6-services-migration-spec-20260518-1355.md +82 -0
- package/docs/design/hook-failure-queue-spec-20260516-1530.md +204 -0
- package/docs/design/l1-swarm-protocol-extract-spec-20260518-1605.md +106 -0
- package/docs/design/m10-forge-paths-spec-20260518-1320.md +121 -0
- package/docs/design/m2-m3-tool-input-spec-20260518-1425.md +131 -0
- package/docs/design/m7-routing-event-association-spec-20260518-1545.md +103 -0
- package/docs/design/project-path-gitroot-spec-20260518-1715.md +134 -0
- package/docs/design/refactor-phase1-spec-20260515-1600.md +543 -0
- package/docs/design/refactor-phase2-spec-20260515-1700.md +424 -0
- package/docs/design/task-active-gc-spec-20260518-1745.md +146 -0
- package/docs/design/tasks-list-filter-pagination-spec-20260518-0930.md +208 -0
- package/docs/implementation/fix-skills-data-and-set-leak-changelog-20260516-1300.md +104 -0
- package/docs/implementation/h1-storage-aggregation-changelog-20260518-1121.md +82 -0
- package/docs/implementation/h2-final-changelog-20260518-1530.md +61 -0
- package/docs/implementation/h2-phase1-safety-net-changelog-20260518-1450.md +70 -0
- package/docs/implementation/h2-phase2-operations-changelog-20260518-1450.md +120 -0
- package/docs/implementation/h2-phase3-callsites-changelog-20260518-1450.md +71 -0
- package/docs/implementation/h3-fallback-removal-changelog-20260518-1245.md +71 -0
- package/docs/implementation/h4-index-dedup-changelog-20260518-1230.md +60 -0
- package/docs/implementation/h6-services-migration-changelog-20260518-1355.md +46 -0
- package/docs/implementation/h7-m9-defaults-changelog-20260518-1300.md +46 -0
- package/docs/implementation/hook-failure-queue-changelog-20260516-1530.md +196 -0
- package/docs/implementation/hotfix-daemon-event-reject-20260516-1430.md +56 -0
- package/docs/implementation/l1-swarm-protocol-extract-changelog-20260518-1605.md +45 -0
- package/docs/implementation/l3-l4-daemon-perf-changelog-20260518-1410.md +63 -0
- package/docs/implementation/l6-l8-final-cleanup-changelog-20260518-1640.md +38 -0
- package/docs/implementation/m1-m4-m5-l7-cleanup-changelog-20260518-1310.md +58 -0
- package/docs/implementation/m10-forge-paths-changelog-20260518-1320.md +60 -0
- package/docs/implementation/m2-m3-tool-input-changelog-20260518-1425.md +43 -0
- package/docs/implementation/m6-m8-naming-shutdown-changelog-20260518-1340.md +56 -0
- package/docs/implementation/m7-routing-association-changelog-20260518-1545.md +69 -0
- package/docs/implementation/project-path-gitroot-changelog-20260518-1715.md +63 -0
- package/docs/implementation/refactor-phase1-changelog-20260515-1630.md +354 -0
- package/docs/implementation/refactor-phase2-changelog-20260515-1705.md +421 -0
- package/docs/implementation/task-active-gc-changelog-20260518-1745.md +35 -0
- package/docs/implementation/task-title-summary-changelog-20260518-1130.md +39 -0
- package/docs/implementation/tasks-detail-back-loses-filters-changelog-20260518-1100.md +22 -0
- package/docs/implementation/tasks-list-filter-pagination-changelog-20260518-0930.md +72 -0
- package/docs/implementation/tasks-page-white-screen-hotfix-changelog-20260518-1015.md +56 -0
- package/docs/reviews/claudemd-template-sync.md +54 -0
- package/docs/reviews/task-title-summary.md +92 -0
- package/docs/reviews/tasks-detail-back-loses-filters.md +58 -0
- package/docs/reviews/tasks-filter-pagination.md +80 -0
- package/docs/reviews/tasks-page-white-screen-hotfix.md +126 -0
- package/docs/ruflo-learning-strategy.md +322 -0
- package/docs/skills-deduplication-analysis.md +83 -0
- package/docs/skills-multiformat-support.md +177 -0
- package/docs/skills-third-party.md +183 -0
- package/docs/testing/tasks-filter-pagination-test-report.md +86 -0
- package/forge +321 -0
- package/package.json +28 -62
- package/playwright.config.ts +40 -0
- package/scripts/demo-v2.ts +91 -0
- package/scripts/dev-daemon.sh +232 -0
- package/scripts/dev-web.ts +109 -0
- package/scripts/e2e-mcp-link.ts +423 -0
- package/scripts/e2e-methodology-quality.ts +253 -0
- package/scripts/e2e-routing.ts +456 -0
- package/scripts/e2e-user-methodology.ts +326 -0
- package/scripts/e2e-web-workflows.ts +299 -0
- package/scripts/migrate-legacy-to-dynamic.sql +108 -0
- package/scripts/regenerate-execution-docs.ts +116 -0
- package/scripts/sync-agent-skills.ts +193 -0
- package/scripts/test-hook.sh +71 -0
- package/scripts/verify-skill-loading.ts +62 -0
- package/src/claudemd/claudemd-generator.ts +568 -0
- package/src/claudemd/convention-extractor.ts +69 -0
- package/src/claudemd/index.ts +35 -0
- package/src/claudemd/persona-manager.ts +88 -0
- package/src/claudemd/resume-manager.ts +236 -0
- package/src/claudemd/tech-detector.ts +220 -0
- package/src/claudemd/templates/swarm-protocol.md +222 -0
- package/src/cli/commands/claudemd.ts +84 -0
- package/src/cli/commands/config.ts +46 -0
- package/src/cli/commands/daemon.ts +310 -0
- package/src/cli/commands/executions.ts +115 -0
- package/src/cli/commands/init.ts +204 -0
- package/src/cli/commands/logs.ts +181 -0
- package/src/cli/commands/mcp.ts +242 -0
- package/src/cli/commands/menu.ts +357 -0
- package/src/cli/commands/skills.ts +185 -0
- package/src/cli/commands/stats.ts +73 -0
- package/src/cli/commands/status.ts +69 -0
- package/src/cli/commands/template.ts +77 -0
- package/src/cli/commands/trace.ts +148 -0
- package/src/cli/index.ts +42 -0
- package/src/cli/init/hook-manager.ts +132 -0
- package/src/core/ai/provider.ts +308 -0
- package/src/core/ai/types.ts +51 -0
- package/src/core/config.ts +124 -0
- package/src/core/constants.ts +62 -0
- package/src/core/event-fields.ts +32 -0
- package/src/core/queue/index.ts +192 -0
- package/src/core/storage/base.ts +302 -0
- package/src/core/storage/events.ts +434 -0
- package/src/core/storage/injections.ts +78 -0
- package/src/core/storage/maintenance.ts +59 -0
- package/src/core/storage/migrations/002_add_skill_tracking.sql +6 -0
- package/src/core/storage/migrations/003_add_skill_invocations.sql +23 -0
- package/src/core/storage/performance-indexes.sql +23 -0
- package/src/core/storage/routing.ts +322 -0
- package/src/core/storage/rows.ts +112 -0
- package/src/core/storage/schema.sql +224 -0
- package/src/core/storage/sessions.ts +168 -0
- package/src/core/storage/skills.ts +233 -0
- package/src/core/storage/sqlite.ts +293 -0
- package/src/core/storage/tasks.ts +318 -0
- package/src/core/storage/token-usage.ts +93 -0
- package/src/core/types.ts +181 -0
- package/src/core/utils/error-handler.ts +257 -0
- package/src/core/utils/forge-resume-block.ts +74 -0
- package/src/core/utils/format.ts +69 -0
- package/src/core/utils/git.ts +23 -0
- package/src/core/utils/logger.ts +134 -0
- package/src/core/utils/lru-cache.ts +54 -0
- package/src/core/utils/path.ts +19 -0
- package/src/core/utils/session.ts +26 -0
- package/src/core/utils/time.ts +37 -0
- package/src/core/utils/token-tracker.ts +97 -0
- package/src/daemon/event-parser.ts +36 -0
- package/src/daemon/handlers/history-exporter.ts +117 -0
- package/src/daemon/handlers/post-tool-use.ts +54 -0
- package/src/daemon/handlers/stop.ts +208 -0
- package/src/daemon/handlers/user-prompt.ts +178 -0
- package/src/daemon/index.ts +292 -0
- package/src/daemon/launchd/com.claude-forge.daemon.plist.template +47 -0
- package/src/daemon/launchd-installer.ts +260 -0
- package/src/daemon/lifecycle.ts +128 -0
- package/src/daemon/router.ts +40 -0
- package/src/daemon/server.ts +196 -0
- package/src/daemon/services/task-segmenter.ts +112 -0
- package/src/hooks/hook-lib.sh +118 -0
- package/src/hooks/notification.sh +35 -0
- package/src/hooks/post-tool-use.sh +61 -0
- package/src/hooks/pre-tool-use.sh +63 -0
- package/src/hooks/stop.sh +43 -0
- package/src/hooks/user-prompt-submit.sh +69 -0
- package/src/mcp/server.ts +322 -0
- package/src/skills/index.ts +2 -0
- package/src/skills/invocation-guard.ts +177 -0
- package/src/skills/matcher.ts +148 -0
- package/src/skills/official/code-simplifier.md +16 -0
- package/src/skills/official/find-skills.md +23 -0
- package/src/skills/official/official-api-design.md +17 -0
- package/src/skills/official/official-architecture-decision.md +20 -0
- package/src/skills/official/official-bmad.md +118 -0
- package/src/skills/official/official-db-schema-design.md +16 -0
- package/src/skills/official/official-debug.md +17 -0
- package/src/skills/official/official-doc-driven.md +31 -0
- package/src/skills/official/official-harness-engineering.md +108 -0
- package/src/skills/official/official-performance-optimization.md +30 -0
- package/src/skills/official/official-pr-review.md +35 -0
- package/src/skills/official/official-release-checklist.md +30 -0
- package/src/skills/official/official-security-hardening.md +26 -0
- package/src/skills/official/official-spec-driven-design.md +31 -0
- package/src/skills/official/planning-with-files.md +37 -0
- package/src/skills/official/ui-ux-pro-max.md +18 -0
- package/src/skills/official/webapp-testing.md +12 -0
- package/src/skills/official-skills.ts +89 -0
- package/src/skills/registry.ts +355 -0
- package/src/skills/semantic-matcher.ts +231 -0
- package/src/skills/tools/pipeline-suggest.ts +226 -0
- package/src/skills/tools/skill-invoke.ts +168 -0
- package/src/skills/tools/skill-list.ts +59 -0
- package/src/templates/go.yaml +53 -0
- package/src/templates/python.yaml +59 -0
- package/src/templates/react.yaml +55 -0
- package/src/templates/template-manager.ts +170 -0
- package/src/web/analytics/anti-pattern-detector.ts +367 -0
- package/src/web/analytics/drift-detector.ts +219 -0
- package/src/web/analytics/weekly-report.ts +431 -0
- package/src/web/auth-middleware.ts +54 -0
- package/src/web/routes/_helpers.ts +34 -0
- package/src/web/routes/ai.ts +204 -0
- package/src/web/routes/auth.ts +22 -0
- package/src/web/routes/drift.ts +25 -0
- package/src/web/routes/error-handler.ts +120 -0
- package/src/web/routes/events.ts +47 -0
- package/src/web/routes/insights.ts +43 -0
- package/src/web/routes/patch.ts +117 -0
- package/src/web/routes/reports.ts +34 -0
- package/src/web/routes/rules.ts +76 -0
- package/src/web/routes/sessions.ts +250 -0
- package/src/web/routes/skill-stats.ts +92 -0
- package/src/web/routes/skills.ts +350 -0
- package/src/web/routes/static.ts +67 -0
- package/src/web/routes/stats.ts +50 -0
- package/src/web/routes/status.ts +30 -0
- package/src/web/routes/tasks.ts +193 -0
- package/src/web/routes/token-usage.ts +20 -0
- package/src/web/routes/trace.ts +126 -0
- package/src/web/routes/types.ts +57 -0
- package/src/web/server.ts +134 -0
- package/src/web/ssrf-guard.ts +112 -0
- package/src/web/static/index.html +3251 -0
- package/src/web/static/vendor/chart.umd.min.js +20 -0
- package/tests/e2e/dashboard.spec.ts +205 -0
- package/tests/e2e/routing-skill-e2e.test.ts +39 -0
- package/tests/helpers/mock-ai.ts +92 -0
- package/tests/helpers/mock-storage.ts +159 -0
- package/tests/integration/claudemd-generator.test.ts +90 -0
- package/tests/integration/queue-replay.integration.test.ts +193 -0
- package/tests/integration/tasks-filter.integration.test.ts +154 -0
- package/tests/integration/web-analytics.integration.test.ts +133 -0
- package/tests/integration/web-stats.integration.test.ts +135 -0
- package/tests/integration/web-trace.integration.test.ts +175 -0
- package/tests/performance/database.benchmark.ts +161 -0
- package/tests/semantic-matcher.test.ts +99 -0
- package/tests/skill-matcher.test.ts +110 -0
- package/tests/unit/ai-provider-retry.test.ts +194 -0
- package/tests/unit/ai-provider-vision.test.ts +224 -0
- package/tests/unit/claudemd-generator.test.ts +68 -0
- package/tests/unit/cli-mcp.test.ts +141 -0
- package/tests/unit/core/forge-paths.test.ts +99 -0
- package/tests/unit/daemon/post-tool-use.test.ts +121 -0
- package/tests/unit/daemon/stop-handler-behavior-summary.test.ts +202 -0
- package/tests/unit/daemon/task-segmenter-recover.test.ts +84 -0
- package/tests/unit/event-fields.test.ts +88 -0
- package/tests/unit/event-parser.test.ts +55 -0
- package/tests/unit/handlers.test.ts +171 -0
- package/tests/unit/hooks/resolve-project-path.test.ts +122 -0
- package/tests/unit/invocation-guard.test.ts +125 -0
- package/tests/unit/queue.test.ts +272 -0
- package/tests/unit/router.test.ts +138 -0
- package/tests/unit/security.test.ts +128 -0
- package/tests/unit/skill-invocations-workflow.test.ts +495 -0
- package/tests/unit/skill-registry.test.ts +94 -0
- package/tests/unit/skills/invocation-guard-ttl.test.ts +211 -0
- package/tests/unit/skills/official-skills-loader.test.ts +126 -0
- package/tests/unit/skills/registry-multiformat.test.ts +92 -0
- package/tests/unit/socket-server.test.ts +183 -0
- package/tests/unit/storage/event-operations-aggregates.test.ts +342 -0
- package/tests/unit/storage/migration-idempotent.test.ts +304 -0
- package/tests/unit/storage/routing-aggregates.test.ts +276 -0
- package/tests/unit/storage/routing.test.ts +117 -0
- package/tests/unit/storage/schema-missing.test.ts +81 -0
- package/tests/unit/storage/session-operations-aggregates.test.ts +120 -0
- package/tests/unit/storage/sessions-aggregate.test.ts +435 -0
- package/tests/unit/storage/skill-operations-counts.test.ts +106 -0
- package/tests/unit/storage/skills-aggregates.test.ts +104 -0
- package/tests/unit/storage/sqlite-refactor-harness.test.ts +314 -0
- package/tests/unit/storage/task-operations-counts.test.ts +46 -0
- package/tests/unit/storage/tasks-getById.test.ts +343 -0
- package/tests/unit/storage/tasks-stale-gc.test.ts +86 -0
- package/tests/unit/storage.test.ts +172 -0
- package/tests/unit/token-usage.test.ts +144 -0
- package/tests/unit/type-guards.test.ts +201 -0
- package/tests/unit/utils/format.test.ts +189 -0
- package/tests/unit/utils/session.test.ts +89 -0
- package/tests/unit/utils/time.test.ts +112 -0
- package/tests/unit/web/navigation-back-contract.test.ts +134 -0
- package/tests/unit/web/routes-auth.test.ts +93 -0
- package/tests/unit/web/routes-events.test.ts +101 -0
- package/tests/unit/web/routes-rules.test.ts +182 -0
- package/tests/unit/web/routes-sessions.test.ts +181 -0
- package/tests/unit/web/routes-skill-stats.test.ts +179 -0
- package/tests/unit/web/routes-stats.test.ts +92 -0
- package/tests/unit/web/routes-tasks.test.ts +385 -0
- package/tests/unit/web/task-title-contract.test.ts +210 -0
- package/tests/unit/web/tasks-component-contract.test.ts +179 -0
- package/tsconfig.json +22 -0
- package/vitest.config.ts +21 -0
- package/vitest.integration.config.ts +16 -0
- package/web/CLAUDE.md +20 -0
- package/web/index.html +13 -0
- package/web/package-lock.json +4854 -0
- package/web/package.json +35 -0
- package/web/postcss.config.js +6 -0
- package/web/src/App.tsx +110 -0
- package/web/src/components/CodeBlock.tsx +31 -0
- package/web/src/components/Confirm.tsx +96 -0
- package/web/src/components/Drawer.tsx +60 -0
- package/web/src/components/Layout.tsx +145 -0
- package/web/src/components/MarkdownRenderer.tsx +77 -0
- package/web/src/components/SearchInput.tsx +31 -0
- package/web/src/components/SessionDetailContent.tsx +157 -0
- package/web/src/components/Toast.tsx +92 -0
- package/web/src/index.css +19 -0
- package/web/src/main.tsx +31 -0
- package/web/src/pages/AIConfig.tsx +233 -0
- package/web/src/pages/Dashboard.tsx +572 -0
- package/web/src/pages/Events.tsx +271 -0
- package/web/src/pages/Reports.tsx +428 -0
- package/web/src/pages/SessionDetail.tsx +162 -0
- package/web/src/pages/Sessions.tsx +205 -0
- package/web/src/pages/Skills.tsx +180 -0
- package/web/src/pages/TaskDetail.tsx +515 -0
- package/web/src/pages/Tasks.tsx +415 -0
- package/web/src/utils/auth.ts +59 -0
- package/web/src/utils/export.ts +54 -0
- package/web/src/utils/navigation.ts +25 -0
- package/web/src/utils/task-title.ts +49 -0
- package/web/src/utils/time.ts +13 -0
- package/web/tailwind.config.js +11 -0
- package/web/tsconfig.json +21 -0
- package/web/tsconfig.node.json +10 -0
- package/web/vite.config.ts +76 -0
- package/winspan-claude-forge-8.43.0.tgz +0 -0
- package/dist/agents/definition.d.ts +0 -62
- package/dist/agents/definition.d.ts.map +0 -1
- package/dist/agents/definition.js +0 -27
- package/dist/agents/definition.js.map +0 -1
- package/dist/agents/distributor.d.ts +0 -23
- package/dist/agents/distributor.d.ts.map +0 -1
- package/dist/agents/distributor.js +0 -85
- package/dist/agents/distributor.js.map +0 -1
- package/dist/agents/index.d.ts +0 -5
- package/dist/agents/index.d.ts.map +0 -1
- package/dist/agents/index.js +0 -5
- package/dist/agents/index.js.map +0 -1
- package/dist/agents/methodologies/agent-builder.d.ts +0 -21
- package/dist/agents/methodologies/agent-builder.d.ts.map +0 -1
- package/dist/agents/methodologies/agent-builder.js +0 -149
- package/dist/agents/methodologies/agent-builder.js.map +0 -1
- package/dist/agents/methodologies/phases/bmad/analyze.d.ts +0 -3
- package/dist/agents/methodologies/phases/bmad/analyze.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/bmad/analyze.js +0 -19
- package/dist/agents/methodologies/phases/bmad/analyze.js.map +0 -1
- package/dist/agents/methodologies/phases/bmad/design.d.ts +0 -3
- package/dist/agents/methodologies/phases/bmad/design.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/bmad/design.js +0 -18
- package/dist/agents/methodologies/phases/bmad/design.js.map +0 -1
- package/dist/agents/methodologies/phases/bmad/implement.d.ts +0 -3
- package/dist/agents/methodologies/phases/bmad/implement.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/bmad/implement.js +0 -17
- package/dist/agents/methodologies/phases/bmad/implement.js.map +0 -1
- package/dist/agents/methodologies/phases/bmad/index.d.ts +0 -6
- package/dist/agents/methodologies/phases/bmad/index.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/bmad/index.js +0 -6
- package/dist/agents/methodologies/phases/bmad/index.js.map +0 -1
- package/dist/agents/methodologies/phases/bmad/review.d.ts +0 -3
- package/dist/agents/methodologies/phases/bmad/review.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/bmad/review.js +0 -17
- package/dist/agents/methodologies/phases/bmad/review.js.map +0 -1
- package/dist/agents/methodologies/phases/bmad/test.d.ts +0 -3
- package/dist/agents/methodologies/phases/bmad/test.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/bmad/test.js +0 -21
- package/dist/agents/methodologies/phases/bmad/test.js.map +0 -1
- package/dist/agents/methodologies/phases/harness/fix.d.ts +0 -3
- package/dist/agents/methodologies/phases/harness/fix.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/harness/fix.js +0 -17
- package/dist/agents/methodologies/phases/harness/fix.js.map +0 -1
- package/dist/agents/methodologies/phases/harness/index.d.ts +0 -6
- package/dist/agents/methodologies/phases/harness/index.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/harness/index.js +0 -6
- package/dist/agents/methodologies/phases/harness/index.js.map +0 -1
- package/dist/agents/methodologies/phases/harness/reproduce.d.ts +0 -3
- package/dist/agents/methodologies/phases/harness/reproduce.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/harness/reproduce.js +0 -20
- package/dist/agents/methodologies/phases/harness/reproduce.js.map +0 -1
- package/dist/agents/methodologies/phases/harness/root-cause.d.ts +0 -3
- package/dist/agents/methodologies/phases/harness/root-cause.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/harness/root-cause.js +0 -21
- package/dist/agents/methodologies/phases/harness/root-cause.js.map +0 -1
- package/dist/agents/methodologies/phases/harness/safety-net.d.ts +0 -3
- package/dist/agents/methodologies/phases/harness/safety-net.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/harness/safety-net.js +0 -17
- package/dist/agents/methodologies/phases/harness/safety-net.js.map +0 -1
- package/dist/agents/methodologies/phases/harness/verify.d.ts +0 -3
- package/dist/agents/methodologies/phases/harness/verify.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/harness/verify.js +0 -22
- package/dist/agents/methodologies/phases/harness/verify.js.map +0 -1
- package/dist/agents/methodologies/presets.d.ts +0 -10
- package/dist/agents/methodologies/presets.d.ts.map +0 -1
- package/dist/agents/methodologies/presets.js +0 -79
- package/dist/agents/methodologies/presets.js.map +0 -1
- package/dist/agents/methodologies/types.d.ts +0 -45
- package/dist/agents/methodologies/types.d.ts.map +0 -1
- package/dist/agents/methodologies/types.js +0 -10
- package/dist/agents/methodologies/types.js.map +0 -1
- package/dist/agents/methodologies/user-config-loader.d.ts +0 -30
- package/dist/agents/methodologies/user-config-loader.d.ts.map +0 -1
- package/dist/agents/methodologies/user-config-loader.js +0 -159
- package/dist/agents/methodologies/user-config-loader.js.map +0 -1
- package/dist/agents/official-agents.d.ts +0 -4
- package/dist/agents/official-agents.d.ts.map +0 -1
- package/dist/agents/official-agents.js +0 -559
- package/dist/agents/official-agents.js.map +0 -1
- package/dist/agents/registry.d.ts +0 -57
- package/dist/agents/registry.d.ts.map +0 -1
- package/dist/agents/registry.js +0 -271
- package/dist/agents/registry.js.map +0 -1
- package/dist/capability/index.d.ts +0 -10
- package/dist/capability/index.d.ts.map +0 -1
- package/dist/capability/index.js +0 -10
- package/dist/capability/index.js.map +0 -1
- package/dist/capability/types.d.ts +0 -10
- package/dist/capability/types.d.ts.map +0 -1
- package/dist/capability/types.js +0 -10
- package/dist/capability/types.js.map +0 -1
- package/dist/cli/commands/agents.d.ts +0 -3
- package/dist/cli/commands/agents.d.ts.map +0 -1
- package/dist/cli/commands/agents.js +0 -62
- package/dist/cli/commands/agents.js.map +0 -1
- package/dist/cli/commands/rules.d.ts +0 -8
- package/dist/cli/commands/rules.d.ts.map +0 -1
- package/dist/cli/commands/rules.js +0 -89
- package/dist/cli/commands/rules.js.map +0 -1
- package/dist/daemon/auto-disable-scheduler.d.ts +0 -53
- package/dist/daemon/auto-disable-scheduler.d.ts.map +0 -1
- package/dist/daemon/auto-disable-scheduler.js +0 -114
- package/dist/daemon/auto-disable-scheduler.js.map +0 -1
- package/dist/daemon/handlers/pre-tool-use.d.ts +0 -39
- package/dist/daemon/handlers/pre-tool-use.d.ts.map +0 -1
- package/dist/daemon/handlers/pre-tool-use.js +0 -166
- package/dist/daemon/handlers/pre-tool-use.js.map +0 -1
- package/dist/daemon/routing-observer.d.ts +0 -42
- package/dist/daemon/routing-observer.d.ts.map +0 -1
- package/dist/daemon/routing-observer.js +0 -264
- package/dist/daemon/routing-observer.js.map +0 -1
- package/dist/daemon/routing-state.d.ts +0 -64
- package/dist/daemon/routing-state.d.ts.map +0 -1
- package/dist/daemon/routing-state.js +0 -240
- package/dist/daemon/routing-state.js.map +0 -1
- package/dist/engine/agent-router.d.ts +0 -142
- package/dist/engine/agent-router.d.ts.map +0 -1
- package/dist/engine/agent-router.js +0 -276
- package/dist/engine/agent-router.js.map +0 -1
- package/dist/engine/context-builder.d.ts +0 -23
- package/dist/engine/context-builder.d.ts.map +0 -1
- package/dist/engine/context-builder.js +0 -63
- package/dist/engine/context-builder.js.map +0 -1
- package/dist/engine/conventions/basic-security.yaml +0 -109
- package/dist/engine/conventions/code-quality.yaml +0 -123
- package/dist/engine/conventions/database-safety.yaml +0 -74
- package/dist/engine/conventions/dependency-safety.yaml +0 -132
- package/dist/engine/conventions/docker-safety.yaml +0 -69
- package/dist/engine/conventions/git-safety.yaml +0 -118
- package/dist/engine/conventions/go-best-practices.yaml +0 -84
- package/dist/engine/conventions/python-best-practices.yaml +0 -96
- package/dist/engine/conventions/react-best-practices.yaml +0 -96
- package/dist/engine/conventions/routing.yaml +0 -378
- package/dist/engine/conventions/strict-security.yaml +0 -30
- package/dist/engine/conventions/ts-quality.yaml +0 -49
- package/dist/engine/dsl/compiler.d.ts +0 -34
- package/dist/engine/dsl/compiler.d.ts.map +0 -1
- package/dist/engine/dsl/compiler.js +0 -702
- package/dist/engine/dsl/compiler.js.map +0 -1
- package/dist/engine/dsl/parser.d.ts +0 -25
- package/dist/engine/dsl/parser.d.ts.map +0 -1
- package/dist/engine/dsl/parser.js +0 -208
- package/dist/engine/dsl/parser.js.map +0 -1
- package/dist/engine/dsl/runtime.d.ts +0 -46
- package/dist/engine/dsl/runtime.d.ts.map +0 -1
- package/dist/engine/dsl/runtime.js +0 -173
- package/dist/engine/dsl/runtime.js.map +0 -1
- package/dist/engine/dsl/types.d.ts +0 -139
- package/dist/engine/dsl/types.d.ts.map +0 -1
- package/dist/engine/dsl/types.js +0 -11
- package/dist/engine/dsl/types.js.map +0 -1
- package/dist/engine/evidence-store.d.ts +0 -44
- package/dist/engine/evidence-store.d.ts.map +0 -1
- package/dist/engine/evidence-store.js +0 -109
- package/dist/engine/evidence-store.js.map +0 -1
- package/dist/engine/experiment-router.d.ts +0 -102
- package/dist/engine/experiment-router.d.ts.map +0 -1
- package/dist/engine/experiment-router.js +0 -289
- package/dist/engine/experiment-router.js.map +0 -1
- package/dist/engine/recommender.d.ts +0 -52
- package/dist/engine/recommender.d.ts.map +0 -1
- package/dist/engine/recommender.js +0 -162
- package/dist/engine/recommender.js.map +0 -1
- package/dist/engine/rule-engine.d.ts +0 -33
- package/dist/engine/rule-engine.d.ts.map +0 -1
- package/dist/engine/rule-engine.js +0 -250
- package/dist/engine/rule-engine.js.map +0 -1
- package/dist/engine/security-gates.d.ts +0 -42
- package/dist/engine/security-gates.d.ts.map +0 -1
- package/dist/engine/security-gates.js +0 -210
- package/dist/engine/security-gates.js.map +0 -1
- package/dist/intelligence/classifier.d.ts +0 -75
- package/dist/intelligence/classifier.d.ts.map +0 -1
- package/dist/intelligence/classifier.js +0 -352
- package/dist/intelligence/classifier.js.map +0 -1
- package/dist/intelligence/context-gatherer.d.ts +0 -101
- package/dist/intelligence/context-gatherer.d.ts.map +0 -1
- package/dist/intelligence/context-gatherer.js +0 -417
- package/dist/intelligence/context-gatherer.js.map +0 -1
- package/dist/intelligence/cot-classifier.d.ts +0 -95
- package/dist/intelligence/cot-classifier.d.ts.map +0 -1
- package/dist/intelligence/cot-classifier.js +0 -391
- package/dist/intelligence/cot-classifier.js.map +0 -1
- package/dist/intelligence/distiller.d.ts +0 -22
- package/dist/intelligence/distiller.d.ts.map +0 -1
- package/dist/intelligence/distiller.js +0 -108
- package/dist/intelligence/distiller.js.map +0 -1
- package/dist/intelligence/execution-doc-builder.d.ts +0 -151
- package/dist/intelligence/execution-doc-builder.d.ts.map +0 -1
- package/dist/intelligence/execution-doc-builder.js +0 -1018
- package/dist/intelligence/execution-doc-builder.js.map +0 -1
- package/dist/intelligence/intent-types.d.ts +0 -13
- package/dist/intelligence/intent-types.d.ts.map +0 -1
- package/dist/intelligence/intent-types.js +0 -19
- package/dist/intelligence/intent-types.js.map +0 -1
- package/dist/intelligence/multimodal-parser.d.ts +0 -105
- package/dist/intelligence/multimodal-parser.d.ts.map +0 -1
- package/dist/intelligence/multimodal-parser.js +0 -425
- package/dist/intelligence/multimodal-parser.js.map +0 -1
- package/dist/intelligence/quality-gate.d.ts +0 -45
- package/dist/intelligence/quality-gate.d.ts.map +0 -1
- package/dist/intelligence/quality-gate.js +0 -193
- package/dist/intelligence/quality-gate.js.map +0 -1
- package/dist/intelligence/task-segmenter.d.ts.map +0 -1
- package/dist/intelligence/task-segmenter.js.map +0 -1
- package/dist/web/routes/agents.d.ts +0 -7
- package/dist/web/routes/agents.d.ts.map +0 -1
- package/dist/web/routes/agents.js +0 -209
- package/dist/web/routes/agents.js.map +0 -1
- package/dist/web/routes/execution-trace.d.ts +0 -21
- package/dist/web/routes/execution-trace.d.ts.map +0 -1
- package/dist/web/routes/execution-trace.js +0 -353
- package/dist/web/routes/execution-trace.js.map +0 -1
- package/dist/web/routes/experiments.d.ts +0 -15
- package/dist/web/routes/experiments.d.ts.map +0 -1
- package/dist/web/routes/experiments.js +0 -187
- package/dist/web/routes/experiments.js.map +0 -1
- package/dist/web/routes/routing.d.ts +0 -17
- package/dist/web/routes/routing.d.ts.map +0 -1
- package/dist/web/routes/routing.js +0 -592
- package/dist/web/routes/routing.js.map +0 -1
- package/dist/web/routes/workflows.d.ts +0 -19
- package/dist/web/routes/workflows.d.ts.map +0 -1
- package/dist/web/routes/workflows.js +0 -86
- package/dist/web/routes/workflows.js.map +0 -1
- package/dist/web/static/assets/AIConfig-R5wZ3ZKT.js +0 -2
- package/dist/web/static/assets/AIConfig-R5wZ3ZKT.js.map +0 -1
- package/dist/web/static/assets/Agents-Beg34V1g.js +0 -2
- package/dist/web/static/assets/Agents-Beg34V1g.js.map +0 -1
- package/dist/web/static/assets/CodeBlock--H53gk46.js +0 -2
- package/dist/web/static/assets/CodeBlock--H53gk46.js.map +0 -1
- package/dist/web/static/assets/Dashboard-Cy1xsj1J.js +0 -2
- package/dist/web/static/assets/Dashboard-Cy1xsj1J.js.map +0 -1
- package/dist/web/static/assets/Events-mFhXl4zI.js +0 -2
- package/dist/web/static/assets/Events-mFhXl4zI.js.map +0 -1
- package/dist/web/static/assets/ExecutionTrace-DG901hLR.js +0 -3
- package/dist/web/static/assets/ExecutionTrace-DG901hLR.js.map +0 -1
- package/dist/web/static/assets/MarkdownRenderer-CCIz1MOz.js +0 -2
- package/dist/web/static/assets/MarkdownRenderer-CCIz1MOz.js.map +0 -1
- package/dist/web/static/assets/Routing-B7BFLfjh.js +0 -2
- package/dist/web/static/assets/Routing-B7BFLfjh.js.map +0 -1
- package/dist/web/static/assets/SessionDetail-BT0l4RrK.js +0 -2
- package/dist/web/static/assets/SessionDetail-BT0l4RrK.js.map +0 -1
- package/dist/web/static/assets/Sessions-C6J_HQ_u.js +0 -2
- package/dist/web/static/assets/Sessions-C6J_HQ_u.js.map +0 -1
- package/dist/web/static/assets/Skills-4DQWLaTv.js +0 -2
- package/dist/web/static/assets/Skills-4DQWLaTv.js.map +0 -1
- package/dist/web/static/assets/WorkflowDetail-zhNqUkBE.js +0 -2
- package/dist/web/static/assets/WorkflowDetail-zhNqUkBE.js.map +0 -1
- package/dist/web/static/assets/Workflows-Btvi-lGw.js +0 -2
- package/dist/web/static/assets/Workflows-Btvi-lGw.js.map +0 -1
- package/dist/web/static/assets/export-BQQZLaHV.js +0 -4
- package/dist/web/static/assets/export-BQQZLaHV.js.map +0 -1
- package/dist/web/static/assets/index-Cgr9qMtq.js +0 -3
- package/dist/web/static/assets/index-Cgr9qMtq.js.map +0 -1
- package/dist/web/static/assets/index-CngWb5gC.css +0 -1
- package/dist/web/static/assets/lucide-53bR2rki.js.map +0 -1
- package/dist/web/static/assets/react-router-I-HqunH7.js +0 -20
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# H4: DB 索引/列去重 Spec
|
|
2
|
+
|
|
3
|
+
## 目标
|
|
4
|
+
消除 `schema.sql` 与 `base.ts::runMigrations` 之间的索引/列重复定义,让 schema.sql 成为新库权威源,runMigrations 只承担"存量库补齐"的职责,并保持 idempotent。
|
|
5
|
+
|
|
6
|
+
## 涉及文件
|
|
7
|
+
- `src/core/storage/schema.sql`(权威 schema,新库初始化)
|
|
8
|
+
- `src/core/storage/base.ts`(migration 入口,存量库补齐)
|
|
9
|
+
|
|
10
|
+
## 重复清单
|
|
11
|
+
|
|
12
|
+
| 名称 | schema.sql | base.ts | 类型 | 备注 |
|
|
13
|
+
|------|------------|---------|------|------|
|
|
14
|
+
| `first_prompt` | L55 | L99 | column | schema 已含,migration 仍 ALTER |
|
|
15
|
+
| `skill_confidence` | L139 | L101 | column | 同上 |
|
|
16
|
+
| `skill_source` | L140 | L102 | column | 同上 |
|
|
17
|
+
| `workflow` | L178 | L104 | column | 同上 |
|
|
18
|
+
| `phase` | L179 | L105 | column | 同上 |
|
|
19
|
+
| `feature_slug` | L180 | L106 | column | 同上 |
|
|
20
|
+
| `artifact_path` | L181 | L107 | column | 同上 |
|
|
21
|
+
| `idx_sessions_start_time` | L66 | L119 | index | 双写 |
|
|
22
|
+
| `idx_events_session_ts` | L198 | L127 | index | 双写 |
|
|
23
|
+
| `idx_routing_events_session_ts` | L199 | L128 | index | 双写 |
|
|
24
|
+
| `idx_skill_invocations_session_ts` | L200 | L129 | index | 双写 |
|
|
25
|
+
| `idx_routing_events_obeyed_ts` | L205 | L138 | index | 双写 |
|
|
26
|
+
| `idx_events_session_hook` | L211 | L139 | index | 双写 |
|
|
27
|
+
| `idx_injections_session_handler` | L214 | L140 | index | 双写 |
|
|
28
|
+
| `idx_routing_events_type_ts` | L217 | L141 | index | 双写(H1 新增)|
|
|
29
|
+
| `idx_skill_invocations_workflow` | 缺 | L111 | index | **仅 migration**,应补到 schema |
|
|
30
|
+
| `idx_skill_invocations_feature` | 缺 | L112 | index | 同上 |
|
|
31
|
+
|
|
32
|
+
## 设计方案
|
|
33
|
+
|
|
34
|
+
### 决策:方案 B(保留 idempotent 双写 + 显式 has 判断)
|
|
35
|
+
|
|
36
|
+
**理由**:
|
|
37
|
+
- 简单删 base.ts 的 `CREATE INDEX IF NOT EXISTS` 会导致存量库(旧版未跑过 H1 migration 的用户)永远缺索引;migration 必须保留补齐能力。
|
|
38
|
+
- 不能依赖"新装用户走 schema.sql、老用户走 migration"——同一份 base.ts 两端都跑。
|
|
39
|
+
- 索引层面 `CREATE INDEX IF NOT EXISTS` 本身已 idempotent,"双写"代价仅是一次 PRAGMA 查表,可接受。
|
|
40
|
+
- 列层面 ALTER TABLE 无 IF NOT EXISTS,必须靠 `hasColumn`(已存在)守护。
|
|
41
|
+
|
|
42
|
+
### 选定方案的详细做法
|
|
43
|
+
|
|
44
|
+
1. **schema.sql** 补两条缺失的索引:
|
|
45
|
+
- `idx_skill_invocations_workflow ON skill_invocations(workflow, phase)`
|
|
46
|
+
- `idx_skill_invocations_feature ON skill_invocations(feature_slug)`
|
|
47
|
+
这样新库一次成型,migration 块只是"防御性补齐"。
|
|
48
|
+
|
|
49
|
+
2. **base.ts::runMigrations** 全部改造为 has 判断守护:
|
|
50
|
+
- 列:维持 `addColumnIfMissing`(已有 hasColumn)。
|
|
51
|
+
- 索引:新增 `hasIndex(name)` 工具;每个 migration 索引创建前先判断 `if (!this.hasIndex(name)) exec(...)`,跳过则记一行 debug 日志。
|
|
52
|
+
- 目的不是性能(CREATE INDEX IF NOT EXISTS 已便宜),而是让"哪些索引由 migration 补齐"显式可读、便于日后裁剪。
|
|
53
|
+
|
|
54
|
+
3. **删除 inline fallback**(base.ts L57-72)—— 如果 schema.sql 缺失,应直接抛错而不是用残缺 schema 启动;保留只会埋坑。可在 spec 里建议但放在 H4 之外。**本次 H4 不动它**,仅注释 TODO。
|
|
55
|
+
|
|
56
|
+
### 新增工具函数(base.ts)
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
protected hasIndex(name: string): boolean {
|
|
60
|
+
try {
|
|
61
|
+
const row = this.db
|
|
62
|
+
.prepare(`SELECT name FROM sqlite_master WHERE type='index' AND name = ?`)
|
|
63
|
+
.get(name);
|
|
64
|
+
return !!row;
|
|
65
|
+
} catch { return false; }
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
注:`pragma_index_list(table)` 需要知道表名,而 `sqlite_master` 直接按索引名查更简单。
|
|
70
|
+
|
|
71
|
+
## 测试策略
|
|
72
|
+
|
|
73
|
+
新增 `tests/unit/storage/migration-idempotent.test.ts`:
|
|
74
|
+
|
|
75
|
+
1. **baseline(旧库补齐)**:
|
|
76
|
+
- 建临时 db,先 exec 一份"H1 之前的旧 schema"(手写删掉 `idx_routing_events_type_ts` 等)+ 缺 `first_prompt` 列。
|
|
77
|
+
- 用 `new SQLiteStorage(path)` 启动,断言所有重复清单中的索引/列都已存在(`sqlite_master` + `PRAGMA table_info`)。
|
|
78
|
+
|
|
79
|
+
2. **新库无害**:
|
|
80
|
+
- 临时 db 走完整 `schema.sql` 初始化。
|
|
81
|
+
- 再实例化一次 SQLiteStorage,断言 migration 不抛错、不重复创建(spy `db.exec` 调用次数或检查 logger.warn 无输出)。
|
|
82
|
+
|
|
83
|
+
3. **idempotent(多次启动)**:
|
|
84
|
+
- 同一 db 连续 `new SQLiteStorage()` 3 次。
|
|
85
|
+
- 断言索引数量、列数量两次之间相等;断言 logger 无 error/warn。
|
|
86
|
+
|
|
87
|
+
4. **现有测试回归**:跑 `npx vitest run src/tests/storage*.test.ts` 与 `tests/unit/storage/`。
|
|
88
|
+
|
|
89
|
+
## 实施顺序
|
|
90
|
+
|
|
91
|
+
1. schema.sql 补 `idx_skill_invocations_workflow` / `idx_skill_invocations_feature`
|
|
92
|
+
2. base.ts 加 `hasIndex`
|
|
93
|
+
3. base.ts::runMigrations 所有 `CREATE INDEX IF NOT EXISTS` 用 `if (!this.hasIndex(...))` 守护
|
|
94
|
+
4. 新增 `tests/unit/storage/migration-idempotent.test.ts`
|
|
95
|
+
5. 跑 `npx vitest run tests/unit/storage` + `npx tsc --noEmit`
|
|
96
|
+
6. 跑全量 `npm test`
|
|
97
|
+
|
|
98
|
+
## 风险与回滚
|
|
99
|
+
|
|
100
|
+
- **风险**:存量数据库(线上用户)必须能补齐 → baseline 测试是硬门槛,CI 必跑。
|
|
101
|
+
- **风险**:`hasIndex` 名字查询不区分表(同名索引理论上不会跨表,SQLite 索引名全局唯一)—— 实际安全。
|
|
102
|
+
- **回滚**:所有改动局限在 schema.sql + base.ts + 1 个新测试,`git revert` 单 commit 即可。
|
|
103
|
+
- **不动 inline fallback**:H4 范围之外,避免一次改太多。
|
|
104
|
+
|
|
105
|
+
## 命名遵循
|
|
106
|
+
|
|
107
|
+
- `hasIndex` / `hasColumn`:has 前缀 → 符合 CLAUDE.md "布尔值用 is/has/should 前缀"。
|
|
108
|
+
- 测试文件名 `migration-idempotent.test.ts`:kebab-case + `.test.ts` → 符合命名规范。
|
|
109
|
+
- 工具函数 `hasIndex` 与已有 `hasColumn` 并列,对称命名。
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# H6: daemon/services analytics 类迁移 Spec
|
|
2
|
+
|
|
3
|
+
## 目标
|
|
4
|
+
将 3 个纯查询/聚合类从 `src/daemon/services/` 迁出,纠正位置错配,使依赖图反映真实调用方向(仅 web 层使用)。
|
|
5
|
+
|
|
6
|
+
## 调研结果
|
|
7
|
+
|
|
8
|
+
### 调用链
|
|
9
|
+
| 类 | 文件 | daemon 调用 | web 调用 | cli 调用 |
|
|
10
|
+
|---|---|---|---|---|
|
|
11
|
+
| DriftDetector | `src/daemon/services/drift-detector.ts` | 0 | `web/routes/drift.ts:3,21` | 0 |
|
|
12
|
+
| WeeklyReportGenerator | `src/daemon/services/weekly-report.ts`(注意:非 `weekly-report-generator.ts`) | 0 | `web/routes/reports.ts:10,20` | 0 |
|
|
13
|
+
| AntiPatternDetector | `src/daemon/services/anti-pattern-detector.ts` | 0 | `web/routes/insights.ts:4,7,25` | 0 |
|
|
14
|
+
|
|
15
|
+
`src/daemon/{index,handlers,pipeline}` 全无引用。同目录的 `task-segmenter.ts` 是真 daemon 服务(`daemon/index.ts:28,105` + `handlers/stop.ts:14,27`),**留在原地**。
|
|
16
|
+
|
|
17
|
+
### 依赖关系
|
|
18
|
+
3 个文件 imports 仅有:
|
|
19
|
+
- `core/storage/sqlite` (SQLiteStorage 类型)
|
|
20
|
+
- `core/storage/sessions` (SessionSummary 类型,仅 anti-pattern)
|
|
21
|
+
- `core/types` (ForgeEvent,仅 anti-pattern)
|
|
22
|
+
- `node:crypto`(标准库)
|
|
23
|
+
|
|
24
|
+
**零 daemon 内部依赖** → 无反向依赖风险。注意 `weekly-report.ts:20` 构造时还接收 `skillRegistry`(来自 `web/routes/reports.ts` 的 ctx),但类型来源属 core 层,安全。
|
|
25
|
+
|
|
26
|
+
### 现有测试
|
|
27
|
+
- 单元测试:**无**(3 个文件 + 3 个调用方 routes 均无 `.test.ts`)
|
|
28
|
+
- 集成测试覆盖路由:**无**(`tests/` 下无 drift/report/insight/anti-pattern 测试)
|
|
29
|
+
- 现有 web 路由测试:sessions/stats/skill-stats/events/auth/tasks/rules(均不覆盖本次迁移路径)
|
|
30
|
+
|
|
31
|
+
## 目标目录决策
|
|
32
|
+
|
|
33
|
+
**推荐:`src/web/analytics/`**
|
|
34
|
+
|
|
35
|
+
理由:
|
|
36
|
+
1. 实际调用方 100% 是 `web/routes/`,符合"用在哪放在哪"
|
|
37
|
+
2. 当前无 cli/daemon 消费,提升到 core 是过度设计;未来若 cli 需要再上提成本低
|
|
38
|
+
3. 与同层模块 `web/routes/`、`web/static/` 平行,依赖方向天然向下(web → core)
|
|
39
|
+
|
|
40
|
+
## 改造范围
|
|
41
|
+
|
|
42
|
+
| 操作 | 来源 → 目标 / 修改点 |
|
|
43
|
+
|---|---|
|
|
44
|
+
| git mv | `src/daemon/services/drift-detector.ts` → `src/web/analytics/drift-detector.ts` |
|
|
45
|
+
| git mv | `src/daemon/services/weekly-report.ts` → `src/web/analytics/weekly-report.ts` |
|
|
46
|
+
| git mv | `src/daemon/services/anti-pattern-detector.ts` → `src/web/analytics/anti-pattern-detector.ts` |
|
|
47
|
+
| 改 import | `src/web/routes/drift.ts:3` → `'../analytics/drift-detector.js'` |
|
|
48
|
+
| 改 import | `src/web/routes/reports.ts:10` → `'../analytics/weekly-report.js'` |
|
|
49
|
+
| 改 import | `src/web/routes/insights.ts:7` → `'../analytics/anti-pattern-detector.js'` |
|
|
50
|
+
| 清理注释 | `weekly-report.ts:294`、`anti-pattern-detector.ts:80` 引用"daemon/services 既定做法"的文字 |
|
|
51
|
+
| barrel | **不建** `index.ts`(仅 3 个文件、3 个调用方,barrel 收益低) |
|
|
52
|
+
| 保留 | `src/daemon/services/task-segmenter.ts` 原地不动 |
|
|
53
|
+
|
|
54
|
+
## 测试策略
|
|
55
|
+
|
|
56
|
+
- **safety-net(必做)**:迁移前补一个最小集成测试 baseline
|
|
57
|
+
- `tests/integration/web-analytics.integration.test.ts`:分别 GET `/api/drift`、`/api/reports/weekly`、`/api/insights`,断言 200 + 关键字段存在(不校验业务正确性,只校验 wiring 没断)
|
|
58
|
+
- **回归**:`npx tsc --noEmit` + `npm test` 全量
|
|
59
|
+
- **手测**:`./scripts/dev-daemon.sh restart` 后 `curl` 3 个 endpoint
|
|
60
|
+
|
|
61
|
+
## 风险与回滚
|
|
62
|
+
|
|
63
|
+
- 风险 1:dist/ 残留旧路径 → `npm run build` 前清理 `dist/daemon/services/{drift,weekly,anti}*`
|
|
64
|
+
- 风险 2:第三方/外部脚本 import 旧路径 → 已 grep 确认仅 src/ 内部使用,无外部入口
|
|
65
|
+
- 风险 3:`weekly-report.ts:294` 注释提到 anti-pattern-detector 协作历史,迁移后描述失真(仅文档影响)
|
|
66
|
+
- 回滚:`git mv` 保留 history,单 commit 完成;失败 `git revert <hash>` 即可
|
|
67
|
+
|
|
68
|
+
## 实施顺序
|
|
69
|
+
|
|
70
|
+
1. 补 safety-net 集成测试(独立 commit,验证当前 main 通过)
|
|
71
|
+
2. `mkdir -p src/web/analytics`
|
|
72
|
+
3. `git mv` 3 个文件(一个 commit)
|
|
73
|
+
4. 改 3 处 import + 清理 2 处误导注释(同 commit 或下一 commit)
|
|
74
|
+
5. `npx tsc --noEmit` → `npm test` → daemon 重启 + curl 三 endpoint
|
|
75
|
+
6. 提交 PR / push
|
|
76
|
+
|
|
77
|
+
## 命名遵循
|
|
78
|
+
|
|
79
|
+
- 文件名 kebab-case ✓(保持原名)
|
|
80
|
+
- 类名 PascalCase ✓(无改动)
|
|
81
|
+
- 目录 `web/analytics/` 全小写 ✓
|
|
82
|
+
- 注意:源文件叫 `weekly-report.ts` 而非任务描述里写的 `weekly-report-generator.ts`,spec 以实际文件名为准
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Hook 失败缓冲队列 + Daemon 启动重放 — Spec
|
|
2
|
+
|
|
3
|
+
**日期**: 2026-05-16
|
|
4
|
+
**状态**: Draft(待用户 review)
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 一、目标 + 成功标准
|
|
9
|
+
|
|
10
|
+
**核心目标**:实现「至少一次」事件交付,消除 daemon 重启窗口期的静默丢失。
|
|
11
|
+
|
|
12
|
+
| 成功标准 | 验收方式 |
|
|
13
|
+
|---|---|
|
|
14
|
+
| daemon 停机 30 秒内,5 条 UserPromptSubmit 全部最终入库 | 集成测试:停 daemon → 发 5 事件 → 启动 daemon → 查 DB |
|
|
15
|
+
| 队列目录不超过 500 个文件 / 7 天 | 单元测试:写 600 个文件后调 prune,剩余 ≤500 |
|
|
16
|
+
| hook 总执行时间不超过 1 秒 | 脚本计时测试(`time` 命令) |
|
|
17
|
+
| 重放不产生重复入库 | 集成测试:手动写重复 event_id → 验证 DB 只有一条 |
|
|
18
|
+
|
|
19
|
+
**非目标**:已丢失的历史事件(本次故障之前)、跨机器同步、daemon 运行期间的网络抖动(nc 有超时保护,不属于失败场景)。
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 二、设计决策
|
|
24
|
+
|
|
25
|
+
### 决策 1:队列存储格式 — per-event 独立文件
|
|
26
|
+
|
|
27
|
+
**选择**:`~/.claude-forge/queue/<timestamp>-<uuid>.json` 每个事件一个文件。
|
|
28
|
+
|
|
29
|
+
**理由**:
|
|
30
|
+
1. 完全避免并发写冲突:5 个 hook bash 进程写不同文件名,无锁需求
|
|
31
|
+
2. 原子性:`bash` 的 `echo > file` 对新建文件是原子操作(内核 create + write)
|
|
32
|
+
3. 删除操作幂等:`rm -f file` 不会影响其他事件;追加模式下误删一行会破坏整个 jsonl
|
|
33
|
+
|
|
34
|
+
**否决方案**:append-only jsonl —— bash 并发 `>>` 在 chunk > PIPE_BUF(512B) 时会产生交错写,且部分行损坏会影响整个文件解析。
|
|
35
|
+
|
|
36
|
+
### 决策 2:队列目录位置 — `~/.claude-forge/queue/`
|
|
37
|
+
|
|
38
|
+
**理由**:
|
|
39
|
+
1. 与 `daemon.sock`、`data.db`、`daemon.token` 同目录,路径计算逻辑统一
|
|
40
|
+
2. `expandPath` 工具已有 `~/.claude-forge/` 展开支持
|
|
41
|
+
3. daemon 启动时已有 `mkdirSync` 保证父目录存在,子目录只需 `mkdir -p queue`
|
|
42
|
+
|
|
43
|
+
### 决策 3:触发投递条件 — daemon 启动时一次性扫描
|
|
44
|
+
|
|
45
|
+
**理由**:
|
|
46
|
+
1. 失败窗口期(daemon 重启)是短暂的,启动一次扫描即可覆盖
|
|
47
|
+
2. 不需要额外的 watcher 进程/定时器,降低复杂度
|
|
48
|
+
3. 重放完成后队列目录为空,无持续扫描开销
|
|
49
|
+
|
|
50
|
+
### 决策 4:去重策略 — `event_id` 数据库唯一索引(已存在)+ catch ignore
|
|
51
|
+
|
|
52
|
+
**理由**:
|
|
53
|
+
1. `events.event_id TEXT PRIMARY KEY` 已存在,无需额外工作
|
|
54
|
+
2. daemon 侧只需在 `writeEvent` 的 catch 中识别 `UNIQUE constraint failed` 并静默跳过,其他错误仍 re-throw
|
|
55
|
+
3. 避免内存 LRU 在 daemon 重启时丢失已处理记录的风险
|
|
56
|
+
|
|
57
|
+
### 决策 5:容量保护 — 500 文件上限 + 7 天 TTL,过期写入 dead-letter
|
|
58
|
+
|
|
59
|
+
- 写入前检查:队列文件数 ≥ 500,**丢弃最旧的超额文件**
|
|
60
|
+
- TTL:daemon 启动重放时,跳过 > 7 天的文件,移入 `~/.claude-forge/queue/dead/`
|
|
61
|
+
- dead-letter 目录不自动清理,供人工审查
|
|
62
|
+
|
|
63
|
+
### 决策 6:hook 脚本写队列方式 — fork 子进程同步写
|
|
64
|
+
|
|
65
|
+
**方式**:在 `nc` 失败后,用 `( ... ) &` 后台子进程写文件,主进程立即 `exit 0`。
|
|
66
|
+
|
|
67
|
+
**理由**:
|
|
68
|
+
1. 主进程不阻塞,子进程独立 fork 不受父退出影响
|
|
69
|
+
2. bash 原生支持,比 nohup/setsid 简单
|
|
70
|
+
3. 单文件写入 syscall < 5ms,子进程开销可忽略
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 三、改动文件清单
|
|
75
|
+
|
|
76
|
+
| 路径 | 改动类型 | 概述 |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| `src/hooks/user-prompt-submit.sh` | 修改 | nc 失败后 fork 子进程写队列文件 |
|
|
79
|
+
| `src/hooks/pre-tool-use.sh` | 修改 | 同上,补充 socket 存在检测 |
|
|
80
|
+
| `src/hooks/post-tool-use.sh` | 修改 | 同上 |
|
|
81
|
+
| `src/hooks/notification.sh` | 修改 | 同上(低优先级,可选) |
|
|
82
|
+
| `src/hooks/stop.sh` | **不改** | Stop 事件无重放意义 |
|
|
83
|
+
| `src/core/queue/index.ts` | 新建 | 队列读写、prune、重放逻辑 |
|
|
84
|
+
| `src/daemon/index.ts` | 修改 | Step 8 之后插入 `replayQueue()` 调用 |
|
|
85
|
+
| `src/core/storage/events.ts` | 修改 | `writeEvent` catch 中识别并忽略 UNIQUE 冲突 |
|
|
86
|
+
| `src/tests/queue.test.ts` | 新建 | 单元测试 |
|
|
87
|
+
| `tests/integration/queue-replay.integration.test.ts` | 新建 | 集成测试 |
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 四、模块设计
|
|
92
|
+
|
|
93
|
+
### `src/core/queue/index.ts` 接口
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
QUEUE_DIR = ~/.claude-forge/queue/
|
|
97
|
+
DEAD_DIR = ~/.claude-forge/queue/dead/
|
|
98
|
+
MAX_FILES = 500
|
|
99
|
+
TTL_DAYS = 7
|
|
100
|
+
|
|
101
|
+
enqueueEvent(event: ForgeEvent): void
|
|
102
|
+
- 文件名:<iso-timestamp>-<event_id>.json
|
|
103
|
+
- 写入前 prune:目录文件数 >= MAX_FILES 删最旧
|
|
104
|
+
|
|
105
|
+
replayQueue(storage: SQLiteStorage): Promise<{ replayed, skipped, dead }>
|
|
106
|
+
- 读 QUEUE_DIR 下所有 *.json
|
|
107
|
+
- TTL > 7 天 → 移入 DEAD_DIR
|
|
108
|
+
- JSON.parse → storage.writeEvent
|
|
109
|
+
- UNIQUE constraint → skipped++(去重)
|
|
110
|
+
- 成功入库 → rm 文件 → replayed++
|
|
111
|
+
- JSON 损坏 → 移入 DEAD_DIR → dead++
|
|
112
|
+
|
|
113
|
+
pruneQueue(): void // 内部使用
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### `src/daemon/index.ts` 改动
|
|
117
|
+
|
|
118
|
+
在 socket `listen` 回调内(`logger.info('Socket 服务器已监听')` 之后)追加:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
replayQueue(storage).then(({ replayed, skipped, dead }) => {
|
|
122
|
+
logger.info(`[Queue] Replay: ${replayed} replayed, ${skipped} skipped (dup), ${dead} dead-lettered`);
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Hook 脚本改动模式
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# 当前:
|
|
130
|
+
RESPONSE=$(echo "$EVENT" | nc -U -w 10 "$SOCKET_PATH" 2>/dev/null)
|
|
131
|
+
|
|
132
|
+
# 新增:nc 失败或 RESPONSE 为空时 fork 写队列
|
|
133
|
+
if [ -z "$RESPONSE" ]; then
|
|
134
|
+
(
|
|
135
|
+
QUEUE_DIR="$HOME/.claude-forge/queue"
|
|
136
|
+
mkdir -p "$QUEUE_DIR"
|
|
137
|
+
TS=$(date -u +"%Y%m%dT%H%M%S")
|
|
138
|
+
UUID=$(uuidgen 2>/dev/null || cat /proc/sys/kernel/random/uuid 2>/dev/null || echo "$$-$RANDOM")
|
|
139
|
+
echo "$EVENT" > "$QUEUE_DIR/${TS}-${UUID}.json"
|
|
140
|
+
) &
|
|
141
|
+
fi
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
注意:macOS BSD `date` 不支持 `%N` 毫秒,所以 timestamp 用秒精度 + UUID 兜底唯一性。
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## 五、风险点
|
|
149
|
+
|
|
150
|
+
| 风险 | 概率 | 缓解方案 |
|
|
151
|
+
|---|---|---|
|
|
152
|
+
| 5 hook 同时写同名文件 | 低 | 文件名含 UUID(uuidgen),冲突 < 1/10^12 |
|
|
153
|
+
| JSON 文件写一半被截断 | 低 | replayQueue catch JSON.parse → dead-letter |
|
|
154
|
+
| daemon 重放时 socket 刚启动又挂掉 | 极低 | 每文件独立 try/catch,单失败不中断 |
|
|
155
|
+
| queue 文件含旧 `_auth` token | 必然发生 | 重放走 `storage.writeEvent`,不经 socket 认证,Zod schema strip 自动剥离 |
|
|
156
|
+
| 历史已丢失数据 | 已发生 | 本次范围外;可手动从 `~/.claude/projects/*/*.jsonl` 回填 |
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 六、测试策略
|
|
161
|
+
|
|
162
|
+
### 单元测试 `src/tests/queue.test.ts`
|
|
163
|
+
|
|
164
|
+
| 用例 | 验证点 |
|
|
165
|
+
|---|---|
|
|
166
|
+
| enqueueEvent 写入 | 文件存在,内容可 JSON.parse |
|
|
167
|
+
| 超过 500 文件 prune 删最旧 | 写 510 个 → 文件数 = 500 |
|
|
168
|
+
| replayQueue 成功 → 文件删除 | mock writeEvent 成功 → 文件消失 |
|
|
169
|
+
| UNIQUE 冲突 → 文件删 + skipped++ | mock 抛 UNIQUE → skipped=1 |
|
|
170
|
+
| JSON 损坏 → 移入 dead | 非法 JSON → dead 目录有 |
|
|
171
|
+
| TTL 超期 → 移入 dead | mtime 8 天前 → dead 目录有 |
|
|
172
|
+
|
|
173
|
+
### 集成测试 `tests/integration/queue-replay.integration.test.ts`
|
|
174
|
+
|
|
175
|
+
1. 启动 daemon → 停止 daemon
|
|
176
|
+
2. `enqueueEvent` 写入 3 个 ForgeEvent
|
|
177
|
+
3. 重启 daemon
|
|
178
|
+
4. 查 DB:3 条事件在 events 表
|
|
179
|
+
5. 验证 queue/ 为空
|
|
180
|
+
6. 第二次重启验证去重(skipped=3)
|
|
181
|
+
|
|
182
|
+
### E2E 验证
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
./scripts/dev-daemon.sh restart &
|
|
186
|
+
echo '{"session_id":"test","cwd":"/tmp"}' | bash src/hooks/user-prompt-submit.sh
|
|
187
|
+
sqlite3 ~/.claude-forge/data.db "SELECT count(*) FROM events WHERE session_id='test';"
|
|
188
|
+
# 期望:1
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## 七、执行步骤(自底向上)
|
|
194
|
+
|
|
195
|
+
| # | 步骤 | 文件 |
|
|
196
|
+
|---|---|---|
|
|
197
|
+
| 1 | 实现队列模块(enqueueEvent + replayQueue + pruneQueue) | `src/core/queue/index.ts` |
|
|
198
|
+
| 2 | 单元测试 queue.test.ts 全过 | `src/tests/queue.test.ts` |
|
|
199
|
+
| 3 | `events.ts writeEvent` catch UNIQUE constraint 静默忽略 | `src/core/storage/events.ts` |
|
|
200
|
+
| 4 | daemon/index.ts 调用 replayQueue(socket ready 后) | `src/daemon/index.ts` |
|
|
201
|
+
| 5 | 修改 3 个 hook(user-prompt-submit、pre-tool-use、post-tool-use) | `src/hooks/*.sh` |
|
|
202
|
+
| 6 | 集成测试通过 | `tests/integration/queue-replay.integration.test.ts` |
|
|
203
|
+
| 7 | E2E:dev-daemon.sh restart 期间发事件验证 | 手工 + changelog |
|
|
204
|
+
| 8 | 部署:cp hook 到 ~/.claude-forge/hooks/ + 重启 daemon | 手工 |
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# L1: SWARM_PROTOCOL 字面量抽到 .md 文件 Spec
|
|
2
|
+
|
|
3
|
+
## 目标
|
|
4
|
+
|
|
5
|
+
把 `src/claudemd/claudemd-generator.ts` 中 223 行的 `SWARM_PROTOCOL` 字符串字面量抽到 `src/claudemd/templates/swarm-protocol.md`,build 时 cp 到 dist/,加载方式对齐 H3 `schema.sql` 的 fail-fast 模式。
|
|
6
|
+
|
|
7
|
+
## 调研结果
|
|
8
|
+
|
|
9
|
+
### 当前位置
|
|
10
|
+
|
|
11
|
+
- `src/claudemd/claudemd-generator.ts:555-777`(`const SWARM_PROTOCOL = `...`;`)
|
|
12
|
+
- 内容:223 行 markdown,含转义反引号
|
|
13
|
+
- 唯一使用点:第 59 行 `const full = SWARM_PROTOCOL + '\n\n' + projectContent;`(`generate()` 方法内)
|
|
14
|
+
- 上方有两段重复注释(547-553),可顺手清理
|
|
15
|
+
|
|
16
|
+
### 加载先例
|
|
17
|
+
|
|
18
|
+
1. **`src/core/storage/base.ts:61-73`(H3 schema.sql)**:`fileURLToPath(import.meta.url)` + `dirname` 解析同级目录,`existsSync` 校验,缺失抛 `[SQLiteStorage] schema.sql not found at ...`。ESM 兼容,dev/npm 一致。
|
|
19
|
+
2. **`src/skills/registry.ts:46-49` + `src/skills/official-skills.ts:52-55`(skills/official)**:同样 `fileURLToPath(import.meta.url)`。
|
|
20
|
+
|
|
21
|
+
### 现有测试
|
|
22
|
+
|
|
23
|
+
- `tests/integration/` 与 `src/tests/` 均无 `claudemd-generator` 测试 → **零覆盖**,必须先建 safety-net。
|
|
24
|
+
|
|
25
|
+
## 设计方案
|
|
26
|
+
|
|
27
|
+
### 文件位置
|
|
28
|
+
|
|
29
|
+
- 新建 `src/claudemd/templates/swarm-protocol.md`(kebab-case,内容为现 555-777 行的原文,去掉 JS 反引号转义)
|
|
30
|
+
|
|
31
|
+
### claudemd-generator.ts 改造
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
- 删除 const SWARM_PROTOCOL = `...`;(555-777)
|
|
35
|
+
- 删除上方 547-553 重复注释块
|
|
36
|
+
- 新增模块级函数 getSwarmProtocol(): string
|
|
37
|
+
· const thisDir = dirname(fileURLToPath(import.meta.url))
|
|
38
|
+
· const p = join(thisDir, 'templates', 'swarm-protocol.md')
|
|
39
|
+
· 若 !existsSync(p) 抛 `[ClaudeMdGenerator] swarm-protocol.md not found at ${p}. Run npm run build or reinstall.`
|
|
40
|
+
· readFileSync(p, 'utf-8')
|
|
41
|
+
- 一级缓存:模块级 let cached: string | null = null(避免每次 generate 都读盘)
|
|
42
|
+
- 第 59 行:const full = getSwarmProtocol() + '\n\n' + projectContent;
|
|
43
|
+
- 顶部 import 加 fileURLToPath(node:url)、dirname(已从 node:path 导入需补 dirname)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
命名 `get` 前缀(获取单一资源)。
|
|
47
|
+
|
|
48
|
+
### package.json build 改造
|
|
49
|
+
|
|
50
|
+
在现有 `build` 命令中追加:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
mkdir -p dist/claudemd/templates && cp src/claudemd/templates/*.md dist/claudemd/templates/
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
末尾 fail-fast 校验追加:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
&& (test -f dist/claudemd/templates/swarm-protocol.md || (echo '[build] FATAL: dist/claudemd/templates/swarm-protocol.md missing' && exit 1))
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
与现有 `dist/core/storage/schema.sql` 校验风格保持一致。
|
|
63
|
+
|
|
64
|
+
## 测试策略
|
|
65
|
+
|
|
66
|
+
### safety-net(必做,先行)
|
|
67
|
+
|
|
68
|
+
新增 `tests/integration/claudemd-generator.test.ts`:
|
|
69
|
+
|
|
70
|
+
1. **Baseline 测试(迁移前跑通)**:
|
|
71
|
+
- mock `ClaudeProvider.complete` 抛错(走 fallback 路径),调 `generator.generate(tmpDir)`
|
|
72
|
+
- 断言输出包含 SWARM_PROTOCOL 关键字段:`# claude-forge 工作区规范`、`## 自检`、`Two-Phase Workflow`、`harness-hotfix`、`refactor-safe`、`hybrid-feature-with-safety`
|
|
73
|
+
- 断言总行数 ≥ 200
|
|
74
|
+
2. **快照锚点**:保存 SWARM 段的 SHA256 或长度,迁移后断言不变
|
|
75
|
+
|
|
76
|
+
### 回归
|
|
77
|
+
|
|
78
|
+
- 迁移完成后重跑 safety-net,断言行为完全一致(同一 hash / 同一行数 / 同一关键字)
|
|
79
|
+
- `npx tsc --noEmit`
|
|
80
|
+
- `npm test`
|
|
81
|
+
- 手测:`npm run build` 后 `ls dist/claudemd/templates/swarm-protocol.md`
|
|
82
|
+
|
|
83
|
+
## 风险与回滚
|
|
84
|
+
|
|
85
|
+
| 风险 | 缓解 |
|
|
86
|
+
|---|---|
|
|
87
|
+
| dev 跑 `tsx src/` 时 dist 不存在 | `fileURLToPath(import.meta.url)` 解析到 `src/claudemd/`,同级 `templates/` 在 src 下存在,dev 路径天然兼容 |
|
|
88
|
+
| npm 安装包 cp 失败 | build 末尾 `test -f` 校验,CI 失败而非运行时炸 |
|
|
89
|
+
| .md 内反引号转义遗漏 | safety-net 哈希比对会发现 |
|
|
90
|
+
| 模块级缓存导致测试串扰 | 暴露 `__resetCache()` 仅 test 用,或不缓存(223 行读盘成本可忽略) |
|
|
91
|
+
|
|
92
|
+
**回滚**:单 commit revert 即可(generator.ts + package.json + 新 .md 文件)。
|
|
93
|
+
|
|
94
|
+
## 实施顺序
|
|
95
|
+
|
|
96
|
+
1. 补 `tests/integration/claudemd-generator.test.ts`(safety-net,**当前字面量实现下跑绿**)
|
|
97
|
+
2. 创建 `src/claudemd/templates/swarm-protocol.md`(复制 555-777 原文,去 JS 转义)
|
|
98
|
+
3. 改 `claudemd-generator.ts`:加 `getSwarmProtocol()`,删字面量与重复注释
|
|
99
|
+
4. 改 `package.json` build:cp + fail-fast 校验
|
|
100
|
+
5. 跑 `npm run build && npm test && npx tsc --noEmit`,对比 safety-net hash
|
|
101
|
+
|
|
102
|
+
## 命名遵循
|
|
103
|
+
|
|
104
|
+
- 文件 kebab-case:`swarm-protocol.md`、`claudemd-generator.test.ts`
|
|
105
|
+
- 加载函数 `get` 前缀:`getSwarmProtocol()`
|
|
106
|
+
- 错误前缀 `[ClaudeMdGenerator]`,与 `[SQLiteStorage]` 风格一致
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# M10: ~/.claude-forge 子路径硬编码收敛 Spec
|
|
2
|
+
|
|
3
|
+
## 目标
|
|
4
|
+
把 `~/.claude-forge/<子路径>` 的硬编码(共 7 类、20+ 处)统一收敛到 `src/core/constants.ts` 的 `FORGE_PATHS`,消除 `path.join(homedir(), '.claude-forge', ...)` 重复并降低未来路径变更的成本。
|
|
5
|
+
|
|
6
|
+
## 调研结果
|
|
7
|
+
|
|
8
|
+
### 子路径分组(仅 `~/.claude-forge/` 下的真实文件路径)
|
|
9
|
+
|
|
10
|
+
| 子路径 | 引用文件:行 | 总次数 | 现有 FORGE_PATHS |
|
|
11
|
+
|---|---|---|---|
|
|
12
|
+
| `daemon.token` | lifecycle.ts:9; cli/mcp.ts:45; auth-middleware.ts:18 | 3 | 否 |
|
|
13
|
+
| `daemon.pid` | lifecycle.ts:10; cli/daemon.ts:45; cli/status.ts:8; cli/mcp.ts:86 | 4 | 否 |
|
|
14
|
+
| `daemon.sock` | lifecycle.ts:52 | 1(外加 error-handler.ts:239 的"forge.sock"字面量提示文本,**待统一**) | 否 |
|
|
15
|
+
| `daemon.log` / `daemon-stdout.log` / `daemon-stderr.log` | cli/daemon.ts:47,48,115 | 3 | 否 |
|
|
16
|
+
| `hooks/` | cli/init/hook-manager.ts:8 | 1 | 否 |
|
|
17
|
+
| `queue/` + `queue/dead/` | core/queue/index.ts:26-28 | 2 | 否 |
|
|
18
|
+
| `routing.yaml` | web/routes/types.ts:37 | 1 | 否 |
|
|
19
|
+
| `backups/skills` | web/routes/skills.ts:208,235,279,321; web/routes/types.ts:32 | 5 | 否 |
|
|
20
|
+
| `backups/routing` | web/routes/types.ts:38 | 1 | 否 |
|
|
21
|
+
| `data.db` (字面量) | cli/stats.ts:21 | 1 | **已有但未用** → 改为 `FORGE_PATHS.database()` |
|
|
22
|
+
|
|
23
|
+
### 不属于 FORGE_PATHS 的引用(保留硬编码)
|
|
24
|
+
|
|
25
|
+
- `process.cwd() + '.claude-forge/executions/by-route'`(cli/executions.ts:16,53,85)— **项目级目录**,不是 `~/.claude-forge`
|
|
26
|
+
- `project_path + '.claude-forge/history'`(daemon/handlers/history-exporter.ts:24)— 同上
|
|
27
|
+
- `templates/template-manager.ts:88`(在项目 `projectPath` 下创建 `.claude-forge`)— 项目级
|
|
28
|
+
- `cli/init/hook-manager.ts:34`(substring 匹配字符串,非路径拼接)
|
|
29
|
+
- `error-handler.ts` 内所有 `~/.claude-forge/...` 是**面向用户的提示文本**,建议保留字符串字面量(用户阅读),但 `forge.sock` 与代码中 `daemon.sock` 不一致 → 顺手修一下
|
|
30
|
+
- `claudemd-generator.ts:751` 与 `:211` 是模板内嵌字符串
|
|
31
|
+
|
|
32
|
+
## FORGE_PATHS 扩展设计
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
export const FORGE_PATHS = {
|
|
36
|
+
home: () => FORGE_HOME,
|
|
37
|
+
config: () => join(FORGE_HOME, 'config.yaml'),
|
|
38
|
+
database: () => join(FORGE_HOME, 'data.db'),
|
|
39
|
+
logs: () => join(FORGE_HOME, 'logs'),
|
|
40
|
+
|
|
41
|
+
// ── Daemon runtime files ────────────────────────────────
|
|
42
|
+
daemonSocket: () => join(FORGE_HOME, 'daemon.sock'),
|
|
43
|
+
daemonPid: () => join(FORGE_HOME, 'daemon.pid'),
|
|
44
|
+
daemonToken: () => join(FORGE_HOME, 'daemon.token'),
|
|
45
|
+
daemonLog: () => join(FORGE_HOME, 'daemon.log'),
|
|
46
|
+
daemonStdout: () => join(FORGE_HOME, 'daemon-stdout.log'),
|
|
47
|
+
daemonStderr: () => join(FORGE_HOME, 'daemon-stderr.log'),
|
|
48
|
+
|
|
49
|
+
// ── Subdirs ─────────────────────────────────────────────
|
|
50
|
+
hooks: () => join(FORGE_HOME, 'hooks'),
|
|
51
|
+
queue: () => join(FORGE_HOME, 'queue'),
|
|
52
|
+
queueDead: () => join(FORGE_HOME, 'queue', 'dead'),
|
|
53
|
+
|
|
54
|
+
// ── Patchable targets ───────────────────────────────────
|
|
55
|
+
routingYaml: () => join(FORGE_HOME, 'routing.yaml'),
|
|
56
|
+
backups: (kind: 'skills' | 'routing') => join(FORGE_HOME, 'backups', kind),
|
|
57
|
+
} as const;
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 关键决策
|
|
61
|
+
|
|
62
|
+
1. **`backups(kind)` 参数化 vs 分开**:选**参数化**。理由:`backups` 的两个子目录有共同语义(patch 系统的备份根),且 `resolvePatchTarget` 内已经按 `targetType` 分支。`kind` 用字面量联合类型,越界编译期就报错。
|
|
63
|
+
2. **`daemonLog`/`daemonStdout`/`daemonStderr` 三个独立方法 vs 一个 `daemonLog(channel)`**:选**独立方法**。理由:三者在调用点完全分离(stdout/stderr 仅用于 launchd 重定向,daemon.log 是 logger 输出),不存在动态选择场景。
|
|
64
|
+
3. **动态参数(sessionId 等)不纳入**:`history-exporter` 是 `project_path` 拼接,**不属于** `~/.claude-forge`,本次范围外。
|
|
65
|
+
4. **`error-handler.ts` 的字符串字面量**:保留 `~/.claude-forge/...` 字符串(面向用户阅读),但把 `forge.sock` 改成 `daemon.sock` 与代码一致(顺手修,1 行)。
|
|
66
|
+
|
|
67
|
+
## 改造范围(按文件)
|
|
68
|
+
|
|
69
|
+
| 文件 | 改动点 | 影响行数 |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| `src/core/constants.ts` | 扩展 FORGE_PATHS(11 个新方法)| +12 |
|
|
72
|
+
| `src/daemon/lifecycle.ts` | TOKEN_FILE/PID_FILE 改 FORGE_PATHS;getSocketPath 复用 daemonSocket | ~5 |
|
|
73
|
+
| `src/cli/commands/daemon.ts` | PID_FILE/STDOUT_LOG/STDERR_LOG + line 115 logFile | 4 |
|
|
74
|
+
| `src/cli/commands/status.ts` | PID_FILE(注意:与 lifecycle.ts 重复,可考虑后续从 lifecycle 复用,但本次保持就地替换)| 1 |
|
|
75
|
+
| `src/cli/commands/mcp.ts` | tokenPath:45, pid:86 | 2 |
|
|
76
|
+
| `src/cli/commands/stats.ts` | dbPath:21 改 `FORGE_PATHS.database()` | 1 |
|
|
77
|
+
| `src/cli/init/hook-manager.ts` | HOOKS_DIR 改 `FORGE_PATHS.hooks()` | 1 |
|
|
78
|
+
| `src/core/queue/index.ts` | FORGE_DIR/QUEUE_DIR/DEAD_DIR | 3 |
|
|
79
|
+
| `src/web/auth-middleware.ts` | TOKEN_FILE | 1 |
|
|
80
|
+
| `src/web/routes/types.ts` | resolvePatchTarget 4 处路径 | 4 |
|
|
81
|
+
| `src/web/routes/skills.ts` | backupDir × 4 处 | 4 |
|
|
82
|
+
| `src/core/utils/error-handler.ts` | `forge.sock` → `daemon.sock`(一致性修复)| 1 |
|
|
83
|
+
|
|
84
|
+
**合计:约 39 处替换、12 文件**。无字符串模板 `${homedir()}/.claude-forge/...` 形式(已用 grep 验证)。所有调用点都是 `path.join(homedir(), '.claude-forge', ...)`,机械替换安全。
|
|
85
|
+
|
|
86
|
+
## 测试策略
|
|
87
|
+
|
|
88
|
+
1. **新增** `tests/unit/core/forge-paths.test.ts`:
|
|
89
|
+
- 每个方法返回值以 `FORGE_HOME` 为前缀
|
|
90
|
+
- `backups('skills')` / `backups('routing')` 返回正确子路径
|
|
91
|
+
- 类型层面(编译期)拒绝 `backups('invalid')`
|
|
92
|
+
2. **回归**:
|
|
93
|
+
- `tests/unit/core/queue/*`(queue 模块已有测试)
|
|
94
|
+
- 单元测试全量 `npx vitest run`
|
|
95
|
+
- `npx tsc --noEmit`
|
|
96
|
+
3. **手测**:`./scripts/dev-daemon.sh restart` 验证 pid/token/socket 文件生成
|
|
97
|
+
|
|
98
|
+
## 风险与回滚
|
|
99
|
+
|
|
100
|
+
- **路径值不变**:FORGE_PATHS 只是函数封装,运行时返回值与原硬编码完全一致 → 已运行的 daemon、已存在的 token/pid/db 文件不受影响
|
|
101
|
+
- **回滚**:单次 PR、git revert 即可
|
|
102
|
+
- **测试覆盖**:daemon/handlers 部分零测试(CLAUDE.md 提示),本次不修改 handler 逻辑,仅替换路径常量,风险面小;但**因为涉及 `src/daemon/lifecycle.ts`(无单元测试)和 `src/web/routes/`(中等覆盖)**,按 CLAUDE.md「工作流升级判定」表,建议走 `refactor-safe`(safety-net 阶段先补 `forge-paths.test.ts` + 跑现有 queue/storage 测试作为安全网)
|
|
103
|
+
- **launchd plist**:未涉及 plist 模板路径(plist 是绝对路径生成时拼接,不在 FORGE_PATHS 范围)
|
|
104
|
+
|
|
105
|
+
## 实施顺序(给 coder agent)
|
|
106
|
+
|
|
107
|
+
1. **safety-net**:新增 `tests/unit/core/forge-paths.test.ts`(先写好测试,让其通过当前 FORGE_PATHS);跑一遍 `npx vitest run tests/unit/core` 与 `npx tsc --noEmit` 作为基线
|
|
108
|
+
2. **扩展 FORGE_PATHS**:编辑 `src/core/constants.ts` 添加 11 个方法;补全 forge-paths.test.ts 对新方法的断言
|
|
109
|
+
3. **分组替换**(每组完成后跑 `npx tsc --noEmit`):
|
|
110
|
+
- Group A:daemon 运行时文件(lifecycle / daemon / status / mcp / auth-middleware)
|
|
111
|
+
- Group B:queue(core/queue/index.ts)
|
|
112
|
+
- Group C:hooks(hook-manager.ts)
|
|
113
|
+
- Group D:web patch(types.ts + skills.ts × 4)
|
|
114
|
+
- Group E:stats.ts + error-handler.ts 文案修复
|
|
115
|
+
4. **全量验证**:`npm test` + `npm run build` + `./scripts/dev-daemon.sh restart` 验证 daemon 正常起停
|
|
116
|
+
|
|
117
|
+
## 命名遵循
|
|
118
|
+
|
|
119
|
+
- 方法名 camelCase:`daemonSocket`, `daemonPid`, `routingYaml`, `queueDead` ✓(与现有 `home/config/database/logs` 一致)
|
|
120
|
+
- 常量名 UPPER_SNAKE_CASE:`FORGE_PATHS`, `FORGE_HOME` ✓
|
|
121
|
+
- 测试文件位置:`tests/unit/core/forge-paths.test.ts`
|