@winspan/claude-forge 8.50.6 → 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.md +7 -7
- package/dist/claudemd/claudemd-generator.d.ts.map +1 -1
- package/dist/claudemd/claudemd-generator.js +27 -237
- package/dist/claudemd/claudemd-generator.js.map +1 -1
- package/dist/claudemd/resume-manager.js +1 -1
- package/dist/claudemd/resume-manager.js.map +1 -1
- package/dist/claudemd/templates/swarm-protocol.md +222 -0
- package/dist/cli/commands/daemon.js +6 -6
- 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.js +2 -2
- 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 +4 -3
- package/dist/cli/commands/menu.js.map +1 -1
- package/dist/cli/commands/stats.d.ts.map +1 -1
- package/dist/cli/commands/stats.js +2 -3
- 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.map +1 -1
- package/dist/cli/commands/trace.js +11 -23
- package/dist/cli/commands/trace.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.js +2 -2
- package/dist/core/ai/provider.js.map +1 -1
- package/dist/core/constants.d.ts +12 -1
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +15 -1
- 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.map +1 -1
- package/dist/core/queue/index.js +3 -4
- package/dist/core/queue/index.js.map +1 -1
- package/dist/core/storage/base.d.ts +36 -3
- package/dist/core/storage/base.d.ts.map +1 -1
- package/dist/core/storage/base.js +101 -58
- package/dist/core/storage/base.js.map +1 -1
- package/dist/core/storage/events.d.ts +92 -3
- package/dist/core/storage/events.d.ts.map +1 -1
- package/dist/core/storage/events.js +147 -0
- package/dist/core/storage/events.js.map +1 -1
- package/dist/core/storage/routing.d.ts +54 -1
- package/dist/core/storage/routing.d.ts.map +1 -1
- package/dist/core/storage/routing.js +99 -1
- package/dist/core/storage/routing.js.map +1 -1
- package/dist/core/storage/schema.sql +12 -2
- package/dist/core/storage/sessions.d.ts +20 -0
- package/dist/core/storage/sessions.d.ts.map +1 -1
- package/dist/core/storage/sessions.js +59 -0
- package/dist/core/storage/sessions.js.map +1 -1
- package/dist/core/storage/skills.d.ts +23 -0
- package/dist/core/storage/skills.d.ts.map +1 -1
- package/dist/core/storage/skills.js +47 -0
- package/dist/core/storage/skills.js.map +1 -1
- package/dist/core/storage/sqlite.d.ts +35 -2
- package/dist/core/storage/sqlite.d.ts.map +1 -1
- package/dist/core/storage/sqlite.js +93 -4
- package/dist/core/storage/sqlite.js.map +1 -1
- package/dist/core/storage/tasks.d.ts +49 -0
- package/dist/core/storage/tasks.d.ts.map +1 -1
- package/dist/core/storage/tasks.js +143 -1
- package/dist/core/storage/tasks.js.map +1 -1
- package/dist/core/storage/token-usage.d.ts +1 -1
- package/dist/core/storage/token-usage.d.ts.map +1 -1
- package/dist/core/storage/token-usage.js +1 -1
- package/dist/core/storage/token-usage.js.map +1 -1
- package/dist/core/types.d.ts +24 -3
- package/dist/core/types.d.ts.map +1 -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/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.map +1 -1
- package/dist/core/utils/logger.js +15 -1
- 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/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.js.map +1 -1
- package/dist/daemon/handlers/post-tool-use.d.ts.map +1 -1
- package/dist/daemon/handlers/post-tool-use.js +7 -3
- package/dist/daemon/handlers/post-tool-use.js.map +1 -1
- package/dist/daemon/handlers/stop.d.ts +4 -0
- package/dist/daemon/handlers/stop.d.ts.map +1 -1
- package/dist/daemon/handlers/stop.js +23 -35
- package/dist/daemon/handlers/stop.js.map +1 -1
- package/dist/daemon/handlers/user-prompt.d.ts +3 -3
- package/dist/daemon/handlers/user-prompt.d.ts.map +1 -1
- package/dist/daemon/handlers/user-prompt.js +12 -22
- package/dist/daemon/handlers/user-prompt.js.map +1 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +23 -9
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/lifecycle.js +3 -4
- package/dist/daemon/lifecycle.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 +76 -85
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/services/task-segmenter.js +1 -1
- package/dist/daemon/services/task-segmenter.js.map +1 -1
- package/dist/hooks/hook-lib.sh +37 -0
- package/dist/hooks/notification.sh +2 -2
- package/dist/hooks/post-tool-use.sh +2 -2
- package/dist/hooks/pre-tool-use.sh +2 -2
- package/dist/hooks/stop.sh +9 -6
- package/dist/hooks/user-prompt-submit.sh +2 -2
- package/dist/{daemon/services → web/analytics}/anti-pattern-detector.d.ts +3 -4
- package/dist/web/analytics/anti-pattern-detector.d.ts.map +1 -0
- package/dist/{daemon/services → web/analytics}/anti-pattern-detector.js +7 -46
- package/dist/{daemon/services → web/analytics}/anti-pattern-detector.js.map +1 -1
- package/dist/web/analytics/drift-detector.d.ts.map +1 -0
- package/dist/{daemon/services → web/analytics}/drift-detector.js +10 -13
- package/dist/web/analytics/drift-detector.js.map +1 -0
- package/dist/web/analytics/weekly-report.d.ts.map +1 -0
- package/dist/{daemon/services → web/analytics}/weekly-report.js +51 -50
- 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/drift.js +1 -1
- package/dist/web/routes/drift.js.map +1 -1
- package/dist/web/routes/insights.js +1 -1
- package/dist/web/routes/insights.js.map +1 -1
- package/dist/web/routes/reports.js +1 -1
- package/dist/web/routes/reports.js.map +1 -1
- package/dist/web/routes/rules.d.ts +3 -0
- package/dist/web/routes/rules.d.ts.map +1 -1
- package/dist/web/routes/rules.js +28 -52
- package/dist/web/routes/rules.js.map +1 -1
- package/dist/web/routes/sessions.d.ts.map +1 -1
- package/dist/web/routes/sessions.js +16 -30
- 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 +28 -64
- 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 +5 -4
- package/dist/web/routes/skills.js.map +1 -1
- package/dist/web/routes/stats.d.ts +4 -0
- package/dist/web/routes/stats.d.ts.map +1 -1
- package/dist/web/routes/stats.js +19 -21
- package/dist/web/routes/stats.js.map +1 -1
- package/dist/web/routes/tasks.d.ts.map +1 -1
- package/dist/web/routes/tasks.js +17 -42
- package/dist/web/routes/tasks.js.map +1 -1
- package/dist/web/routes/trace.d.ts.map +1 -1
- package/dist/web/routes/trace.js +7 -17
- package/dist/web/routes/trace.js.map +1 -1
- package/dist/web/routes/types.d.ts.map +1 -1
- package/dist/web/routes/types.js +4 -3
- package/dist/web/routes/types.js.map +1 -1
- package/dist/web/static/assets/{AIConfig-BQCAQE9D.js → AIConfig-CdDWzJyO.js} +2 -2
- package/dist/web/static/assets/{AIConfig-BQCAQE9D.js.map → AIConfig-CdDWzJyO.js.map} +1 -1
- package/dist/web/static/assets/{Dashboard-D7Bo6Kan.js → Dashboard-CoEmmIDt.js} +2 -2
- package/dist/web/static/assets/{Dashboard-D7Bo6Kan.js.map → Dashboard-CoEmmIDt.js.map} +1 -1
- package/dist/web/static/assets/{Drawer-BeHRQxUS.js → Drawer-DdRTzlLB.js} +2 -2
- package/dist/web/static/assets/{Drawer-BeHRQxUS.js.map → Drawer-DdRTzlLB.js.map} +1 -1
- package/dist/web/static/assets/{Events-K_tCY2ti.js → Events-DrIq1SUS.js} +2 -2
- package/dist/web/static/assets/{Events-K_tCY2ti.js.map → Events-DrIq1SUS.js.map} +1 -1
- package/dist/web/static/assets/{Reports-BJCmBnc_.js → Reports-DFBM3MDK.js} +2 -2
- package/dist/web/static/assets/{Reports-BJCmBnc_.js.map → Reports-DFBM3MDK.js.map} +1 -1
- package/dist/web/static/assets/{SearchInput-BX2KhMkw.js → SearchInput-qCj_jAcf.js} +2 -2
- package/dist/web/static/assets/{SearchInput-BX2KhMkw.js.map → SearchInput-qCj_jAcf.js.map} +1 -1
- package/dist/web/static/assets/{SessionDetail-Bkr-kC7V.js → SessionDetail-CCzwdoT7.js} +2 -2
- package/dist/web/static/assets/{SessionDetail-Bkr-kC7V.js.map → SessionDetail-CCzwdoT7.js.map} +1 -1
- package/dist/web/static/assets/{Sessions-Chx9OCLH.js → Sessions-FfLYkAw9.js} +2 -2
- package/dist/web/static/assets/{Sessions-Chx9OCLH.js.map → Sessions-FfLYkAw9.js.map} +1 -1
- package/dist/web/static/assets/{Skills-O0GT1i7m.js → Skills-C8Gvs3Qa.js} +2 -2
- package/dist/web/static/assets/{Skills-O0GT1i7m.js.map → Skills-C8Gvs3Qa.js.map} +1 -1
- 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/index-CBX47X8l.js +3 -0
- package/dist/web/static/assets/{index-DxIbmNmr.js.map → index-CBX47X8l.js.map} +1 -1
- package/dist/web/static/assets/index-DjIoMdoR.css +1 -0
- package/dist/web/static/assets/{lucide-fJlPI3H7.js → lucide-Bs_edTLa.js} +44 -39
- 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/index.html +4 -4
- 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/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/task-active-gc-spec-20260518-1745.md +146 -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/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/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-page-white-screen-hotfix-changelog-20260518-1015.md +56 -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-page-white-screen-hotfix.md +126 -0
- package/package.json +2 -2
- package/src/claudemd/claudemd-generator.ts +29 -238
- package/src/claudemd/resume-manager.ts +1 -1
- package/src/claudemd/templates/swarm-protocol.md +222 -0
- package/src/cli/commands/daemon.ts +6 -6
- package/src/cli/commands/executions.ts +4 -3
- package/src/cli/commands/init.ts +2 -2
- package/src/cli/commands/logs.ts +1 -1
- package/src/cli/commands/mcp.ts +3 -5
- package/src/cli/commands/menu.ts +4 -3
- package/src/cli/commands/stats.ts +2 -3
- package/src/cli/commands/status.ts +2 -2
- package/src/cli/commands/trace.ts +10 -26
- package/src/cli/init/hook-manager.ts +2 -2
- package/src/core/ai/provider.ts +2 -2
- package/src/core/constants.ts +18 -1
- package/src/core/event-fields.ts +32 -0
- package/src/core/queue/index.ts +3 -4
- package/src/core/storage/base.ts +132 -56
- package/src/core/storage/events.ts +183 -4
- package/src/core/storage/routing.ts +129 -1
- package/src/core/storage/schema.sql +12 -2
- package/src/core/storage/sessions.ts +64 -0
- package/src/core/storage/skills.ts +69 -0
- package/src/core/storage/sqlite.ts +103 -4
- package/src/core/storage/tasks.ts +149 -1
- package/src/core/storage/token-usage.ts +1 -1
- package/src/core/types.ts +30 -3
- package/src/core/utils/error-handler.ts +3 -2
- package/src/core/utils/git.ts +23 -0
- package/src/core/utils/logger.ts +16 -1
- package/src/core/utils/lru-cache.ts +4 -0
- package/src/core/utils/token-tracker.ts +1 -1
- package/src/daemon/event-parser.ts +4 -3
- package/src/daemon/handlers/history-exporter.ts +1 -1
- package/src/daemon/handlers/post-tool-use.ts +7 -3
- package/src/daemon/handlers/stop.ts +32 -39
- package/src/daemon/handlers/user-prompt.ts +12 -22
- package/src/daemon/index.ts +24 -10
- package/src/daemon/lifecycle.ts +3 -3
- package/src/daemon/server.ts +76 -89
- package/src/daemon/services/task-segmenter.ts +1 -1
- package/src/hooks/hook-lib.sh +37 -0
- package/src/hooks/notification.sh +2 -2
- package/src/hooks/post-tool-use.sh +2 -2
- package/src/hooks/pre-tool-use.sh +2 -2
- package/src/hooks/stop.sh +9 -6
- package/src/hooks/user-prompt-submit.sh +2 -2
- package/src/{daemon/services → web/analytics}/anti-pattern-detector.ts +9 -54
- package/src/{daemon/services → web/analytics}/drift-detector.ts +10 -23
- package/src/{daemon/services → web/analytics}/weekly-report.ts +52 -75
- package/src/web/auth-middleware.ts +1 -2
- package/src/web/routes/_helpers.ts +34 -0
- package/src/web/routes/drift.ts +1 -1
- package/src/web/routes/insights.ts +1 -1
- package/src/web/routes/reports.ts +1 -1
- package/src/web/routes/rules.ts +31 -56
- package/src/web/routes/sessions.ts +18 -30
- package/src/web/routes/skill-stats.ts +29 -69
- package/src/web/routes/skills.ts +5 -4
- package/src/web/routes/stats.ts +19 -29
- package/src/web/routes/tasks.ts +17 -42
- package/src/web/routes/trace.ts +7 -19
- package/src/web/routes/types.ts +4 -3
- package/tests/integration/claudemd-generator.test.ts +90 -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/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/hooks/resolve-project-path.test.ts +122 -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/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 +3 -3
- 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/token-usage.test.ts +6 -6
- package/tests/unit/web/navigation-back-contract.test.ts +134 -0
- package/tests/unit/web/routes-rules.test.ts +182 -0
- package/tests/unit/web/routes-tasks.test.ts +34 -0
- package/tests/unit/web/task-title-contract.test.ts +210 -0
- package/tests/unit/web/tasks-component-contract.test.ts +179 -0
- package/vitest.config.ts +1 -1
- package/web/src/pages/TaskDetail.tsx +9 -5
- package/web/src/pages/Tasks.tsx +315 -50
- package/web/src/utils/navigation.ts +25 -0
- package/web/src/utils/task-title.ts +49 -0
- package/dist/daemon/services/anti-pattern-detector.d.ts.map +0 -1
- package/dist/daemon/services/drift-detector.d.ts.map +0 -1
- package/dist/daemon/services/drift-detector.js.map +0 -1
- package/dist/daemon/services/weekly-report.d.ts.map +0 -1
- package/dist/daemon/services/weekly-report.js.map +0 -1
- package/dist/web/static/assets/TaskDetail-5SR8zGzv.js +0 -2
- package/dist/web/static/assets/TaskDetail-5SR8zGzv.js.map +0 -1
- package/dist/web/static/assets/Tasks-DCgDqvOZ.js +0 -2
- package/dist/web/static/assets/Tasks-DCgDqvOZ.js.map +0 -1
- package/dist/web/static/assets/index-D8AKj26b.css +0 -1
- package/dist/web/static/assets/index-DxIbmNmr.js +0 -3
- package/dist/web/static/assets/lucide-fJlPI3H7.js.map +0 -1
- package/dist/web/static/assets/react-router-I-HqunH7.js +0 -20
- /package/dist/{daemon/services → web/analytics}/drift-detector.d.ts +0 -0
- /package/dist/{daemon/services → web/analytics}/weekly-report.d.ts +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# M6 + M8 实施 Changelog
|
|
2
|
+
|
|
3
|
+
**Date**: 2026-05-18 13:40
|
|
4
|
+
**Status**: 完成
|
|
5
|
+
|
|
6
|
+
## 完成清单
|
|
7
|
+
|
|
8
|
+
- [x] M8: daemon shutdown 加 clearInterval
|
|
9
|
+
- [x] M6: `recordTokenUsage` → `writeTokenUsage`
|
|
10
|
+
- [x] M6: `findPendingRoutingEvents` → `queryPendingRoutingEvents`
|
|
11
|
+
- [x] M6: `fetchEventsSince` → `queryEventsSince`(顺手 `fetchSessionsSince` → `querySessionsSince`)
|
|
12
|
+
|
|
13
|
+
## 关键代码定位
|
|
14
|
+
|
|
15
|
+
### M8: daemon shutdown clearInterval
|
|
16
|
+
|
|
17
|
+
- `src/daemon/index.ts:111-119` — `setInterval` 返回值保存到 `maintenanceInterval` 常量
|
|
18
|
+
- `src/daemon/index.ts:254` — `shutdown()` 中新增 `clearInterval(maintenanceInterval)`,置于 webServer.stop 之前、process.exit 之前
|
|
19
|
+
|
|
20
|
+
### M6: `recordTokenUsage` → `writeTokenUsage`
|
|
21
|
+
|
|
22
|
+
- `src/core/storage/token-usage.ts:13` — `TokenUsageOperations.writeTokenUsage`(定义)
|
|
23
|
+
- `src/core/storage/sqlite.ts:186-188` — facade 转发更新(含 `Parameters<...>` 泛型引用同步)
|
|
24
|
+
- `src/core/utils/token-tracker.ts:36` — 业务调用方
|
|
25
|
+
- `tests/unit/token-usage.test.ts` — 6 处调用点(replace_all)
|
|
26
|
+
- `tests/unit/storage/sqlite-refactor-harness.test.ts:231-246` — 测试调用 + test name 同步更新
|
|
27
|
+
|
|
28
|
+
### M6: `findPendingRoutingEvents` → `queryPendingRoutingEvents`
|
|
29
|
+
|
|
30
|
+
- `src/core/storage/routing.ts:130` — `RoutingOperations.queryPendingRoutingEvents`(定义)
|
|
31
|
+
- `src/core/storage/sqlite.ts:167-169` — facade 转发更新
|
|
32
|
+
|
|
33
|
+
无外部调用方(grep 仅命中定义与 facade)。
|
|
34
|
+
|
|
35
|
+
### M6: `fetchEventsSince` / `fetchSessionsSince` → `queryEventsSince` / `querySessionsSince`
|
|
36
|
+
|
|
37
|
+
- `src/daemon/services/anti-pattern-detector.ts:58-59` — 内部调用点
|
|
38
|
+
- `src/daemon/services/anti-pattern-detector.ts:82` — `private queryEventsSince`
|
|
39
|
+
- `src/daemon/services/anti-pattern-detector.ts:102` — `private querySessionsSince`
|
|
40
|
+
|
|
41
|
+
均为私有方法,无类外引用。
|
|
42
|
+
|
|
43
|
+
## 测试结果
|
|
44
|
+
|
|
45
|
+
- `npx tsc --noEmit` → **0 errors**
|
|
46
|
+
- `npx vitest run tests/unit/storage/ tests/unit/token-usage.test.ts --reporter=dot` → 67 passed / 1 failed(pre-existing `linkEventToTask`)
|
|
47
|
+
- `npm test -- --reporter=dot` → 439 passed / 1 failed(同一 pre-existing 失败)
|
|
48
|
+
|
|
49
|
+
## 顺手发现的其它命名违规
|
|
50
|
+
|
|
51
|
+
- `fetchSessionsSince`(在 anti-pattern-detector.ts,与 `fetchEventsSince` 配对)一并改为 `querySessionsSince`。
|
|
52
|
+
- 未发现其它 `findXxx`/`fetchYyy`/`retrieveZzz` 违规(grep 已扫过 src/ tests/)。
|
|
53
|
+
|
|
54
|
+
## 已知问题
|
|
55
|
+
|
|
56
|
+
- `tests/unit/storage/sqlite-refactor-harness.test.ts` 中 `linkEventToTask associates events with tasks` 用例 pre-existing 失败(writeEvent 校验抛错),与本次改名无关。
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# M7 实施 Changelog
|
|
2
|
+
|
|
3
|
+
**Date**: 2026-05-18 15:45
|
|
4
|
+
**Spec**: docs/design/m7-routing-event-association-spec-20260518-1545.md
|
|
5
|
+
**Status**: 完成
|
|
6
|
+
|
|
7
|
+
## 完成清单
|
|
8
|
+
- [x] routing.ts 加 getRecentPendingRoutingEvent
|
|
9
|
+
- [x] sqlite.ts facade 透传
|
|
10
|
+
- [x] storage 单测 5 case(4 必需 + 1 legacy 行为锁定)
|
|
11
|
+
- [x] post-tool-use.ts 切换调用
|
|
12
|
+
- [x] handler 单测 3 case
|
|
13
|
+
- [x] 文档化已知限制
|
|
14
|
+
|
|
15
|
+
## 关键代码定位
|
|
16
|
+
|
|
17
|
+
- 新方法实现:`src/core/storage/routing.ts:148-170`
|
|
18
|
+
- Facade 透传:`src/core/storage/sqlite.ts:225-227`
|
|
19
|
+
- Handler 切换:`src/daemon/handlers/post-tool-use.ts:32-36`
|
|
20
|
+
- Storage 单测:`tests/unit/storage/routing.test.ts:1-112`
|
|
21
|
+
- Handler 单测:`tests/unit/daemon/post-tool-use.test.ts:1-119`
|
|
22
|
+
|
|
23
|
+
## 测试结果
|
|
24
|
+
|
|
25
|
+
- **新增 storage 测试**:5/5 passed
|
|
26
|
+
- case 1: 旧 obeyed=1 + 新 pending → 返回新 pending
|
|
27
|
+
- case 2: 全部 obeyed=1 → 返回 null
|
|
28
|
+
- case 3: session 隔离
|
|
29
|
+
- case 4: 单条 pending → 返回该条
|
|
30
|
+
- bonus: legacy `getRecentRoutingEvent` 行为锁定(仍返回 most-recent,不受 obeyed 影响)
|
|
31
|
+
- **新增 handler 测试**:3/3 passed
|
|
32
|
+
- case 1(核心 bug 验证):同 prompt 第 2 个 Agent 不二次覆盖原 routing_event
|
|
33
|
+
- case 2: 跨 prompt 各自关联
|
|
34
|
+
- case 3: 无 routing_event 不抛错
|
|
35
|
+
- **tsc --noEmit**:0 errors
|
|
36
|
+
- **npm test 全量**:549 passed / 1 failed = 549/550
|
|
37
|
+
- 唯一失败 `linkEventToTask associates events with tasks`,与 M7 无关(spec 第 86 行已标注 pre-existing)
|
|
38
|
+
|
|
39
|
+
## 实施细节
|
|
40
|
+
|
|
41
|
+
### 向后兼容策略
|
|
42
|
+
|
|
43
|
+
- **保留** 旧 `getRecentRoutingEvent`(无 `obeyed IS NULL` 过滤)不动
|
|
44
|
+
- **新增** `getRecentPendingRoutingEvent`(带 `obeyed IS NULL` 过滤)
|
|
45
|
+
- Handler 仅切换到新方法;其他调用方(如有)维持旧语义
|
|
46
|
+
|
|
47
|
+
### Bug 修复验证
|
|
48
|
+
|
|
49
|
+
handler 单测 case 1 直接复现了 spec 描述的"同 prompt 多 Agent 覆盖"场景:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
// Before M7: Agent#2 也会拿到 routing_event#1 → routed_to_name 被覆盖为 'coder'
|
|
53
|
+
// After M7: Agent#2 拿不到 pending(#1 已 obeyed=1)→ 不再触碰 #1
|
|
54
|
+
expect(rowsAfter2[0].routed_to_name).toBe('researcher'); // NOT 'coder'
|
|
55
|
+
expect(rowsAfter2[0].first_tool_ts).toBe(firstToolTs); // 不被 stomp
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 已知限制(文档化)
|
|
59
|
+
|
|
60
|
+
- **同 prompt 多 Agent 漏记**:第 2+ 个 Agent 在 M7 修复后会被 silently skip(找不到 pending)。
|
|
61
|
+
- 影响:该 Agent 调用在 routing_events 表中没有归属行。
|
|
62
|
+
- 不在 M7 范围内:要彻底解决须把 PostToolUse 改为 **INSERT** 新行(而非 UPDATE),属功能扩展。
|
|
63
|
+
- 与 M7 前的对比:M7 前是"覆盖原行"(数据丢失 + 错配),M7 后是"放弃记录"(数据缺失但不错配)。语义更可控。
|
|
64
|
+
|
|
65
|
+
- **旧库残留 obeyed=NULL 的 stale 行**:若 session 内存在非常老的孤儿 pending(如旧 daemon crash 留下),可能被新 prompt 的 Agent 错关联。受 `ORDER BY ts DESC + session_id` 限制,影响面极小,可接受。
|
|
66
|
+
|
|
67
|
+
## 已知问题
|
|
68
|
+
|
|
69
|
+
- `tests/unit/storage/sqlite-refactor-harness.test.ts > linkEventToTask associates events with tasks` 失败为 pre-existing,与 M7 无关,未触碰。
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# project-path git root 修复 Changelog
|
|
2
|
+
|
|
3
|
+
**Date**: 2026-05-18 17:15
|
|
4
|
+
**Spec**: docs/design/project-path-gitroot-spec-20260518-1715.md
|
|
5
|
+
**Status**: 完成
|
|
6
|
+
|
|
7
|
+
## 完成清单
|
|
8
|
+
|
|
9
|
+
- [x] hook-lib.sh `resolve_project_path` — 已由前序 agent 完成
|
|
10
|
+
- [x] pre-tool-use.sh 改造 — 已由前序 agent 完成
|
|
11
|
+
- [x] post-tool-use.sh 改造 — 已由前序 agent 完成
|
|
12
|
+
- [x] user-prompt-submit.sh 改造 — 已由前序 agent 完成
|
|
13
|
+
- [x] notification.sh 改造 — 已由前序 agent 完成
|
|
14
|
+
- [x] stop.sh 改造 — 本次完成(source hook-lib.sh 方案 + 替换 nc 为 send_event_or_enqueue)
|
|
15
|
+
- [x] `src/core/utils/git.ts` — 本次新建
|
|
16
|
+
- [x] `src/cli/commands/executions.ts` 3 处 `process.cwd()` → `resolveGitRoot()`
|
|
17
|
+
- [△] `src/cli/commands/init.ts` — 未改,见下方原因
|
|
18
|
+
- [x] 安全网单测(7 case 全过),扩展现有 `tests/unit/hooks/resolve-project-path.test.ts`
|
|
19
|
+
- [△] 集成测试 — 降级方案:扩展现有单测(case 6/7),不新建独立 integration 文件
|
|
20
|
+
|
|
21
|
+
## 关键代码定位
|
|
22
|
+
|
|
23
|
+
| 文件 | 行 | 说明 |
|
|
24
|
+
|------|-----|------|
|
|
25
|
+
| `src/hooks/hook-lib.sh:26-48` | — | `resolve_project_path` 函数体 |
|
|
26
|
+
| `src/hooks/stop.sh:5` | 5 | `source hook-lib.sh` 新增 |
|
|
27
|
+
| `src/hooks/stop.sh:13-14` | 13-14 | `RAW_CWD` + `resolve_project_path` 替换原两行 |
|
|
28
|
+
| `src/hooks/stop.sh:29-30` | 29-30 | `send_event_or_enqueue` 替换原 `nc` 调用 |
|
|
29
|
+
| `src/core/utils/git.ts:1-20` | — | `resolveGitRoot()` TS helper |
|
|
30
|
+
| `src/cli/commands/executions.ts:5` | 5 | import `resolveGitRoot` |
|
|
31
|
+
| `src/cli/commands/executions.ts:16,53,85` | 16,53,85 | 3 处 `process.cwd()` → `resolveGitRoot()` |
|
|
32
|
+
| `tests/unit/hooks/resolve-project-path.test.ts:99-117` | 99-117 | case 6/7 新增 |
|
|
33
|
+
|
|
34
|
+
## 测试结果
|
|
35
|
+
|
|
36
|
+
- `tsc --noEmit`: 0 errors
|
|
37
|
+
- `npm test`: 558 passed / 1 failed(pre-existing: `linkEventToTask` in sqlite-refactor-harness.test.ts)
|
|
38
|
+
- hook 单测: 7 / 7 passed(含 2 个新增 case)
|
|
39
|
+
- `npm run build`: 成功
|
|
40
|
+
|
|
41
|
+
## 实施决策
|
|
42
|
+
|
|
43
|
+
### stop.sh: source 方案(非 inline)
|
|
44
|
+
|
|
45
|
+
`stop.sh` 原来手写 `nc` 直连 socket,未 source `hook-lib.sh`。本次采用 source 方案:
|
|
46
|
+
- 在文件顶部加 `source "$(dirname "$0")/hook-lib.sh"`,与其他 4 个 hook 保持一致性
|
|
47
|
+
- 同时将 `nc` 调用替换为 `send_event_or_enqueue`,获得"daemon 停机时自动入队"的能力
|
|
48
|
+
- stop.sh 在 daemon 运行时由 hook 调用,`$(dirname "$0")` 指向已安装的 hook 目录,路径可达
|
|
49
|
+
|
|
50
|
+
### 集成测试降级方案
|
|
51
|
+
|
|
52
|
+
选择"扩展现有单测"(case 6/7)而非新建独立 integration 文件:
|
|
53
|
+
- case 6 模拟 hook INPUT JSON 中 cwd 指向嵌套子目录的场景
|
|
54
|
+
- case 7 模拟 hook INPUT cwd 为空时 fallback 到 shell $PWD 的场景
|
|
55
|
+
- 覆盖核心路径,避免端到端测试引入 daemon 启动复杂度
|
|
56
|
+
|
|
57
|
+
### init.ts: 未改
|
|
58
|
+
|
|
59
|
+
`init.ts` 不操作项目级路径(`.claude-forge/` 子目录)。它只操作全局 `FORGE_HOME`(`~/.claude-forge/`)和 Claude Code 的全局 settings.json。`initProject` / `template-manager` 调用不在 init.ts 中出现。无需修改。
|
|
60
|
+
|
|
61
|
+
## 已知问题
|
|
62
|
+
|
|
63
|
+
- `linkEventToTask` 测试失败为 pre-existing,与本次改动无关
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# task active GC 修复 Changelog
|
|
2
|
+
|
|
3
|
+
**Date**: 2026-05-18 17:45
|
|
4
|
+
**Spec**: docs/design/task-active-gc-spec-20260518-1745.md
|
|
5
|
+
**Status**: 完成
|
|
6
|
+
|
|
7
|
+
## 完成清单
|
|
8
|
+
- [x] storage completeStaleActiveTasks
|
|
9
|
+
- [x] sqlite facade 转发
|
|
10
|
+
- [x] task-segmenter completeCurrentTask recover fallback
|
|
11
|
+
- [x] daemon staleTaskGcInterval (5 分钟一次,idle 10 分钟阈值)
|
|
12
|
+
- [x] shutdown clearInterval
|
|
13
|
+
- [x] 单测 4 case + recover fallback 3 case
|
|
14
|
+
|
|
15
|
+
## 关键代码定位
|
|
16
|
+
|
|
17
|
+
- `src/core/storage/tasks.ts:144-155` — `completeStaleActiveTasks` 方法
|
|
18
|
+
- `src/core/storage/sqlite.ts:183-185` — facade 代理方法
|
|
19
|
+
- `src/daemon/services/task-segmenter.ts:78` — `completeCurrentTask` recover fallback
|
|
20
|
+
- `src/daemon/index.ts:118-131` — `staleTaskGcInterval` 注册(STALE_TASK_GC_INTERVAL=5min,STALE_TASK_IDLE_MINUTES=10)
|
|
21
|
+
- `src/daemon/index.ts:251` — `clearInterval(staleTaskGcInterval)` 在 shutdown 中
|
|
22
|
+
|
|
23
|
+
## 测试结果
|
|
24
|
+
- tsc: 0 errors
|
|
25
|
+
- npm test: 565 passed / 1 failed (pre-existing `linkEventToTask` in sqlite-refactor-harness.test.ts)
|
|
26
|
+
- 新增测试: 7 cases all passed (4 storage GC + 3 segmenter recover)
|
|
27
|
+
|
|
28
|
+
## 验证 bug 修复
|
|
29
|
+
|
|
30
|
+
- 场景 A(ESC 中断,Stop hook 不触发):5 分钟 GC 轮询后自动将 idle > 10 分钟的 active task 转 completed
|
|
31
|
+
- 场景 B(daemon 重启后 Stop hook 触发但 Map 空):completeCurrentTask recover fallback 从 DB 恢复并关闭任务
|
|
32
|
+
- 场景 C(用户永不再 prompt 旧 session):GC 兜底,idle 10 分钟后自动关闭
|
|
33
|
+
|
|
34
|
+
## 已知问题
|
|
35
|
+
- `linkEventToTask` pre-existing failure in `sqlite-refactor-harness.test.ts` — 与本次改动无关
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Changelog: task-title-summary — 2026-05-18 11:30
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
Frontend-only fix: Tasks list and TaskDetail header now display the human-readable
|
|
6
|
+
`<summary>` extracted from `<task-notification>` XML titles instead of the raw blob.
|
|
7
|
+
|
|
8
|
+
## Files Changed
|
|
9
|
+
|
|
10
|
+
### New
|
|
11
|
+
|
|
12
|
+
- `web/src/utils/task-title.ts` — pure helper `normalizeTaskTitle(title)`
|
|
13
|
+
- `tests/unit/web/task-title-contract.test.ts` — 19 contract tests (TDD, written before implementation)
|
|
14
|
+
- `docs/reviews/task-title-summary.md` — fix report
|
|
15
|
+
|
|
16
|
+
### Modified
|
|
17
|
+
|
|
18
|
+
- `web/src/pages/Tasks.tsx`
|
|
19
|
+
- Import `normalizeTaskTitle` from `../utils/task-title`
|
|
20
|
+
- Line 340: `{task.title}` → `{normalizeTaskTitle(task.title)}`
|
|
21
|
+
|
|
22
|
+
- `web/src/pages/TaskDetail.tsx`
|
|
23
|
+
- Import `normalizeTaskTitle` from `../utils/task-title`
|
|
24
|
+
- Line 205: `{data.title}` → `{normalizeTaskTitle(data.title)}`
|
|
25
|
+
|
|
26
|
+
## Constraints Respected
|
|
27
|
+
|
|
28
|
+
- Backend untouched (task-segmenter, routes/tasks.ts, storage)
|
|
29
|
+
- No new npm dependencies
|
|
30
|
+
- TypeScript strict — zero errors
|
|
31
|
+
- Pure function, no React dependency
|
|
32
|
+
- Pre-existing test failure (sqlite-refactor-harness / uuid) is unrelated and pre-dates this change
|
|
33
|
+
|
|
34
|
+
## Workflow
|
|
35
|
+
|
|
36
|
+
harness-hotfix: safety-net → fix → verify
|
|
37
|
+
- safety-net: wrote 19 failing contract tests
|
|
38
|
+
- fix: implemented normalizeTaskTitle, wired into Tasks.tsx + TaskDetail.tsx, all 19 tests green
|
|
39
|
+
- verify: web build ✓, tsc --noEmit ✓ (both root + web), 378/379 tests pass
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Changelog: tasks-detail-back-loses-filters
|
|
2
|
+
|
|
3
|
+
**Date**: 2026-05-18 11:00
|
|
4
|
+
**Harness workflow**: safety-net → fix → verify
|
|
5
|
+
**skill_invoke**: MCP not invoked (direct execution per harness instructions)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 2026-05-18
|
|
10
|
+
|
|
11
|
+
- **10:06** Safety-net established — created `tests/unit/web/navigation-back-contract.test.ts` with 21 characterization tests locking the `resolveBackTo` fallback and happy-path behaviours before any code was changed.
|
|
12
|
+
|
|
13
|
+
- **10:08** Fix applied:
|
|
14
|
+
- Created `web/src/utils/navigation.ts` — exports `resolveBackTo(state: unknown, fallback='/tasks'): string` with strict type narrowing (no `as any`).
|
|
15
|
+
- `web/src/pages/Tasks.tsx` — added `useLocation` import; passed `{ state: { from: location.pathname + location.search } }` on task navigation.
|
|
16
|
+
- `web/src/pages/TaskDetail.tsx` — added `useLocation` + `resolveBackTo` imports; computed `backTo = resolveBackTo(location.state)`; replaced both absolute `<Link to="/tasks">` (error branch + success branch) with `<Link to={backTo}>`.
|
|
17
|
+
|
|
18
|
+
- **10:09** Verification:
|
|
19
|
+
- `web npm run build`: clean (tsc + vite, 0 errors).
|
|
20
|
+
- `npx tsc --noEmit` (root + web): 0 errors.
|
|
21
|
+
- Full test suite: 359/360 pass; 1 pre-existing failure in `sqlite-refactor-harness.test.ts` (confirmed present before our changes via `git stash` baseline run).
|
|
22
|
+
- Fix report written to `docs/reviews/tasks-detail-back-loses-filters.md`.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Changelog: Tasks Page White Screen Hotfix
|
|
2
|
+
|
|
3
|
+
**Date**: 2026-05-18 10:15
|
|
4
|
+
**Bug slug**: tasks-page-white-screen
|
|
5
|
+
**Workflow**: harness-hotfix (safety-net → fix → verify)
|
|
6
|
+
|
|
7
|
+
## Phase 1: safety-net
|
|
8
|
+
|
|
9
|
+
Created `tests/unit/web/tasks-component-contract.test.ts` with 15 characterization tests:
|
|
10
|
+
- Documents the broken consumer behaviour (TypeError on `.filter` of `TaskPage` object)
|
|
11
|
+
- Locks the correct `{ items, total, has_more }` API contract
|
|
12
|
+
- Tests pagination parameter logic
|
|
13
|
+
|
|
14
|
+
All 15 tests pass immediately (they lock current correct contract + document the defect pattern).
|
|
15
|
+
|
|
16
|
+
## Phase 2: fix
|
|
17
|
+
|
|
18
|
+
### Files Modified
|
|
19
|
+
|
|
20
|
+
**`web/src/pages/Tasks.tsx`** — full rewrite
|
|
21
|
+
- Fixed `fetchTasks` return type from `Task[]` to `TaskPage`
|
|
22
|
+
- Destructure `data.items`, `data.total`, `data.has_more` correctly
|
|
23
|
+
- Added URL sync via `useSearchParams` (page, size, project, preset, from, to, search)
|
|
24
|
+
- Added project multi-select dropdown (fetches `/api/tasks/projects`)
|
|
25
|
+
- Added time presets (1h / 24h / 7d)
|
|
26
|
+
- Added pagination controls (prev/next + page size selector 20/50/100)
|
|
27
|
+
- Added "共 N 条" total count display
|
|
28
|
+
- Added `shortPath()` helper to truncate project paths to last 2 segments
|
|
29
|
+
- Tailwind utility classes only, no inline styles
|
|
30
|
+
|
|
31
|
+
**`CLAUDE.md`** (line 184)
|
|
32
|
+
- Changed: `原生 HTML + Vanilla JS(单文件 SPA),无打包`
|
|
33
|
+
- To: `React 18 + Vite + Tailwind + react-router-dom + react-query + Recharts(\`web/\` 目录,build 后被 cp 到 dist/web/static/)`
|
|
34
|
+
|
|
35
|
+
**`src/claudemd/claudemd-generator.ts`** (line 737)
|
|
36
|
+
- Same correction in embedded template, backtick escaped to `\`` to avoid breaking the template literal
|
|
37
|
+
|
|
38
|
+
### No Backend Changes
|
|
39
|
+
|
|
40
|
+
`App.tsx` already had correct `<Route path="tasks">` config.
|
|
41
|
+
`Layout.tsx` already had Tasks nav item with `ListTodo` icon.
|
|
42
|
+
All backend routes (`/api/tasks`, `/api/tasks/projects`) were correct and untouched.
|
|
43
|
+
|
|
44
|
+
## Phase 3: verify
|
|
45
|
+
|
|
46
|
+
- `web/` TypeScript: clean
|
|
47
|
+
- Root TypeScript: clean (after escaping backtick in template literal)
|
|
48
|
+
- `web/npm run build`: success, `Tasks-D98y3WV2.js` chunk produced
|
|
49
|
+
- Root `npm run build`: success, chunk copied to `dist/web/static/assets/`
|
|
50
|
+
- Test results: 338/339 pass (1 pre-existing failure in sqlite-refactor-harness, unrelated)
|
|
51
|
+
- `curl http://127.0.0.1:3721/` → 200 OK, HTML contains 8 vite/module references
|
|
52
|
+
- API response confirmed: `{"items":[...],"total":393,"has_more":true}`
|
|
53
|
+
|
|
54
|
+
## Action Required
|
|
55
|
+
|
|
56
|
+
Run `./scripts/dev-daemon.sh restart` to serve the updated bundle.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Fix Report: task-title-summary
|
|
2
|
+
|
|
3
|
+
**Bug slug**: `task-title-summary`
|
|
4
|
+
**Date**: 2026-05-18
|
|
5
|
+
**Workflow**: harness-hotfix (safety-net → fix → verify)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Root Cause
|
|
10
|
+
|
|
11
|
+
Sub-agent completion callbacks are pushed to the session as a `UserPromptSubmit`
|
|
12
|
+
event whose content is the raw `<task-notification>` XML blob. The
|
|
13
|
+
`task-segmenter` uses the first user-prompt content as the task `title`, so
|
|
14
|
+
tasks spawned from these callbacks end up with a title like:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
<task-notification>
|
|
18
|
+
<task-id>aefe161c…</task-id>
|
|
19
|
+
…
|
|
20
|
+
<summary>Agent "Hotfix Tasks 返回丢筛选" completed</summary>
|
|
21
|
+
…
|
|
22
|
+
</task-notification>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The frontend rendered the literal XML string in both the Tasks list (`h3`) and
|
|
26
|
+
the TaskDetail header (`h1`), making the task unrecognisable.
|
|
27
|
+
|
|
28
|
+
**Backend was intentionally left unchanged** — the raw XML is the ground truth.
|
|
29
|
+
The fix lives entirely in the frontend presentation layer.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Fix Points
|
|
34
|
+
|
|
35
|
+
| File | Change |
|
|
36
|
+
|------|--------|
|
|
37
|
+
| `web/src/utils/task-title.ts` | **New file** — pure helper `normalizeTaskTitle()` |
|
|
38
|
+
| `web/src/pages/Tasks.tsx` | Import + wrap `{task.title}` → `{normalizeTaskTitle(task.title)}` in list `<h3>` |
|
|
39
|
+
| `web/src/pages/TaskDetail.tsx` | Import + wrap `{data.title}` → `{normalizeTaskTitle(data.title)}` in detail `<h1>` |
|
|
40
|
+
|
|
41
|
+
### `normalizeTaskTitle` logic (MAX_LEN = 80)
|
|
42
|
+
|
|
43
|
+
1. `null / undefined / whitespace` → `"(无标题)"`
|
|
44
|
+
2. Title starts with `<task-notification>`:
|
|
45
|
+
- Has `<summary>` with non-blank content → extract, trim, truncate + `…` if > 80 chars
|
|
46
|
+
- No `<summary>` or blank → `"(子任务回调)"`
|
|
47
|
+
3. Regular title → trim, truncate + `…` if > 80 chars
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## New Tests
|
|
52
|
+
|
|
53
|
+
File: `tests/unit/web/task-title-contract.test.ts`
|
|
54
|
+
|
|
55
|
+
**19 test cases** covering:
|
|
56
|
+
|
|
57
|
+
| Group | Cases |
|
|
58
|
+
|-------|-------|
|
|
59
|
+
| Passthrough | normal title, English title, whitespace trim |
|
|
60
|
+
| Fallback | empty string, whitespace-only, null, undefined |
|
|
61
|
+
| XML extraction | full blob, missing summary, bare tag, emoji+Chinese, quotes, first-match-wins |
|
|
62
|
+
| Truncation | summary > 80, summary = 80, plain title > 80, plain title = 80 |
|
|
63
|
+
| Summary whitespace | padded summary, whitespace-only summary |
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Regression / Build Verification
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
Tests: 19 passed (task-title-contract.test.ts — all green)
|
|
71
|
+
Suite: 378 passed, 1 pre-existing failure (sqlite-refactor-harness / uuid validation,
|
|
72
|
+
unrelated to this change, present before this fix)
|
|
73
|
+
|
|
74
|
+
web build: ✓ built in 2.50s (no errors)
|
|
75
|
+
new chunk: dist/assets/task-title-Bc8tnLXB.js (0.36 kB gzip: 0.30 kB)
|
|
76
|
+
Tasks chunk hash: Tasks-C8JHCGTC.js
|
|
77
|
+
TaskDetail chunk hash: TaskDetail-DYEk8pNw.js
|
|
78
|
+
|
|
79
|
+
TypeScript: npx tsc --noEmit → 0 errors (root)
|
|
80
|
+
npx tsc --noEmit → 0 errors (web/)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Notes
|
|
86
|
+
|
|
87
|
+
- `normalizeTaskTitle` is a pure function with zero React dependency — safe to
|
|
88
|
+
test in Node environment without jsdom.
|
|
89
|
+
- The helper intentionally **does not** modify stored data. Backend titles remain
|
|
90
|
+
unchanged; this is purely a display-layer normalisation.
|
|
91
|
+
- The first `<summary>` match is used defensively in case of malformed XML with
|
|
92
|
+
duplicate tags.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Fix Report: tasks-detail-back-loses-filters
|
|
2
|
+
|
|
3
|
+
**Date**: 2026-05-18
|
|
4
|
+
**Workflow**: harness-hotfix (safety-net → fix → verify)
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Root Cause
|
|
9
|
+
|
|
10
|
+
`TaskDetail.tsx` used `<Link to="/tasks">` — a hard absolute path — for both the
|
|
11
|
+
error-state and success-state "back" buttons (lines 161 and 195 of the original
|
|
12
|
+
file). React Router resolves this to `/tasks` with no query string, discarding
|
|
13
|
+
whatever filter state the user had on the Tasks page.
|
|
14
|
+
|
|
15
|
+
Concretely: a user at `/tasks?project=foo&page=2` clicks a task, lands on
|
|
16
|
+
`/tasks/<id>`, then clicks "返回" → router navigates to `/tasks` (no `?project=foo&page=2`).
|
|
17
|
+
`useSearchParams()` returns empty values, so the Tasks page re-renders showing
|
|
18
|
+
all tasks from page 1.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Fix Points
|
|
23
|
+
|
|
24
|
+
| File | Change |
|
|
25
|
+
|------|--------|
|
|
26
|
+
| `web/src/utils/navigation.ts` (new) | Pure function `resolveBackTo(state, fallback='/tasks'): string` with full type narrowing — no `as any`. |
|
|
27
|
+
| `web/src/pages/Tasks.tsx` | Added `useLocation` import. Added `const location = useLocation()` in component body. Changed `navigate(\`/tasks/${task.id}\`)` to `navigate(\`/tasks/${task.id}\`, { state: { from: location.pathname + location.search } })`. |
|
|
28
|
+
| `web/src/pages/TaskDetail.tsx` | Added `useLocation` + `resolveBackTo` imports. Added `const location = useLocation()` and `const backTo = resolveBackTo(location.state)` in component body. Replaced both `<Link to="/tasks">` with `<Link to={backTo}>` (error branch line ~161, success branch line ~195). |
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## New Tests
|
|
33
|
+
|
|
34
|
+
**File**: `tests/unit/web/navigation-back-contract.test.ts`
|
|
35
|
+
|
|
36
|
+
21 contract tests across 4 suites:
|
|
37
|
+
|
|
38
|
+
1. **fallback path** (7 tests) — `state` is `null`, `undefined`, `{}`, `{ from: undefined }`, `{ from: '' }`, custom fallback with `null`, custom fallback with `{}`.
|
|
39
|
+
2. **happy path** (5 tests) — `state.from` carries full query string with project filter, page number, preset, search; plain `/tasks` (no query string).
|
|
40
|
+
3. **type safety** (6 tests) — `state.from` is number, array, object, `null`; `state` itself is a number or string — all fall back gracefully.
|
|
41
|
+
4. **navigation state construction** (3 tests) — verifies the `location.pathname + location.search` encoding round-trips without mutation; handles empty search string.
|
|
42
|
+
|
|
43
|
+
Tests import from the real `web/src/utils/navigation.ts` module.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Regression Test Results
|
|
48
|
+
|
|
49
|
+
| Run | Files | Tests | Failures |
|
|
50
|
+
|-----|-------|-------|---------|
|
|
51
|
+
| Pre-change baseline | 1 failed / 29 passed | 1 failed / 359 passed | `sqlite-refactor-harness.test.ts` (pre-existing, unrelated) |
|
|
52
|
+
| Post-fix | 1 failed / 29 passed | 1 failed / 359 passed | same pre-existing failure only |
|
|
53
|
+
|
|
54
|
+
- `npm run build` (web/): clean — 0 TypeScript errors, 0 Vite errors
|
|
55
|
+
- `npx tsc --noEmit` (project root): 0 errors
|
|
56
|
+
- `npx tsc --noEmit` (web/): 0 errors (run as part of `npm run build`)
|
|
57
|
+
- New safety-net: 21/21 pass
|
|
58
|
+
- Existing tasks contract: 15/15 pass (no regression)
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Hotfix Report: Tasks Page White Screen
|
|
2
|
+
|
|
3
|
+
**Bug slug**: tasks-page-white-screen
|
|
4
|
+
**Date**: 2026-05-18
|
|
5
|
+
**Severity**: P0 (production white screen on Tasks nav item click)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Root Cause
|
|
10
|
+
|
|
11
|
+
### Error Chain
|
|
12
|
+
|
|
13
|
+
1. `web/src/App.tsx:12` lazy-imports `./pages/Tasks`
|
|
14
|
+
2. `Tasks.tsx` (pre-fix) called `GET /api/tasks` and did `return res.json()` — treating the response body as `Task[]`
|
|
15
|
+
3. `GET /api/tasks` actually returns `{ items: Task[], total: number, has_more: boolean }` — a paginated wrapper (`TaskPage`), not a bare array
|
|
16
|
+
4. The component called `tasks.filter(...)` on the `TaskPage` object, which has no `.filter` method → `TypeError: tasks.filter is not a function`
|
|
17
|
+
5. React's error boundary was not configured → unhandled `TypeError` inside `<Suspense>` → white screen
|
|
18
|
+
|
|
19
|
+
### Why This Shape Mismatch Existed
|
|
20
|
+
|
|
21
|
+
The backend `/api/tasks` route was upgraded (v8.50.6 implementation task `tasks-filter-pagination`) to add filter + pagination support, returning `{ items, total, has_more }`. The `Tasks.tsx` component was a pre-existing stub that was never updated to consume the new paginated shape.
|
|
22
|
+
|
|
23
|
+
### Why v8.50.6 Spec Walked Off Target
|
|
24
|
+
|
|
25
|
+
The planner agent generating the v8.50.6 spec analyzed `src/web/routes/tasks.ts` (backend) but did not inspect `web/src/pages/Tasks.tsx` (frontend). It documented the backend correctly but left the frontend in an inconsistent state. Additionally, `CLAUDE.md` was incorrectly updated to say the frontend uses "原生 HTML + Vanilla JS" (Vanilla JS) rather than React + Vite — this misdirected future agents away from looking in `web/`.
|
|
26
|
+
|
|
27
|
+
**How to avoid next time**:
|
|
28
|
+
- When modifying a backend API shape, always grep for frontend consumers in `web/src/` before closing the task
|
|
29
|
+
- `CLAUDE.md` tech stack description is a critical navigation signal for agents — any incorrect entry should be treated as a P1 issue
|
|
30
|
+
- Add a CI check or spec gate: "if API response shape changes, verify frontend page component is updated"
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Fix Points
|
|
35
|
+
|
|
36
|
+
### Modified Files
|
|
37
|
+
|
|
38
|
+
| File | Lines | Change |
|
|
39
|
+
|------|-------|--------|
|
|
40
|
+
| `web/src/pages/Tasks.tsx` | full rewrite (~290 lines) | Fix `fetchTasks` to return `TaskPage`, destructure `items`/`total`/`has_more`, add pagination + project filter + time presets + URL sync via `useSearchParams` |
|
|
41
|
+
| `CLAUDE.md` | line 184 | Restore frontend description to React 18 + Vite + Tailwind + react-router-dom + react-query + Recharts |
|
|
42
|
+
| `src/claudemd/claudemd-generator.ts` | line 737 | Same correction in the embedded template (escaped backtick) |
|
|
43
|
+
|
|
44
|
+
### New Files
|
|
45
|
+
|
|
46
|
+
| File | Purpose |
|
|
47
|
+
|------|---------|
|
|
48
|
+
| `tests/unit/web/tasks-component-contract.test.ts` | Safety-net: 15 tests locking the `{ items, total, has_more }` API contract and documenting the broken consumer behaviour |
|
|
49
|
+
|
|
50
|
+
### Key Code Fix
|
|
51
|
+
|
|
52
|
+
Before (broken):
|
|
53
|
+
```typescript
|
|
54
|
+
async function fetchTasks(): Promise<Task[]> {
|
|
55
|
+
const res = await fetch('/api/tasks')
|
|
56
|
+
if (!res.ok) throw new Error('Failed to fetch tasks')
|
|
57
|
+
return res.json() // returns TaskPage object, not Task[]
|
|
58
|
+
}
|
|
59
|
+
// ...
|
|
60
|
+
const { data: tasks } = useQuery({ queryFn: fetchTasks })
|
|
61
|
+
tasks.filter(...) // TypeError: tasks.filter is not a function
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
After (fixed):
|
|
65
|
+
```typescript
|
|
66
|
+
async function fetchTasks(params: URLSearchParams): Promise<TaskPage> {
|
|
67
|
+
const res = await fetch(`/api/tasks?${params.toString()}`)
|
|
68
|
+
if (!res.ok) throw new Error('Failed to fetch tasks')
|
|
69
|
+
return res.json() as Promise<TaskPage>
|
|
70
|
+
}
|
|
71
|
+
// ...
|
|
72
|
+
const { data } = useQuery({ queryFn: () => fetchTasks(queryParams) })
|
|
73
|
+
const tasks = data?.items ?? [] // correct: array from paginated wrapper
|
|
74
|
+
const total = data?.total ?? 0
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## New Tests (Safety-Net)
|
|
80
|
+
|
|
81
|
+
File: `tests/unit/web/tasks-component-contract.test.ts`
|
|
82
|
+
|
|
83
|
+
15 tests in 4 groups:
|
|
84
|
+
1. **API response shape** (5 tests) — asserts `{ items, total, has_more }` structure
|
|
85
|
+
2. **[CHAR] broken consumer** (2 tests) — documents the pre-fix white screen defect: `consumeTasksResponseBROKEN` returns object not array, `.filter()` throws `TypeError`
|
|
86
|
+
3. **Correct consumer** (5 tests) — contract the fix satisfies: array extraction, field access, empty page
|
|
87
|
+
4. **Pagination parameters** (3 tests) — default limit 50, valid page sizes [20, 50, 100], offset formula
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Regression Test Results
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
Test Files 1 failed | 28 passed (29)
|
|
95
|
+
Tests 1 failed | 338 passed (339)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The 1 pre-existing failure (`sqlite-refactor-harness.test.ts:166 linkEventToTask`) was present before this hotfix and is unrelated (UUID validation in test fixture). 15 new safety-net tests all pass.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Build Evidence
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
web/dist/assets/Tasks-D98y3WV2.js (3.xx kB — new chunk)
|
|
106
|
+
dist/web/static/assets/Tasks-D98y3WV2.js (copied to production path)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`curl -sI http://127.0.0.1:3721/` → `200 OK`
|
|
110
|
+
`curl -s http://127.0.0.1:3721/ | grep -c "vite|module"` → `8` (React app, not vanilla HTML)
|
|
111
|
+
`curl -s "http://127.0.0.1:3721/api/tasks?limit=1"` → `{"items":[...],"total":393,"has_more":true}`
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Verification Checklist
|
|
116
|
+
|
|
117
|
+
- [x] `web/` TypeScript: `npx tsc --noEmit` → 0 errors
|
|
118
|
+
- [x] Root TypeScript: `npx tsc --noEmit` → 0 errors
|
|
119
|
+
- [x] `web/npm run build` → succeeds, Tasks chunk present
|
|
120
|
+
- [x] Root `npm run build` → succeeds, chunk copied to `dist/web/static/assets/`
|
|
121
|
+
- [x] Safety-net tests: 15/15 pass
|
|
122
|
+
- [x] Full suite: 338/339 pass (pre-existing failure unrelated)
|
|
123
|
+
- [x] `curl http://127.0.0.1:3721/` → 200 OK, HTML contains vite module references
|
|
124
|
+
- [x] API returns `{ items, total, has_more }` shape confirmed
|
|
125
|
+
- [x] `CLAUDE.md` and `claudemd-generator.ts` frontend description corrected
|
|
126
|
+
- [ ] Daemon restart (requires manual: `./scripts/dev-daemon.sh restart`)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@winspan/claude-forge",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.51.0",
|
|
4
4
|
"description": "SDLC intelligent orchestration engine for Claude Code",
|
|
5
5
|
"main": "dist/cli/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
12
|
"prebuild": "rm -rf dist",
|
|
13
|
-
"build": "tsc && mkdir -p dist/hooks && cp -r src/hooks/* dist/hooks/ && chmod +x dist/hooks/*.sh && chmod +x dist/cli/index.js && cp src/core/storage/schema.sql dist/core/storage/schema.sql && mkdir -p dist/daemon/launchd && cp src/daemon/launchd/*.template dist/daemon/launchd/ && mkdir -p dist/skills/official && cp src/skills/official/*.md dist/skills/official/ && mkdir -p dist/web/static && cp -r web/dist/* dist/web/static/ 2>/dev/null || cp src/web/static/index.html dist/web/static/ && cp -r src/web/static/vendor dist/web/static/ 2>/dev/null || true",
|
|
13
|
+
"build": "tsc && mkdir -p dist/hooks && cp -r src/hooks/* dist/hooks/ && chmod +x dist/hooks/*.sh && chmod +x dist/cli/index.js && cp src/core/storage/schema.sql dist/core/storage/schema.sql && mkdir -p dist/daemon/launchd && cp src/daemon/launchd/*.template dist/daemon/launchd/ && mkdir -p dist/skills/official && cp src/skills/official/*.md dist/skills/official/ && mkdir -p dist/claudemd/templates && cp src/claudemd/templates/*.md dist/claudemd/templates/ && mkdir -p dist/web/static && cp -r web/dist/* dist/web/static/ 2>/dev/null || cp src/web/static/index.html dist/web/static/ && cp -r src/web/static/vendor dist/web/static/ 2>/dev/null || true && (test -f dist/core/storage/schema.sql || (echo '[build] FATAL: dist/core/storage/schema.sql missing' && exit 1)) && (test -f dist/claudemd/templates/swarm-protocol.md || (echo '[build] FATAL: dist/claudemd/templates/swarm-protocol.md missing' && exit 1))",
|
|
14
14
|
"test": "vitest run",
|
|
15
15
|
"test:watch": "vitest",
|
|
16
16
|
"dev:daemon": "./scripts/dev-daemon.sh",
|