gsd-pi 2.44.0-dev.62b5d6c → 2.44.0-dev.73f2fd5
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/README.md +30 -12
- package/dist/resources/extensions/gsd/auto/infra-errors.js +3 -0
- package/dist/resources/extensions/gsd/auto/phases.js +36 -36
- package/dist/resources/extensions/gsd/auto-prompts.js +24 -1
- package/dist/resources/extensions/gsd/auto-start.js +10 -0
- package/dist/resources/extensions/gsd/auto-timers.js +57 -3
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +4 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +9 -6
- package/dist/resources/extensions/gsd/auto.js +30 -3
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +156 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -12
- package/dist/resources/extensions/gsd/commands/catalog.js +6 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
- package/dist/resources/extensions/gsd/commands-mcp-status.js +187 -0
- package/dist/resources/extensions/gsd/db-writer.js +34 -16
- package/dist/resources/extensions/gsd/doctor.js +8 -0
- package/dist/resources/extensions/gsd/git-service.js +8 -3
- package/dist/resources/extensions/gsd/gsd-db.js +12 -1
- package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
- package/dist/resources/extensions/gsd/preferences.js +9 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +3 -14
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
- package/dist/resources/extensions/gsd/provider-error-pause.js +7 -0
- package/dist/resources/extensions/gsd/state.js +19 -2
- package/dist/resources/extensions/gsd/tools/plan-slice.js +1 -0
- package/dist/resources/extensions/gsd/tools/plan-task.js +1 -0
- package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -0
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +88 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +6 -0
- package/dist/resources/extensions/mcp-client/index.js +14 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +3 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +15 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
- package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/local-model-check.d.ts +15 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.js +41 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +20 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
- package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +6 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/main.js +17 -0
- package/packages/pi-coding-agent/dist/main.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js +32 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +3 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +8 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +12 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts +15 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js +40 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +4 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +5 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +13 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +17 -8
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +7 -3
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
- package/packages/pi-coding-agent/src/core/auth-storage.ts +15 -1
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
- package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
- package/packages/pi-coding-agent/src/core/local-model-check.ts +45 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +21 -1
- package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
- package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
- package/packages/pi-coding-agent/src/core/settings-manager.ts +9 -0
- package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
- package/packages/pi-coding-agent/src/main.ts +19 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/timestamp.test.ts +38 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +10 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/timestamp.ts +48 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +3 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +18 -3
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +16 -7
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +8 -1
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
- package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
- package/src/resources/extensions/gsd/auto/phases.ts +45 -48
- package/src/resources/extensions/gsd/auto-prompts.ts +24 -1
- package/src/resources/extensions/gsd/auto-start.ts +14 -0
- package/src/resources/extensions/gsd/auto-timers.ts +64 -3
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +5 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +9 -6
- package/src/resources/extensions/gsd/auto.ts +37 -3
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +148 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +48 -11
- package/src/resources/extensions/gsd/commands/catalog.ts +6 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
- package/src/resources/extensions/gsd/commands-mcp-status.ts +247 -0
- package/src/resources/extensions/gsd/db-writer.ts +39 -17
- package/src/resources/extensions/gsd/doctor.ts +7 -1
- package/src/resources/extensions/gsd/git-service.ts +6 -2
- package/src/resources/extensions/gsd/gsd-db.ts +16 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +1 -1
- package/src/resources/extensions/gsd/preferences.ts +11 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
- package/src/resources/extensions/gsd/prompts/replan-slice.md +3 -14
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
- package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
- package/src/resources/extensions/gsd/state.ts +19 -1
- package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
- package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
- package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
- package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
- package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
- package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
- package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
- package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
- package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +38 -59
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +228 -263
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +250 -302
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
- package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
- package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
- package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +465 -416
- package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +210 -181
- package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
- package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
- package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
- package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
- package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
- package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
- package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
- package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
- package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
- package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
- package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
- package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
- package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
- package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
- package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
- package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
- package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
- package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
- package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
- package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
- package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
- package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
- package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -102
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +20 -2
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
- package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
- package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
- package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
- package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +80 -93
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
- package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
- package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
- package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
- package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +35 -36
- package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
- package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
- package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
- package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
- package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
- package/src/resources/extensions/gsd/tests/preferences.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +11 -7
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
- package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
- package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
- package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
- package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
- package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
- package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
- package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
- package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
- package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
- package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
- package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
- package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +10 -11
- package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
- package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
- package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
- package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
- package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
- package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
- package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
- package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
- package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
- package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +2 -0
- package/src/resources/extensions/gsd/tools/replan-slice.ts +3 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +127 -0
- package/src/resources/extensions/gsd/worktree-resolver.ts +7 -0
- package/src/resources/extensions/mcp-client/index.ts +20 -0
- /package/dist/web/standalone/.next/static/{fOnWQBjWXMKUs4bqTg530 → kxxAA66bah_yhPYqLBHE2}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{fOnWQBjWXMKUs4bqTg530 → kxxAA66bah_yhPYqLBHE2}/_ssgManifest.js +0 -0
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
// (b) Helpers fall back to non-null output when DB unavailable
|
|
6
6
|
// (c) Scoped filtering actually reduces content
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { describe, test } from 'node:test';
|
|
9
|
+
import assert from 'node:assert/strict';
|
|
9
10
|
import {
|
|
10
11
|
openDatabase,
|
|
11
12
|
closeDatabase,
|
|
@@ -22,8 +23,6 @@ import {
|
|
|
22
23
|
formatRequirementsForPrompt,
|
|
23
24
|
} from '../context-store.ts';
|
|
24
25
|
|
|
25
|
-
const { assertEq, assertTrue, assertMatch, assertNoMatch, report } = createTestContext();
|
|
26
|
-
|
|
27
26
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
28
27
|
// prompt-db: DB-aware decisions helper returns scoped content
|
|
29
28
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -50,23 +49,23 @@ console.log('\n=== prompt-db: scoped decisions from DB ===');
|
|
|
50
49
|
|
|
51
50
|
// Query scoped to M001
|
|
52
51
|
const m001Decisions = queryDecisions({ milestoneId: 'M001' });
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
assert.ok(m001Decisions.length > 0, 'M001 decisions should exist');
|
|
53
|
+
assert.ok(m001Decisions.length < 10, `scoped query should return fewer than 10 (got ${m001Decisions.length})`);
|
|
55
54
|
|
|
56
55
|
// Verify all returned decisions are for M001
|
|
57
56
|
for (const d of m001Decisions) {
|
|
58
|
-
|
|
57
|
+
assert.match(d.when_context, /M001/, `decision ${d.id} should be for M001`);
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
// Format and verify wrapping
|
|
62
61
|
const formatted = formatDecisionsForPrompt(m001Decisions);
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
assert.ok(formatted.length > 0, 'formatted decisions should be non-empty');
|
|
63
|
+
assert.match(formatted, /\| # \| When \| Scope/, 'formatted decisions have table header');
|
|
65
64
|
|
|
66
65
|
// Verify the expected wrapper format that inlineDecisionsFromDb would produce
|
|
67
66
|
const wrapped = `### Decisions\nSource: \`.gsd/DECISIONS.md\`\n\n${formatted}`;
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
assert.match(wrapped, /^### Decisions/, 'wrapped decisions start with ### Decisions');
|
|
68
|
+
assert.match(wrapped, /Source:.*DECISIONS\.md/, 'wrapped decisions have source path');
|
|
70
69
|
|
|
71
70
|
closeDatabase();
|
|
72
71
|
}
|
|
@@ -101,25 +100,25 @@ console.log('\n=== prompt-db: scoped requirements from DB ===');
|
|
|
101
100
|
|
|
102
101
|
// Query scoped to S01 — should get R001 (primary) and R002 (supporting)
|
|
103
102
|
const s01Reqs = queryRequirements({ sliceId: 'S01' });
|
|
104
|
-
|
|
103
|
+
assert.deepStrictEqual(s01Reqs.length, 2, 'S01 requirements should be 2 (primary + supporting)');
|
|
105
104
|
const ids = s01Reqs.map(r => r.id).sort();
|
|
106
|
-
|
|
105
|
+
assert.deepStrictEqual(ids, ['R001', 'R002'], 'S01 owns R001 and supports R002');
|
|
107
106
|
|
|
108
107
|
// Unscoped query returns all 3
|
|
109
108
|
const allReqs = queryRequirements();
|
|
110
|
-
|
|
109
|
+
assert.deepStrictEqual(allReqs.length, 3, 'unscoped requirements should return all 3');
|
|
111
110
|
|
|
112
111
|
// Format and verify wrapping
|
|
113
112
|
const formatted = formatRequirementsForPrompt(s01Reqs);
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
113
|
+
assert.ok(formatted.length > 0, 'formatted requirements should be non-empty');
|
|
114
|
+
assert.match(formatted, /### R001/, 'formatted requirements include R001');
|
|
115
|
+
assert.match(formatted, /### R002/, 'formatted requirements include R002');
|
|
116
|
+
assert.doesNotMatch(formatted, /### R003/, 'formatted requirements exclude R003');
|
|
118
117
|
|
|
119
118
|
// Verify the expected wrapper format that inlineRequirementsFromDb would produce
|
|
120
119
|
const wrapped = `### Requirements\nSource: \`.gsd/REQUIREMENTS.md\`\n\n${formatted}`;
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
assert.match(wrapped, /^### Requirements/, 'wrapped requirements start with ### Requirements');
|
|
121
|
+
assert.match(wrapped, /Source:.*REQUIREMENTS\.md/, 'wrapped requirements have source path');
|
|
123
122
|
|
|
124
123
|
closeDatabase();
|
|
125
124
|
}
|
|
@@ -142,13 +141,13 @@ console.log('\n=== prompt-db: project content from DB ===');
|
|
|
142
141
|
});
|
|
143
142
|
|
|
144
143
|
const content = queryProject();
|
|
145
|
-
|
|
144
|
+
assert.deepStrictEqual(content, '# Test Project\n\nThis is the project description.', 'queryProject returns content');
|
|
146
145
|
|
|
147
146
|
// Verify the expected wrapper format that inlineProjectFromDb would produce
|
|
148
147
|
const wrapped = `### Project\nSource: \`.gsd/PROJECT.md\`\n\n${content}`;
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
148
|
+
assert.match(wrapped, /^### Project/, 'wrapped project starts with ### Project');
|
|
149
|
+
assert.match(wrapped, /Source:.*PROJECT\.md/, 'wrapped project has source path');
|
|
150
|
+
assert.match(wrapped, /# Test Project/, 'wrapped project includes content');
|
|
152
151
|
|
|
153
152
|
closeDatabase();
|
|
154
153
|
}
|
|
@@ -160,27 +159,27 @@ console.log('\n=== prompt-db: project content from DB ===');
|
|
|
160
159
|
console.log('\n=== prompt-db: fallback when DB unavailable ===');
|
|
161
160
|
{
|
|
162
161
|
closeDatabase();
|
|
163
|
-
|
|
162
|
+
assert.ok(!isDbAvailable(), 'DB should not be available');
|
|
164
163
|
|
|
165
164
|
// queryDecisions returns [] when DB closed — helper would fall back
|
|
166
165
|
const decisions = queryDecisions({ milestoneId: 'M001' });
|
|
167
|
-
|
|
166
|
+
assert.deepStrictEqual(decisions, [], 'queryDecisions returns [] when DB closed');
|
|
168
167
|
|
|
169
168
|
// queryRequirements returns [] when DB closed — helper would fall back
|
|
170
169
|
const requirements = queryRequirements({ sliceId: 'S01' });
|
|
171
|
-
|
|
170
|
+
assert.deepStrictEqual(requirements, [], 'queryRequirements returns [] when DB closed');
|
|
172
171
|
|
|
173
172
|
// queryProject returns null when DB closed — helper would fall back
|
|
174
173
|
const project = queryProject();
|
|
175
|
-
|
|
174
|
+
assert.deepStrictEqual(project, null, 'queryProject returns null when DB closed');
|
|
176
175
|
|
|
177
176
|
// formatDecisionsForPrompt returns '' for empty input
|
|
178
177
|
const formatted = formatDecisionsForPrompt([]);
|
|
179
|
-
|
|
178
|
+
assert.deepStrictEqual(formatted, '', 'formatDecisionsForPrompt returns empty for empty input');
|
|
180
179
|
|
|
181
180
|
// formatRequirementsForPrompt returns '' for empty input
|
|
182
181
|
const formattedReqs = formatRequirementsForPrompt([]);
|
|
183
|
-
|
|
182
|
+
assert.deepStrictEqual(formattedReqs, '', 'formatRequirementsForPrompt returns empty for empty input');
|
|
184
183
|
}
|
|
185
184
|
|
|
186
185
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -210,15 +209,15 @@ console.log('\n=== prompt-db: scoped filtering reduces content ===');
|
|
|
210
209
|
const allDecisions = queryDecisions();
|
|
211
210
|
const m001Decisions = queryDecisions({ milestoneId: 'M001' });
|
|
212
211
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
212
|
+
assert.deepStrictEqual(allDecisions.length, 10, 'unscoped returns all 10 decisions');
|
|
213
|
+
assert.ok(m001Decisions.length < 10, `M001-scoped returns fewer than 10 (got ${m001Decisions.length})`);
|
|
214
|
+
assert.ok(m001Decisions.length > 0, 'M001-scoped returns at least 1');
|
|
216
215
|
|
|
217
216
|
// Format both and compare sizes — scoped should be shorter
|
|
218
217
|
const allFormatted = formatDecisionsForPrompt(allDecisions);
|
|
219
218
|
const scopedFormatted = formatDecisionsForPrompt(m001Decisions);
|
|
220
219
|
|
|
221
|
-
|
|
220
|
+
assert.ok(
|
|
222
221
|
scopedFormatted.length < allFormatted.length,
|
|
223
222
|
`scoped content (${scopedFormatted.length} chars) should be shorter than unscoped (${allFormatted.length} chars)`,
|
|
224
223
|
);
|
|
@@ -245,14 +244,14 @@ console.log('\n=== prompt-db: scoped filtering reduces content ===');
|
|
|
245
244
|
const allReqs = queryRequirements();
|
|
246
245
|
const s01Reqs = queryRequirements({ sliceId: 'S01' });
|
|
247
246
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
247
|
+
assert.deepStrictEqual(allReqs.length, 8, 'unscoped returns all 8 requirements');
|
|
248
|
+
assert.ok(s01Reqs.length < 8, `S01-scoped returns fewer than 8 (got ${s01Reqs.length})`);
|
|
249
|
+
assert.ok(s01Reqs.length > 0, 'S01-scoped returns at least 1');
|
|
251
250
|
|
|
252
251
|
const allReqsFormatted = formatRequirementsForPrompt(allReqs);
|
|
253
252
|
const scopedReqsFormatted = formatRequirementsForPrompt(s01Reqs);
|
|
254
253
|
|
|
255
|
-
|
|
254
|
+
assert.ok(
|
|
256
255
|
scopedReqsFormatted.length < allReqsFormatted.length,
|
|
257
256
|
`scoped requirements (${scopedReqsFormatted.length} chars) should be shorter than unscoped (${allReqsFormatted.length} chars)`,
|
|
258
257
|
);
|
|
@@ -292,23 +291,23 @@ console.log('\n=== prompt-db: DB helpers wrapper format matches expected pattern
|
|
|
292
291
|
|
|
293
292
|
// Simulate what inlineDecisionsFromDb does
|
|
294
293
|
const decisions = queryDecisions({ milestoneId: 'M001' });
|
|
295
|
-
|
|
294
|
+
assert.ok(decisions.length === 1, 'got 1 decision for M001');
|
|
296
295
|
const dFormatted = formatDecisionsForPrompt(decisions);
|
|
297
296
|
const dWrapped = `### Decisions\nSource: \`.gsd/DECISIONS.md\`\n\n${dFormatted}`;
|
|
298
|
-
|
|
297
|
+
assert.match(dWrapped, /^### Decisions\nSource: `.gsd\/DECISIONS\.md`\n\n\| #/, 'decisions wrapper format correct');
|
|
299
298
|
|
|
300
299
|
// Simulate what inlineRequirementsFromDb does
|
|
301
300
|
const reqs = queryRequirements({ sliceId: 'S01' });
|
|
302
|
-
|
|
301
|
+
assert.ok(reqs.length === 1, 'got 1 requirement for S01');
|
|
303
302
|
const rFormatted = formatRequirementsForPrompt(reqs);
|
|
304
303
|
const rWrapped = `### Requirements\nSource: \`.gsd/REQUIREMENTS.md\`\n\n${rFormatted}`;
|
|
305
|
-
|
|
304
|
+
assert.match(rWrapped, /^### Requirements\nSource: `.gsd\/REQUIREMENTS\.md`\n\n### R001/, 'requirements wrapper format correct');
|
|
306
305
|
|
|
307
306
|
// Simulate what inlineProjectFromDb does
|
|
308
307
|
const project = queryProject();
|
|
309
|
-
|
|
308
|
+
assert.ok(project !== null, 'project content exists');
|
|
310
309
|
const pWrapped = `### Project\nSource: \`.gsd/PROJECT.md\`\n\n${project}`;
|
|
311
|
-
|
|
310
|
+
assert.match(pWrapped, /^### Project\nSource: `.gsd\/PROJECT\.md`\n\n# Project Name/, 'project wrapper format correct');
|
|
312
311
|
|
|
313
312
|
closeDatabase();
|
|
314
313
|
}
|
|
@@ -322,8 +321,9 @@ import { join } from 'node:path';
|
|
|
322
321
|
import { tmpdir } from 'node:os';
|
|
323
322
|
import { migrateFromMarkdown } from '../md-importer.ts';
|
|
324
323
|
|
|
325
|
-
|
|
326
|
-
{
|
|
324
|
+
|
|
325
|
+
describe('prompt-db', () => {
|
|
326
|
+
test('prompt-db: re-import updates DB when source markdown changes', () => {
|
|
327
327
|
// Create a temp dir simulating a project with .gsd/DECISIONS.md
|
|
328
328
|
const tmpDir = mkdtempSync(join(tmpdir(), 'prompt-db-reimport-'));
|
|
329
329
|
const gsdDir = join(tmpDir, '.gsd');
|
|
@@ -345,9 +345,9 @@ console.log('\n=== prompt-db: re-import updates DB when source markdown changes
|
|
|
345
345
|
|
|
346
346
|
// Verify initial state: 2 decisions
|
|
347
347
|
const initial = queryDecisions();
|
|
348
|
-
|
|
348
|
+
assert.deepStrictEqual(initial.length, 2, 're-import: initial import has 2 decisions');
|
|
349
349
|
const initialIds = initial.map(d => d.id).sort();
|
|
350
|
-
|
|
350
|
+
assert.deepStrictEqual(initialIds, ['D001', 'D002'], 're-import: initial decisions are D001, D002');
|
|
351
351
|
|
|
352
352
|
// Now "the LLM modifies DECISIONS.md" — add a third decision
|
|
353
353
|
const updatedDecisions = `# Decisions Register
|
|
@@ -365,23 +365,23 @@ console.log('\n=== prompt-db: re-import updates DB when source markdown changes
|
|
|
365
365
|
|
|
366
366
|
// Verify DB now has 3 decisions
|
|
367
367
|
const afterReimport = queryDecisions();
|
|
368
|
-
|
|
368
|
+
assert.deepStrictEqual(afterReimport.length, 3, 're-import: after re-import has 3 decisions');
|
|
369
369
|
const afterIds = afterReimport.map(d => d.id).sort();
|
|
370
|
-
|
|
370
|
+
assert.deepStrictEqual(afterIds, ['D001', 'D002', 'D003'], 're-import: decisions are D001, D002, D003');
|
|
371
371
|
|
|
372
372
|
// Verify the new decision has correct data
|
|
373
373
|
const d003 = afterReimport.find(d => d.id === 'D003');
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
374
|
+
assert.ok(d003 !== undefined, 're-import: D003 exists');
|
|
375
|
+
assert.deepStrictEqual(d003!.when_context, 'M001/S02', 're-import: D003 when_context is M001/S02');
|
|
376
|
+
assert.deepStrictEqual(d003!.scope, 'runtime', 're-import: D003 scope is runtime');
|
|
377
|
+
assert.deepStrictEqual(d003!.choice, 'D014 pattern', 're-import: D003 choice is D014 pattern');
|
|
378
378
|
|
|
379
379
|
// Verify scoped query picks up the new decision
|
|
380
380
|
const m001Scoped = queryDecisions({ milestoneId: 'M001' });
|
|
381
|
-
|
|
381
|
+
assert.ok(m001Scoped.length === 3, 're-import: all 3 decisions are for M001');
|
|
382
382
|
|
|
383
383
|
closeDatabase();
|
|
384
|
-
}
|
|
384
|
+
});
|
|
385
385
|
|
|
386
386
|
// ─── Final Report ──────────────────────────────────────────────────────────
|
|
387
|
-
|
|
387
|
+
});
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { describe, test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
1
3
|
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
2
4
|
import { join } from "node:path";
|
|
3
5
|
import { tmpdir } from "node:os";
|
|
@@ -5,122 +7,94 @@ import { tmpdir } from "node:os";
|
|
|
5
7
|
import { deriveState } from "../state.js";
|
|
6
8
|
import { buildExistingMilestonesContext } from "../guided-flow.js";
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
writeFileSync(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
//
|
|
40
|
-
mkdirSync(join(gsd, "milestones", "
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
assert(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
assert(
|
|
100
|
-
m003Section.includes("This is the real context"),
|
|
101
|
-
"M003 should show CONTEXT.md content, not draft content",
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
// ─── Test: neither file → no context section ───────────────────────────
|
|
105
|
-
|
|
106
|
-
const m004Idx = context.indexOf("M004:");
|
|
107
|
-
const m004Section = context.slice(m004Idx, m004Idx + 500);
|
|
108
|
-
|
|
109
|
-
assert(
|
|
110
|
-
!m004Section.includes("**Context:**"),
|
|
111
|
-
"M004 (neither file) should not have Context: label",
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
assert(
|
|
115
|
-
!m004Section.includes("Draft context available"),
|
|
116
|
-
"M004 (neither file) should not have Draft label",
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
// ─── Cleanup ──────────────────────────────────────────────────────────
|
|
120
|
-
|
|
121
|
-
rmSync(tmpBase, { recursive: true, force: true });
|
|
122
|
-
|
|
123
|
-
// ─── Results ──────────────────────────────────────────────────────────
|
|
124
|
-
|
|
125
|
-
console.log(`\nqueue-draft-detection: ${passed} passed, ${failed} failed`);
|
|
126
|
-
if (failed > 0) process.exit(1);
|
|
10
|
+
describe('queue-draft-detection', () => {
|
|
11
|
+
test('draft and context milestone detection', async () => {
|
|
12
|
+
const tmpBase = mkdtempSync(join(tmpdir(), "gsd-queue-draft-test-"));
|
|
13
|
+
const gsd = join(tmpBase, ".gsd");
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
// M001: has only CONTEXT-DRAFT.md (draft milestone)
|
|
17
|
+
mkdirSync(join(gsd, "milestones", "M001"), { recursive: true });
|
|
18
|
+
writeFileSync(
|
|
19
|
+
join(gsd, "milestones", "M001", "M001-CONTEXT-DRAFT.md"),
|
|
20
|
+
"# M001: Draft Milestone\n\nSeed material from prior discussion.\n",
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
// M002: has full CONTEXT.md (ready milestone)
|
|
24
|
+
mkdirSync(join(gsd, "milestones", "M002"), { recursive: true });
|
|
25
|
+
writeFileSync(
|
|
26
|
+
join(gsd, "milestones", "M002", "M002-CONTEXT.md"),
|
|
27
|
+
"# M002: Ready Milestone\n\nFull context from deep discussion.\n",
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
// M003: has both CONTEXT.md and CONTEXT-DRAFT.md (CONTEXT wins)
|
|
31
|
+
mkdirSync(join(gsd, "milestones", "M003"), { recursive: true });
|
|
32
|
+
writeFileSync(
|
|
33
|
+
join(gsd, "milestones", "M003", "M003-CONTEXT.md"),
|
|
34
|
+
"# M003: Full Context\n\nThis is the real context.\n",
|
|
35
|
+
);
|
|
36
|
+
writeFileSync(
|
|
37
|
+
join(gsd, "milestones", "M003", "M003-CONTEXT-DRAFT.md"),
|
|
38
|
+
"# M003: Draft\n\nThis should be ignored.\n",
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// M004: has neither (empty milestone dir)
|
|
42
|
+
mkdirSync(join(gsd, "milestones", "M004"), { recursive: true });
|
|
43
|
+
|
|
44
|
+
// Build context
|
|
45
|
+
const state = await deriveState(tmpBase);
|
|
46
|
+
const milestoneIds = ["M001", "M002", "M003", "M004"];
|
|
47
|
+
const context = await buildExistingMilestonesContext(tmpBase, milestoneIds, state);
|
|
48
|
+
|
|
49
|
+
// draft-only milestone includes "Draft context available"
|
|
50
|
+
assert.ok(
|
|
51
|
+
context.includes("Draft context available"),
|
|
52
|
+
"M001 (draft-only) should include 'Draft context available' label",
|
|
53
|
+
);
|
|
54
|
+
assert.ok(
|
|
55
|
+
context.includes("Seed material from prior discussion"),
|
|
56
|
+
"M001 draft content should be included in context output",
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
// full-context milestone uses "Context:" label
|
|
60
|
+
assert.ok(
|
|
61
|
+
context.includes("**Context:**"),
|
|
62
|
+
"M002 (full context) should use 'Context:' label",
|
|
63
|
+
);
|
|
64
|
+
assert.ok(
|
|
65
|
+
context.includes("Full context from deep discussion"),
|
|
66
|
+
"M002 context content should be included",
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
// both files: CONTEXT.md wins, no draft label
|
|
70
|
+
const m003Idx = context.indexOf("M003:");
|
|
71
|
+
const m003Section = context.slice(m003Idx, m003Idx + 500);
|
|
72
|
+
assert.ok(
|
|
73
|
+
m003Section.includes("**Context:**"),
|
|
74
|
+
"M003 (both files) should use 'Context:' label (CONTEXT.md wins)",
|
|
75
|
+
);
|
|
76
|
+
assert.ok(
|
|
77
|
+
!m003Section.includes("Draft context available"),
|
|
78
|
+
"M003 (both files) should NOT show draft label — CONTEXT.md takes precedence",
|
|
79
|
+
);
|
|
80
|
+
assert.ok(
|
|
81
|
+
m003Section.includes("This is the real context"),
|
|
82
|
+
"M003 should show CONTEXT.md content, not draft content",
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
// neither file: no context section
|
|
86
|
+
const m004Idx = context.indexOf("M004:");
|
|
87
|
+
const m004Section = context.slice(m004Idx, m004Idx + 500);
|
|
88
|
+
assert.ok(
|
|
89
|
+
!m004Section.includes("**Context:**"),
|
|
90
|
+
"M004 (neither file) should not have Context: label",
|
|
91
|
+
);
|
|
92
|
+
assert.ok(
|
|
93
|
+
!m004Section.includes("Draft context available"),
|
|
94
|
+
"M004 (neither file) should not have Draft label",
|
|
95
|
+
);
|
|
96
|
+
} finally {
|
|
97
|
+
rmSync(tmpBase, { recursive: true, force: true });
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
});
|