@opengsd/gsd-pi 1.1.1-dev.b2556262 → 1.2.0-dev.4813ead6
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/dist/cli-web-branch.d.ts +2 -0
- package/dist/cli-web-branch.js +9 -2
- package/dist/help-text.js +5 -0
- package/dist/project-sessions.js +4 -2
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/ask-user-questions.js +78 -23
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +101 -237
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +224 -0
- package/dist/resources/extensions/github-sync/templates.js +3 -3
- package/dist/resources/extensions/gsd/artifact-projection.js +14 -0
- package/dist/resources/extensions/gsd/auto/contracts.js +8 -1
- package/dist/resources/extensions/gsd/auto/loop.js +74 -56
- package/dist/resources/extensions/gsd/auto/orchestrator.js +763 -63
- package/dist/resources/extensions/gsd/auto/phases.js +28 -3
- package/dist/resources/extensions/gsd/auto/run-unit.js +2 -1
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +16 -4
- package/dist/resources/extensions/gsd/auto-dispatch.js +6 -5
- package/dist/resources/extensions/gsd/auto-model-selection.js +8 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +4 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +191 -9
- package/dist/resources/extensions/gsd/auto-recovery.js +48 -49
- package/dist/resources/extensions/gsd/auto-runtime-state.js +17 -0
- package/dist/resources/extensions/gsd/auto-start.js +12 -23
- package/dist/resources/extensions/gsd/auto-timers.js +16 -2
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +37 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +33 -29
- package/dist/resources/extensions/gsd/auto-verification.js +7 -7
- package/dist/resources/extensions/gsd/auto-worktree.js +45 -36
- package/dist/resources/extensions/gsd/auto.js +73 -471
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +28 -37
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +11 -37
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +103 -138
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +63 -4
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +21 -4
- package/dist/resources/extensions/gsd/codebase-generator.js +8 -4
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +3 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +20 -0
- package/dist/resources/extensions/gsd/commands-inspect.js +4 -8
- package/dist/resources/extensions/gsd/commands-maintenance.js +61 -41
- package/dist/resources/extensions/gsd/commands-ship.js +2 -2
- package/dist/resources/extensions/gsd/commands-verdict.js +12 -2
- package/dist/resources/extensions/gsd/db-workspace.js +103 -0
- package/dist/resources/extensions/gsd/debug-logger.js +10 -0
- package/dist/resources/extensions/gsd/delegation-policy.js +2 -10
- package/dist/resources/extensions/gsd/discussion-handoff.js +218 -0
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -0
- package/dist/resources/extensions/gsd/doctor-proactive.js +7 -2
- package/dist/resources/extensions/gsd/doctor.js +16 -9
- package/dist/resources/extensions/gsd/error-classifier.js +1 -1
- package/dist/resources/extensions/gsd/git-conflict-state.js +16 -1
- package/dist/resources/extensions/gsd/gsd-db.js +12 -0
- package/dist/resources/extensions/gsd/guided-flow.js +36 -470
- package/dist/resources/extensions/gsd/guided-unit-completion.js +225 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +33 -33
- package/dist/resources/extensions/gsd/mcp-filter.js +8 -1
- package/dist/resources/extensions/gsd/mcp-tool-name.js +26 -0
- package/dist/resources/extensions/gsd/md-importer.js +4 -3
- package/dist/resources/extensions/gsd/migrate/safety.js +2 -2
- package/dist/resources/extensions/gsd/migration-auto-check.js +3 -2
- package/dist/resources/extensions/gsd/milestone-closeout-proof.js +72 -0
- package/dist/resources/extensions/gsd/milestone-closeout.js +12 -4
- package/dist/resources/extensions/gsd/milestone-merge-transaction.js +10 -0
- package/dist/resources/extensions/gsd/milestone-planning-persistence.js +156 -0
- package/dist/resources/extensions/gsd/milestone-readiness.js +77 -0
- package/dist/resources/extensions/gsd/milestone-settlement.js +50 -0
- package/dist/resources/extensions/gsd/milestone-validation-evidence.js +73 -0
- package/dist/resources/extensions/gsd/milestone-validation-verdict.js +57 -0
- package/dist/resources/extensions/gsd/native-git-bridge.js +45 -0
- package/dist/resources/extensions/gsd/parallel-eligibility.js +3 -6
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/preferences-diagnostics.js +67 -0
- package/dist/resources/extensions/gsd/preferences.js +147 -29
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/discuss.md +6 -7
- package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +5 -7
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +6 -6
- package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +1 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -6
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/research-milestone.md +2 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +5 -3
- package/dist/resources/extensions/gsd/provider-payload-policy.js +83 -0
- package/dist/resources/extensions/gsd/pull-request-process.js +13 -0
- package/dist/resources/extensions/gsd/quality-gate-closure.js +109 -0
- package/dist/resources/extensions/gsd/question-transport.js +86 -0
- package/dist/resources/extensions/gsd/roadmap-slices.js +8 -2
- package/dist/resources/extensions/gsd/schemas/parsers.js +6 -1
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +21 -1
- package/dist/resources/extensions/gsd/state.js +13 -5
- package/dist/resources/extensions/gsd/templates/plan.md +7 -0
- package/dist/resources/extensions/gsd/templates/project.md +1 -0
- package/dist/resources/extensions/gsd/templates/roadmap.md +1 -1
- package/dist/resources/extensions/gsd/templates/uat.md +5 -1
- package/dist/resources/extensions/gsd/tool-contract.js +52 -8
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +15 -34
- package/dist/resources/extensions/gsd/tool-surface-snapshot.js +17 -0
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +15 -143
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +39 -0
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +15 -78
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +169 -20
- package/dist/resources/extensions/gsd/uat-policy.js +16 -10
- package/dist/resources/extensions/gsd/uat-run.js +9 -14
- package/dist/resources/extensions/gsd/unit-context-composer.js +40 -20
- package/dist/resources/extensions/gsd/unit-runtime.js +3 -2
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +2 -1
- package/dist/resources/extensions/gsd/user-input-boundary.js +65 -4
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
- package/dist/resources/extensions/gsd/web-app-uat.js +80 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +15 -102
- package/dist/resources/extensions/gsd/workflow-reconcile.js +4 -3
- package/dist/resources/extensions/gsd/workflow-tool-surface.js +46 -0
- package/dist/resources/extensions/gsd/workspace-git-guard.js +2 -0
- package/dist/resources/extensions/gsd/worktree-state-projection.js +33 -4
- package/dist/resources/extensions/gsd/worktree-telemetry.js +12 -0
- package/dist/resources/extensions/shared/interview-ui.js +2 -2
- package/dist/resources/shared/claude-runtime-floor.js +182 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -0
- package/dist/update-cmd.js +20 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +8 -8
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- 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/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +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 +5 -5
- package/dist/web/standalone/.next/server/chunks/5047.js +2 -0
- package/dist/web/standalone/.next/server/chunks/5124.js +1 -0
- package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2659.b7b129ee6a769448.js +1 -0
- package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{3616.4113d484a994e411.js → 3616.3c60753b8ffcbd2e.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/4283.e4873b058df143a1.js +2 -0
- package/dist/web/standalone/.next/static/chunks/5826.a46ecdd1cfe8dabc.js +1 -0
- package/dist/web/standalone/.next/static/chunks/796.cf859a427a2cb2ac.js +10 -0
- package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-dda80a1ef5587410.js → webpack-fbea77b5f9953368.js} +1 -1
- package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/dist/web/standalone/node_modules/postcss/lib/container.js +26 -18
- package/dist/web/standalone/node_modules/postcss/lib/css-syntax-error.js +47 -14
- package/dist/web/standalone/node_modules/postcss/lib/declaration.js +4 -4
- package/dist/web/standalone/node_modules/postcss/lib/fromJSON.js +3 -3
- package/dist/web/standalone/node_modules/postcss/lib/input.js +54 -29
- package/dist/web/standalone/node_modules/postcss/lib/lazy-result.js +47 -37
- package/dist/web/standalone/node_modules/postcss/lib/map-generator.js +26 -9
- package/dist/web/standalone/node_modules/postcss/lib/no-work-result.js +57 -55
- package/dist/web/standalone/node_modules/postcss/lib/node.js +99 -31
- package/dist/web/standalone/node_modules/postcss/lib/parse.js +1 -1
- package/dist/web/standalone/node_modules/postcss/lib/parser.js +10 -9
- package/dist/web/standalone/node_modules/postcss/lib/postcss.js +12 -12
- package/dist/web/standalone/node_modules/postcss/lib/previous-map.js +30 -11
- package/dist/web/standalone/node_modules/postcss/lib/processor.js +7 -7
- package/dist/web/standalone/node_modules/postcss/lib/result.js +5 -5
- package/dist/web/standalone/node_modules/postcss/lib/rule.js +6 -6
- package/dist/web/standalone/node_modules/postcss/lib/stringifier.js +69 -28
- package/dist/web/standalone/node_modules/postcss/lib/tokenize.js +6 -2
- package/dist/web/standalone/node_modules/postcss/package.json +48 -48
- package/dist/web-mode.d.ts +2 -0
- package/dist/web-mode.js +20 -8
- package/package.json +17 -11
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +2 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +14 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +106 -40
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +6 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/server.d.ts +10 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +8 -0
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +41 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +2 -1
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/image-models.generated.d.ts +30 -0
- package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/image-models.generated.js +30 -0
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +8 -127
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +47 -166
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +1 -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 +11 -3
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/components/input.js +1 -1
- package/packages/pi-tui/dist/components/input.js.map +1 -1
- package/packages/pi-tui/dist/keys.d.ts.map +1 -1
- package/packages/pi-tui/dist/keys.js +39 -30
- package/packages/pi-tui/dist/keys.js.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.js +22 -0
- package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/scripts/install/deps.js +10 -0
- package/scripts/link-workspace-packages.cjs +7 -40
- package/src/resources/extensions/ask-user-questions.ts +87 -24
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +126 -289
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +242 -2
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +287 -0
- package/src/resources/extensions/github-sync/templates.ts +3 -3
- package/src/resources/extensions/github-sync/tests/templates.test.ts +2 -2
- package/src/resources/extensions/gsd/artifact-projection.ts +31 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +40 -121
- package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -0
- package/src/resources/extensions/gsd/auto/loop.ts +83 -61
- package/src/resources/extensions/gsd/auto/orchestrator.ts +913 -64
- package/src/resources/extensions/gsd/auto/phases.ts +35 -3
- package/src/resources/extensions/gsd/auto/run-unit.ts +2 -1
- package/src/resources/extensions/gsd/auto/session.ts +4 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +18 -4
- package/src/resources/extensions/gsd/auto-dispatch.ts +20 -7
- package/src/resources/extensions/gsd/auto-model-selection.ts +8 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +4 -3
- package/src/resources/extensions/gsd/auto-prompts.ts +220 -9
- package/src/resources/extensions/gsd/auto-recovery.ts +50 -50
- package/src/resources/extensions/gsd/auto-runtime-state.ts +30 -0
- package/src/resources/extensions/gsd/auto-start.ts +17 -20
- package/src/resources/extensions/gsd/auto-timers.ts +16 -2
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +40 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +42 -30
- package/src/resources/extensions/gsd/auto-verification.ts +7 -8
- package/src/resources/extensions/gsd/auto-worktree.ts +57 -42
- package/src/resources/extensions/gsd/auto.ts +96 -508
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +29 -37
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +10 -37
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +120 -151
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +107 -3
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +27 -5
- package/src/resources/extensions/gsd/codebase-generator.ts +9 -5
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +3 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +18 -0
- package/src/resources/extensions/gsd/commands-inspect.ts +7 -8
- package/src/resources/extensions/gsd/commands-maintenance.ts +74 -40
- package/src/resources/extensions/gsd/commands-ship.ts +2 -2
- package/src/resources/extensions/gsd/commands-verdict.ts +19 -2
- package/src/resources/extensions/gsd/db-workspace.ts +170 -0
- package/src/resources/extensions/gsd/debug-logger.ts +11 -0
- package/src/resources/extensions/gsd/delegation-policy.ts +3 -11
- package/src/resources/extensions/gsd/discussion-handoff.ts +276 -0
- package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -0
- package/src/resources/extensions/gsd/doctor-proactive.ts +8 -2
- package/src/resources/extensions/gsd/doctor.ts +15 -5
- package/src/resources/extensions/gsd/error-classifier.ts +1 -1
- package/src/resources/extensions/gsd/git-conflict-state.ts +17 -1
- package/src/resources/extensions/gsd/gsd-db.ts +12 -0
- package/src/resources/extensions/gsd/guided-flow.ts +49 -560
- package/src/resources/extensions/gsd/guided-unit-completion.ts +275 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +40 -20
- package/src/resources/extensions/gsd/mcp-filter.ts +9 -1
- package/src/resources/extensions/gsd/mcp-tool-name.ts +35 -0
- package/src/resources/extensions/gsd/md-importer.ts +3 -3
- package/src/resources/extensions/gsd/migrate/safety.ts +2 -2
- package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
- package/src/resources/extensions/gsd/milestone-closeout-proof.ts +131 -0
- package/src/resources/extensions/gsd/milestone-closeout.ts +12 -4
- package/src/resources/extensions/gsd/milestone-merge-transaction.ts +47 -0
- package/src/resources/extensions/gsd/milestone-planning-persistence.ts +224 -0
- package/src/resources/extensions/gsd/milestone-readiness.ts +125 -0
- package/src/resources/extensions/gsd/milestone-settlement.ts +81 -0
- package/src/resources/extensions/gsd/milestone-validation-evidence.ts +95 -0
- package/src/resources/extensions/gsd/milestone-validation-verdict.ts +80 -0
- package/src/resources/extensions/gsd/native-git-bridge.ts +48 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +4 -5
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/preferences-diagnostics.ts +98 -0
- package/src/resources/extensions/gsd/preferences-types.ts +16 -0
- package/src/resources/extensions/gsd/preferences.ts +173 -28
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/discuss.md +6 -7
- package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +5 -7
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +6 -6
- package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +1 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -6
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/research-milestone.md +2 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +5 -3
- package/src/resources/extensions/gsd/provider-payload-policy.ts +140 -0
- package/src/resources/extensions/gsd/pull-request-process.ts +41 -0
- package/src/resources/extensions/gsd/quality-gate-closure.ts +140 -0
- package/src/resources/extensions/gsd/question-transport.ts +138 -0
- package/src/resources/extensions/gsd/roadmap-slices.ts +8 -2
- package/src/resources/extensions/gsd/schemas/parsers.ts +6 -1
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +31 -10
- package/src/resources/extensions/gsd/state.ts +15 -5
- package/src/resources/extensions/gsd/templates/plan.md +7 -0
- package/src/resources/extensions/gsd/templates/project.md +1 -0
- package/src/resources/extensions/gsd/templates/roadmap.md +1 -1
- package/src/resources/extensions/gsd/templates/uat.md +5 -1
- package/src/resources/extensions/gsd/tests/artifact-db-drift-memo.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/ask-user-questions-render.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/auto-dispatch-baseline-harness.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +321 -5
- package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +709 -845
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +38 -10
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/debug-logger.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +34 -3
- package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/execute-summary-save-empty-project.test.ts +64 -1
- package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +1 -5
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +1 -5
- package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer-parse-cache.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/mcp-tool-name.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/milestone-closeout-proof.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/milestone-readiness.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/milestone-validation-evidence.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/milestone-validation-verdict.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/native-merge-regular.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/orchestrator-legacy-parity.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/parse-project-milestone-bridge.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +6 -2
- package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/preferences-diagnostics.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +183 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +75 -2
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/provider-payload-policy.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/pull-request-process.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +94 -0
- package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +25 -1
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +80 -0
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +101 -1
- package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +21 -6
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/tool-availability-audit.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +35 -42
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +147 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +126 -9
- package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/worktree-projection-writers.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +15 -3
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +79 -0
- package/src/resources/extensions/gsd/tool-contract.ts +86 -8
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +16 -33
- package/src/resources/extensions/gsd/tool-surface-snapshot.ts +47 -0
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +19 -160
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +43 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -84
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +183 -21
- package/src/resources/extensions/gsd/uat-policy.ts +19 -10
- package/src/resources/extensions/gsd/uat-run.ts +10 -14
- package/src/resources/extensions/gsd/unit-context-composer.ts +85 -20
- package/src/resources/extensions/gsd/unit-runtime.ts +3 -2
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +2 -1
- package/src/resources/extensions/gsd/user-input-boundary.ts +55 -5
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
- package/src/resources/extensions/gsd/web-app-uat.ts +101 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +22 -110
- package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
- package/src/resources/extensions/gsd/workflow-tool-surface.ts +73 -0
- package/src/resources/extensions/gsd/workspace-git-guard.ts +1 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +7 -16
- package/src/resources/extensions/gsd/worktree-state-projection.ts +55 -7
- package/src/resources/extensions/gsd/worktree-telemetry.ts +16 -0
- package/src/resources/extensions/shared/interview-ui.ts +15 -2
- package/src/resources/shared/claude-runtime-floor.ts +248 -0
- package/dist/web/standalone/.next/server/chunks/678.js +0 -2
- package/dist/web/standalone/.next/static/chunks/2659.feb6499ca863ebfc.js +0 -1
- package/dist/web/standalone/.next/static/chunks/2772.151789db0edea835.js +0 -1
- package/dist/web/standalone/.next/static/chunks/4283.10a065467b5340d8.js +0 -2
- package/dist/web/standalone/.next/static/chunks/5826.960dc4634cc9b0d3.js +0 -1
- package/dist/web/standalone/.next/static/chunks/796.46f811c0fac23aab.js +0 -10
- package/dist/web/standalone/.next/static/chunks/8785.d32f7a61f55c1600.js +0 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +0 -21
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +0 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +0 -213
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +0 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.d.ts +0 -28
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.d.ts.map +0 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.js +0 -249
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.js.map +0 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.d.ts +0 -19
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.d.ts.map +0 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.js +0 -797
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.js.map +0 -1
- package/scripts/ensure-workspace-builds.cjs +0 -129
- /package/dist/web/standalone/.next/static/{tJOKQbQRO-9MiFDO8DIDS → tkLHUSzPA2kMmWz4DmGwI}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{tJOKQbQRO-9MiFDO8DIDS → tkLHUSzPA2kMmWz4DmGwI}/_ssgManifest.js +0 -0
|
@@ -21,6 +21,14 @@ function runGit(args: string[], cwd: string): void {
|
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
function renderOutcomeWidget(widget: unknown): string {
|
|
25
|
+
const component = (widget as any)(
|
|
26
|
+
{ requestRender() {} },
|
|
27
|
+
{ fg: (_color: string, text: string) => text, bold: (text: string) => text },
|
|
28
|
+
);
|
|
29
|
+
return component.render(100).join("\n");
|
|
30
|
+
}
|
|
31
|
+
|
|
24
32
|
test("cleanupAfterLoopExit preserves paused auto badge after provider pause", async () => {
|
|
25
33
|
const base = mkdtempSync(join(tmpdir(), "gsd-paused-cleanup-"));
|
|
26
34
|
const previousCwd = process.cwd();
|
|
@@ -167,13 +175,17 @@ test("cleanupAfterLoopExit preserves completion closeout surface after stopAuto
|
|
|
167
175
|
false,
|
|
168
176
|
"completion cleanup must not replace the closeout surface with a generic outcome card",
|
|
169
177
|
);
|
|
170
|
-
assert.equal(
|
|
178
|
+
assert.equal(
|
|
179
|
+
autoSession.completionStopInProgress,
|
|
180
|
+
true,
|
|
181
|
+
"completion closeout preservation must survive post-loop cleanup until the next agent turn",
|
|
182
|
+
);
|
|
171
183
|
} finally {
|
|
172
184
|
autoSession.reset();
|
|
173
185
|
}
|
|
174
186
|
});
|
|
175
187
|
|
|
176
|
-
test("cleanupAfterLoopExit
|
|
188
|
+
test("cleanupAfterLoopExit preserves completionStopInProgress even when preserveStepSurfaceAfterLoopExit is also set", async () => {
|
|
177
189
|
const statusCalls: unknown[] = [];
|
|
178
190
|
const widgetCalls: unknown[] = [];
|
|
179
191
|
|
|
@@ -196,8 +208,8 @@ test("cleanupAfterLoopExit clears completionStopInProgress even when preserveSte
|
|
|
196
208
|
|
|
197
209
|
assert.equal(
|
|
198
210
|
autoSession.completionStopInProgress,
|
|
199
|
-
|
|
200
|
-
"completionStopInProgress must
|
|
211
|
+
true,
|
|
212
|
+
"completionStopInProgress must survive cleanup even when preserveStepSurfaceAfterLoopExit was also set",
|
|
201
213
|
);
|
|
202
214
|
assert.equal(autoSession.preserveStepSurfaceAfterLoopExit, false);
|
|
203
215
|
} finally {
|
|
@@ -641,6 +653,10 @@ test("stopAuto foreground completion closeout reroots session and preserves the
|
|
|
641
653
|
false,
|
|
642
654
|
"foreground completion stop must not install a replacement roll-up widget over the transcript",
|
|
643
655
|
);
|
|
656
|
+
assert.ok(
|
|
657
|
+
widgetCalls.some(([key, value]) => key === "gsd-progress" && value === undefined),
|
|
658
|
+
"foreground completion stop must clear stale progress controls in the rerooted session",
|
|
659
|
+
);
|
|
644
660
|
assert.ok(
|
|
645
661
|
notifications.every(message => !message.includes("/gsd auto to resume")),
|
|
646
662
|
"completion stop notification must not tell users to resume a finished auto run",
|
|
@@ -649,10 +665,15 @@ test("stopAuto foreground completion closeout reroots session and preserves the
|
|
|
649
665
|
notifications.every(message => !message.includes("Auto-mode stopped") && !message.includes("Session:") && !message.includes("Debug log written")),
|
|
650
666
|
"completion stop must not append generic stop/session/debug notifications after the report",
|
|
651
667
|
);
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
668
|
+
const outcome = widgetCalls.find(([key, value]) => key === "gsd-outcome" && typeof value === "function")?.[1];
|
|
669
|
+
assert.equal(
|
|
670
|
+
typeof outcome,
|
|
671
|
+
"function",
|
|
672
|
+
"foreground completion stop must install a durable closeout outcome in the rerooted session",
|
|
655
673
|
);
|
|
674
|
+
const rendered = renderOutcomeWidget(outcome);
|
|
675
|
+
assert.match(rendered, /Milestone M003 complete/);
|
|
676
|
+
assert.match(rendered, /Review the closeout/);
|
|
656
677
|
|
|
657
678
|
const widgetCallCountBeforePostLoopCleanup = widgetCalls.length;
|
|
658
679
|
await cleanupAfterLoopExit(ctx);
|
|
@@ -822,7 +843,7 @@ test("stopAuto closeout-transcript preservation suppresses generic stop widgets"
|
|
|
822
843
|
}
|
|
823
844
|
});
|
|
824
845
|
|
|
825
|
-
test("stopAuto foreground all-complete closeout
|
|
846
|
+
test("stopAuto foreground all-complete closeout installs a durable terminal outcome", async () => {
|
|
826
847
|
const base = mkdtempSync(join(tmpdir(), "gsd-all-complete-closeout-"));
|
|
827
848
|
const previousCwd = process.cwd();
|
|
828
849
|
const widgetCalls: Array<[string, unknown]> = [];
|
|
@@ -875,8 +896,15 @@ test("stopAuto foreground all-complete closeout preserves the transcript surface
|
|
|
875
896
|
false,
|
|
876
897
|
"foreground all-complete closeout must not replace the visible transcript with a roll-up widget",
|
|
877
898
|
);
|
|
878
|
-
const finalOutcome = widgetCalls.filter(([key]) => key === "gsd-outcome").at(-1);
|
|
879
|
-
assert.equal(
|
|
899
|
+
const finalOutcome = widgetCalls.filter(([key]) => key === "gsd-outcome").at(-1)?.[1];
|
|
900
|
+
assert.equal(
|
|
901
|
+
typeof finalOutcome,
|
|
902
|
+
"function",
|
|
903
|
+
"foreground all-complete closeout must install a durable terminal outcome",
|
|
904
|
+
);
|
|
905
|
+
const rendered = renderOutcomeWidget(finalOutcome);
|
|
906
|
+
assert.match(rendered, /All milestones complete/);
|
|
907
|
+
assert.match(rendered, /start new work/);
|
|
880
908
|
} finally {
|
|
881
909
|
try { closeDatabase(); } catch { /* noop */ }
|
|
882
910
|
autoSession.reset();
|
|
@@ -6,12 +6,15 @@ import assert from "node:assert/strict";
|
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
8
|
autoSession,
|
|
9
|
+
clearAutoToolSurfaceSnapshot,
|
|
9
10
|
clearToolInvocationError,
|
|
10
11
|
getAutoRuntimeSnapshot,
|
|
12
|
+
recordAutoToolSurfaceSnapshot,
|
|
11
13
|
} from "../auto-runtime-state.ts";
|
|
12
14
|
|
|
13
15
|
test("getAutoRuntimeSnapshot includes orchestration phase when available", () => {
|
|
14
16
|
autoSession.reset();
|
|
17
|
+
clearAutoToolSurfaceSnapshot();
|
|
15
18
|
autoSession.active = true;
|
|
16
19
|
autoSession.basePath = "/tmp/project";
|
|
17
20
|
autoSession.orchestration = {
|
|
@@ -33,10 +36,40 @@ test("getAutoRuntimeSnapshot includes orchestration phase when available", () =>
|
|
|
33
36
|
assert.equal(snap.orchestrationPhase, "running");
|
|
34
37
|
assert.equal(snap.orchestrationTransitionCount, 3);
|
|
35
38
|
assert.equal(snap.orchestrationLastTransitionAt, 123);
|
|
39
|
+
assert.equal(snap.toolSurface, null);
|
|
36
40
|
|
|
37
41
|
autoSession.reset();
|
|
38
42
|
});
|
|
39
43
|
|
|
44
|
+
test("getAutoRuntimeSnapshot includes the active typed tool-surface snapshot", () => {
|
|
45
|
+
autoSession.reset();
|
|
46
|
+
clearAutoToolSurfaceSnapshot();
|
|
47
|
+
autoSession.active = true;
|
|
48
|
+
|
|
49
|
+
recordAutoToolSurfaceSnapshot({
|
|
50
|
+
source: "dispatch-scope",
|
|
51
|
+
unitType: "run-uat",
|
|
52
|
+
modelFacingToolNames: ["read", "read", "gsd_uat_exec"],
|
|
53
|
+
registeredToolNames: ["read", "browser_navigate"],
|
|
54
|
+
scopedToolNames: ["read", "browser_navigate"],
|
|
55
|
+
presentedToolNames: ["gsd_uat_exec"],
|
|
56
|
+
capturedAt: 123,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const snap = getAutoRuntimeSnapshot();
|
|
60
|
+
|
|
61
|
+
assert.equal(snap.toolSurface?.source, "dispatch-scope");
|
|
62
|
+
assert.equal(snap.toolSurface?.unitType, "run-uat");
|
|
63
|
+
assert.deepEqual(snap.toolSurface?.modelFacingToolNames, ["read", "gsd_uat_exec"]);
|
|
64
|
+
assert.deepEqual(snap.toolSurface?.registeredToolNames, ["read", "browser_navigate"]);
|
|
65
|
+
assert.deepEqual(snap.toolSurface?.scopedToolNames, ["read", "browser_navigate"]);
|
|
66
|
+
assert.deepEqual(snap.toolSurface?.presentedToolNames, ["gsd_uat_exec"]);
|
|
67
|
+
assert.equal(snap.toolSurface?.capturedAt, 123);
|
|
68
|
+
|
|
69
|
+
autoSession.reset();
|
|
70
|
+
clearAutoToolSurfaceSnapshot();
|
|
71
|
+
});
|
|
72
|
+
|
|
40
73
|
test("clearToolInvocationError clears stale tool error state for active auto sessions", () => {
|
|
41
74
|
autoSession.reset();
|
|
42
75
|
autoSession.active = true;
|
|
@@ -56,4 +89,5 @@ test("getAutoRuntimeSnapshot omits orchestration phase when seam not wired", ()
|
|
|
56
89
|
assert.equal(snap.orchestrationPhase, undefined);
|
|
57
90
|
assert.equal(snap.orchestrationTransitionCount, undefined);
|
|
58
91
|
assert.equal(snap.orchestrationLastTransitionAt, undefined);
|
|
92
|
+
assert.equal(snap.toolSurface, null);
|
|
59
93
|
});
|
|
@@ -17,6 +17,7 @@ import { tmpdir } from "node:os";
|
|
|
17
17
|
import { randomUUID } from "node:crypto";
|
|
18
18
|
|
|
19
19
|
import { resolveCanonicalMilestoneRoot } from "../worktree-manager.ts";
|
|
20
|
+
import { resolveCloseoutArtifactProjection } from "../artifact-projection.ts";
|
|
20
21
|
|
|
21
22
|
function makeTmpBase(): string {
|
|
22
23
|
const base = join(tmpdir(), `gsd-canon-test-${randomUUID()}`);
|
|
@@ -106,3 +107,22 @@ test("only returns the worktree for the requested milestone, not siblings", () =
|
|
|
106
107
|
cleanup(base);
|
|
107
108
|
}
|
|
108
109
|
});
|
|
110
|
+
|
|
111
|
+
test("resolveCloseoutArtifactProjection names project and canonical artifact roots", () => {
|
|
112
|
+
const base = makeTmpBase();
|
|
113
|
+
try {
|
|
114
|
+
const wtPath = makeLiveWorktree(base, "M001");
|
|
115
|
+
const projection = resolveCloseoutArtifactProjection({
|
|
116
|
+
milestoneId: "M001",
|
|
117
|
+
basePath: wtPath,
|
|
118
|
+
originalBasePath: base,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
assert.equal(projection.projectRoot, base);
|
|
122
|
+
assert.equal(projection.canonicalMilestoneRoot, wtPath);
|
|
123
|
+
assert.equal(projection.summaryArtifactBasePath, wtPath);
|
|
124
|
+
assert.equal(projection.gateEvidenceBasePath, wtPath);
|
|
125
|
+
} finally {
|
|
126
|
+
cleanup(base);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
@@ -696,3 +696,25 @@ test("ensureCodebaseMapFresh: does not rewrite expired metadata when fingerprint
|
|
|
696
696
|
cleanup(base);
|
|
697
697
|
}
|
|
698
698
|
});
|
|
699
|
+
|
|
700
|
+
test("ensureCodebaseMapFresh: detects file changes within the TTL window", () => {
|
|
701
|
+
const base = makeTmpRepo();
|
|
702
|
+
try {
|
|
703
|
+
addFile(base, "src/main.ts");
|
|
704
|
+
// Generate initial map with a long TTL so the cache is still active.
|
|
705
|
+
const initial = ensureCodebaseMapFresh(base, undefined, { ttlMs: 60_000 });
|
|
706
|
+
assert.equal(initial.status, "generated");
|
|
707
|
+
|
|
708
|
+
// Add a new tracked file while the TTL is still active.
|
|
709
|
+
addFile(base, "src/new.ts");
|
|
710
|
+
|
|
711
|
+
// Must detect the change even though the TTL has not expired.
|
|
712
|
+
const refreshed = ensureCodebaseMapFresh(base, undefined, { ttlMs: 60_000 });
|
|
713
|
+
assert.equal(refreshed.status, "updated");
|
|
714
|
+
assert.equal(refreshed.reason, "files-changed");
|
|
715
|
+
const written = readCodebaseMap(base);
|
|
716
|
+
assert.ok(written?.includes("`src/new.ts`"));
|
|
717
|
+
} finally {
|
|
718
|
+
cleanup(base);
|
|
719
|
+
}
|
|
720
|
+
});
|
|
@@ -64,3 +64,14 @@ test("getWorkspaceGitBlockMessageForBase allows doctor on product conflicts", as
|
|
|
64
64
|
cleanup(base);
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
|
+
|
|
68
|
+
test("getWorkspaceGitBlockMessageForBase allows forensics on product conflicts", async () => {
|
|
69
|
+
const base = makeTempRepo("gsd-dispatch-ws-git-forensics-");
|
|
70
|
+
try {
|
|
71
|
+
seedProductConflict(base);
|
|
72
|
+
const blocked = await getWorkspaceGitBlockMessageForBase(base, "forensics");
|
|
73
|
+
assert.equal(blocked, null);
|
|
74
|
+
} finally {
|
|
75
|
+
cleanup(base);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import test from "node:test";
|
|
12
12
|
import assert from "node:assert/strict";
|
|
13
|
-
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
13
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
14
14
|
import { join } from "node:path";
|
|
15
15
|
import { tmpdir } from "node:os";
|
|
16
16
|
import { randomUUID } from "node:crypto";
|
|
@@ -486,3 +486,40 @@ test("state.ts needs-remediation blocker messages reference /gsd verdict", async
|
|
|
486
486
|
`expected at least 2 references to /gsd verdict in state.ts blockers, found ${occurrences.length}`,
|
|
487
487
|
);
|
|
488
488
|
});
|
|
489
|
+
|
|
490
|
+
// ─── WAL checkpoint regression (#563) ───────────────────────────────────
|
|
491
|
+
|
|
492
|
+
test("handleVerdict pass checkpoints WAL so subsequent processes see the updated verdict (#563)", async () => {
|
|
493
|
+
// Regression: before the fix, executeValidateMilestone wrote the assessment
|
|
494
|
+
// only into the WAL file. The next /gsd auto invocation (a new process)
|
|
495
|
+
// opened gsd.db directly and saw stale pre-verdict data because the WAL
|
|
496
|
+
// had not been flushed. The fix adds checkpointDatabase() after a
|
|
497
|
+
// successful verdict so the WAL is truncated and gsd.db is self-contained.
|
|
498
|
+
const base = makeBase();
|
|
499
|
+
try {
|
|
500
|
+
openTestDb(base);
|
|
501
|
+
seedMilestone("M001", "Checkpoint Test Milestone");
|
|
502
|
+
seedSlice("M001", "S01", "complete");
|
|
503
|
+
writeValidation(base, "M001", "needs-attention");
|
|
504
|
+
|
|
505
|
+
const { ctx } = makeMockCtx();
|
|
506
|
+
await handleVerdict("pass --milestone M001", ctx, base);
|
|
507
|
+
|
|
508
|
+
// After handleVerdict succeeds, PRAGMA wal_checkpoint(TRUNCATE) must have
|
|
509
|
+
// run. The WAL file is truncated to zero bytes — a new process reading
|
|
510
|
+
// gsd.db directly sees the updated verdict without needing the WAL.
|
|
511
|
+
const walPath = join(base, ".gsd", "gsd.db-wal");
|
|
512
|
+
if (existsSync(walPath)) {
|
|
513
|
+
const { size } = statSync(walPath);
|
|
514
|
+
assert.equal(
|
|
515
|
+
size,
|
|
516
|
+
0,
|
|
517
|
+
"WAL must be zero bytes after handleVerdict pass — checkpointDatabase() was not called (#563)",
|
|
518
|
+
);
|
|
519
|
+
}
|
|
520
|
+
} finally {
|
|
521
|
+
closeDatabase();
|
|
522
|
+
invalidateStateCache();
|
|
523
|
+
cleanup(base);
|
|
524
|
+
}
|
|
525
|
+
});
|
|
@@ -115,6 +115,21 @@ test('debugCount increments counters', () => {
|
|
|
115
115
|
assert.strictEqual(summary.dispatches, 5);
|
|
116
116
|
});
|
|
117
117
|
|
|
118
|
+
test('debugCount tracks gitInvocations and writeDebugSummary reports it', () => {
|
|
119
|
+
const tmp = createTempGsdDir();
|
|
120
|
+
enableDebug(tmp);
|
|
121
|
+
|
|
122
|
+
debugCount('gitInvocations');
|
|
123
|
+
debugCount('gitInvocations', 13);
|
|
124
|
+
|
|
125
|
+
const logPath = writeDebugSummary()!;
|
|
126
|
+
const lines = readLogLines(logPath);
|
|
127
|
+
|
|
128
|
+
const summary = lines.find(l => l.event === 'debug-summary') as any;
|
|
129
|
+
assert.ok(summary, 'should have debug-summary event');
|
|
130
|
+
assert.strictEqual(summary.gitInvocations, 14);
|
|
131
|
+
});
|
|
132
|
+
|
|
118
133
|
test('debugPeak tracks max values', () => {
|
|
119
134
|
const tmp = createTempGsdDir();
|
|
120
135
|
enableDebug(tmp);
|
|
@@ -14,7 +14,15 @@ import { execFileSync } from "node:child_process";
|
|
|
14
14
|
|
|
15
15
|
import { DISPATCH_RULES, resolveDispatch, type DispatchContext } from "../auto-dispatch.ts";
|
|
16
16
|
import { AutoSession } from "../auto/session.ts";
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
closeDatabase,
|
|
19
|
+
getPendingGates,
|
|
20
|
+
insertAssessment,
|
|
21
|
+
insertGateRow,
|
|
22
|
+
insertMilestone,
|
|
23
|
+
insertSlice,
|
|
24
|
+
openDatabase,
|
|
25
|
+
} from "../gsd-db.ts";
|
|
18
26
|
|
|
19
27
|
function makeBase(): string {
|
|
20
28
|
const base = mkdtempSync(join(tmpdir(), "gsd-complete-dispatch-"));
|
|
@@ -243,7 +251,7 @@ describe("complete phase dispatch guard (#5683)", () => {
|
|
|
243
251
|
assert.equal(result?.reason, "All milestones complete.");
|
|
244
252
|
});
|
|
245
253
|
|
|
246
|
-
test("
|
|
254
|
+
test("closes stale pending gates from milestone validation before terminal stop", async () => {
|
|
247
255
|
base = makeBase();
|
|
248
256
|
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
249
257
|
insertMilestone({ id: "M001", title: "Milestone One", status: "complete" });
|
|
@@ -268,10 +276,33 @@ describe("complete phase dispatch guard (#5683)", () => {
|
|
|
268
276
|
|
|
269
277
|
const result = await rule.match(ctx);
|
|
270
278
|
|
|
279
|
+
assert.equal(result?.action, "stop");
|
|
280
|
+
assert.equal(result?.reason, "All milestones complete.");
|
|
281
|
+
assert.deepEqual(getPendingGates("M001", "S01"), []);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
test("blocks terminal stop when pending gates have no closeout evidence", async () => {
|
|
285
|
+
base = makeBase();
|
|
286
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
287
|
+
insertMilestone({ id: "M001", title: "Milestone One", status: "complete" });
|
|
288
|
+
insertSlice({ milestoneId: "M001", id: "S01", title: "Done", status: "complete" });
|
|
289
|
+
insertGateRow({
|
|
290
|
+
milestoneId: "M001",
|
|
291
|
+
sliceId: "S01",
|
|
292
|
+
gateId: "Q3",
|
|
293
|
+
scope: "slice",
|
|
294
|
+
status: "pending",
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
const ctx = buildDispatchCtx(base);
|
|
298
|
+
ctx.state.phase = "complete";
|
|
299
|
+
|
|
300
|
+
const result = await rule.match(ctx);
|
|
301
|
+
|
|
271
302
|
assert.equal(result?.action, "stop");
|
|
272
303
|
assert.equal(result?.level, "warning");
|
|
273
304
|
assert.match(result?.reason ?? "", /closeout-consistency-blocked/);
|
|
274
|
-
assert.match(result?.reason ?? "", /
|
|
305
|
+
assert.match(result?.reason ?? "", /latest milestone validation is "absent"/);
|
|
275
306
|
});
|
|
276
307
|
});
|
|
277
308
|
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Regression coverage for run-uat browser tool availability checks.
|
|
3
|
+
|
|
4
|
+
import test from "node:test";
|
|
5
|
+
import assert from "node:assert/strict";
|
|
6
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { tmpdir } from "node:os";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
|
|
10
|
+
import { DISPATCH_RULES, type DispatchContext } from "../auto-dispatch.ts";
|
|
11
|
+
import type { GSDState } from "../types.ts";
|
|
12
|
+
|
|
13
|
+
type DispatchRuleEntry = (typeof DISPATCH_RULES)[number];
|
|
14
|
+
|
|
15
|
+
function runUatRule(): DispatchRuleEntry {
|
|
16
|
+
const rule = DISPATCH_RULES.find((entry) => entry.name === "run-uat (post-completion)");
|
|
17
|
+
assert.ok(rule, "run-uat dispatch rule must exist");
|
|
18
|
+
return rule;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function makeState(): GSDState {
|
|
22
|
+
return {
|
|
23
|
+
activeMilestone: { id: "M001", title: "Browser UAT" },
|
|
24
|
+
activeSlice: { id: "S02", title: "Next Slice" },
|
|
25
|
+
activeTask: null,
|
|
26
|
+
phase: "verifying",
|
|
27
|
+
recentDecisions: [],
|
|
28
|
+
blockers: [],
|
|
29
|
+
nextAction: "",
|
|
30
|
+
registry: [],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function scaffoldRunUatProject(basePath: string): void {
|
|
35
|
+
const milestoneDir = join(basePath, ".gsd", "milestones", "M001");
|
|
36
|
+
const sliceDir = join(milestoneDir, "slices", "S01");
|
|
37
|
+
mkdirSync(sliceDir, { recursive: true });
|
|
38
|
+
|
|
39
|
+
writeFileSync(join(milestoneDir, "M001-ROADMAP.md"), [
|
|
40
|
+
"# M001: Browser UAT",
|
|
41
|
+
"",
|
|
42
|
+
"## Slices",
|
|
43
|
+
"",
|
|
44
|
+
"- [x] **S01: Completed browser slice** `risk:low` `depends:[]`",
|
|
45
|
+
"- [ ] **S02: Next slice** `risk:low` `depends:[S01]`",
|
|
46
|
+
"",
|
|
47
|
+
].join("\n"), "utf-8");
|
|
48
|
+
|
|
49
|
+
writeFileSync(join(sliceDir, "S01-SUMMARY.md"), "# S01 Summary\n\nDone.\n", "utf-8");
|
|
50
|
+
writeFileSync(join(sliceDir, "S01-UAT.md"), [
|
|
51
|
+
"# S01 UAT",
|
|
52
|
+
"",
|
|
53
|
+
"## UAT Type",
|
|
54
|
+
"- UAT mode: human-experience",
|
|
55
|
+
"",
|
|
56
|
+
"Open the app in a browser and verify the completed user flow.",
|
|
57
|
+
"",
|
|
58
|
+
].join("\n"), "utf-8");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function makeContext(basePath: string, overrides: Partial<DispatchContext> = {}): DispatchContext {
|
|
62
|
+
return {
|
|
63
|
+
basePath,
|
|
64
|
+
mid: "M001",
|
|
65
|
+
midTitle: "Browser UAT",
|
|
66
|
+
state: makeState(),
|
|
67
|
+
prefs: undefined,
|
|
68
|
+
activeTools: ["read", "gsd_uat_exec", "gsd_uat_result_save"],
|
|
69
|
+
...overrides,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
test("run-uat browser preflight uses registered tools when the active surface is scoped", async (t) => {
|
|
74
|
+
const basePath = mkdtempSync(join(tmpdir(), "gsd-run-uat-browser-tools-"));
|
|
75
|
+
t.after(() => rmSync(basePath, { recursive: true, force: true }));
|
|
76
|
+
scaffoldRunUatProject(basePath);
|
|
77
|
+
|
|
78
|
+
const blocked = await runUatRule().match(makeContext(basePath));
|
|
79
|
+
assert.equal(blocked?.action, "stop");
|
|
80
|
+
assert.match(blocked?.action === "stop" ? blocked.reason : "", /run-uat tool surface has none/);
|
|
81
|
+
|
|
82
|
+
const dispatched = await runUatRule().match(makeContext(basePath, {
|
|
83
|
+
registeredTools: ["browser_navigate"],
|
|
84
|
+
}));
|
|
85
|
+
assert.equal(dispatched?.action, "dispatch");
|
|
86
|
+
assert.equal(dispatched?.action === "dispatch" ? dispatched.unitType : undefined, "run-uat");
|
|
87
|
+
assert.equal(dispatched?.action === "dispatch" ? dispatched.unitId : undefined, "M001/S01");
|
|
88
|
+
});
|
|
@@ -26,6 +26,24 @@ test("filterDoctorIssues keeps project and environment issues in scoped reports"
|
|
|
26
26
|
);
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
+
test("filterDoctorIssues keeps invalid_preferences issues regardless of preferences file scope", () => {
|
|
30
|
+
// Both global and project preference diagnostics should survive scope filtering.
|
|
31
|
+
// doctor.ts uses unitId: "project" for all invalid_preferences issues so they
|
|
32
|
+
// pass through the scope filter the same way other project-level issues do.
|
|
33
|
+
const issues = [
|
|
34
|
+
{ severity: "error", code: "invalid_preferences", scope: "project", unitId: "project", message: "global PREFERENCES.md parse error", fixable: false },
|
|
35
|
+
{ severity: "error", code: "invalid_preferences", scope: "project", unitId: "project", message: "project PREFERENCES.md parse error", fixable: false },
|
|
36
|
+
{ severity: "error", code: "invalid_preferences", scope: "project", unitId: "global", message: "stale unitId — should be filtered out", fixable: false },
|
|
37
|
+
] as const;
|
|
38
|
+
|
|
39
|
+
const filtered = filterDoctorIssues([...issues], { scope: "M016", includeWarnings: true });
|
|
40
|
+
assert.deepEqual(
|
|
41
|
+
filtered.map((issue) => issue.message),
|
|
42
|
+
["global PREFERENCES.md parse error", "project PREFERENCES.md parse error"],
|
|
43
|
+
"invalid_preferences issues with unitId: project survive scope filtering; unitId: global is dropped",
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
|
|
29
47
|
test("checkEngineHealth reports db_unavailable when gsd.db exists but the DB is closed", async (t) => {
|
|
30
48
|
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-db-unavailable-"));
|
|
31
49
|
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
@@ -6,7 +6,8 @@ import { join } from "node:path";
|
|
|
6
6
|
import { tmpdir } from "node:os";
|
|
7
7
|
import { randomUUID } from "node:crypto";
|
|
8
8
|
|
|
9
|
-
import { openDatabase, closeDatabase, getAllMilestones } from "../gsd-db.ts";
|
|
9
|
+
import { openDatabase, closeDatabase, getAllMilestones, getArtifact } from "../gsd-db.ts";
|
|
10
|
+
import { parseProject } from "../schemas/parsers.ts";
|
|
10
11
|
import { markApprovalGateVerified, clearDiscussionFlowState } from "../bootstrap/write-gate.ts";
|
|
11
12
|
import { executeSummarySave } from "../tools/workflow-tool-executors.ts";
|
|
12
13
|
|
|
@@ -107,3 +108,65 @@ test("executeSummarySave registers milestones when PROJECT.md uses canonical em-
|
|
|
107
108
|
assert.deepEqual(result.details.registeredMilestones, ["M001", "M002"]);
|
|
108
109
|
assert.equal(getAllMilestones().length, 2);
|
|
109
110
|
});
|
|
111
|
+
|
|
112
|
+
test("executeSummarySave self-heals the Milestone Sequence when DB already has milestones but content parses zero", async (t) => {
|
|
113
|
+
const base = setupBase(t);
|
|
114
|
+
|
|
115
|
+
// 1) First save registers M001 as complete; DB now holds the milestone with
|
|
116
|
+
// authoritative status.
|
|
117
|
+
const canonical = [
|
|
118
|
+
"# Project",
|
|
119
|
+
"",
|
|
120
|
+
"## Milestone Sequence",
|
|
121
|
+
"",
|
|
122
|
+
"<!-- Check off milestones as they complete. -->",
|
|
123
|
+
"",
|
|
124
|
+
"- [x] M001: Foo — bar",
|
|
125
|
+
"",
|
|
126
|
+
].join("\n");
|
|
127
|
+
await inProjectDir(base, () => executeSummarySave({ artifact_type: "PROJECT", content: canonical }, base));
|
|
128
|
+
assert.equal(getAllMilestones().length, 1);
|
|
129
|
+
|
|
130
|
+
// 2) A completion re-save reflows the sequence with an en-dash separator the
|
|
131
|
+
// canonical parser rejects → zero parseable lines, but the DB is intact.
|
|
132
|
+
// (A trailing non-bullet section prevents MILESTONE_LINE_RE from bridging
|
|
133
|
+
// onto a later bullet.) The checkbox here is deliberately WRONG (unchecked)
|
|
134
|
+
// to prove the rebuild takes status from the DB, not the malformed content.
|
|
135
|
+
const malformed = [
|
|
136
|
+
"# Project",
|
|
137
|
+
"",
|
|
138
|
+
"## Milestone Sequence",
|
|
139
|
+
"",
|
|
140
|
+
"<!-- Check off milestones as they complete. -->",
|
|
141
|
+
"",
|
|
142
|
+
"- [ ] M001: Foo – shipped bar", // en-dash U+2013, not accepted by MILESTONE_LINE_RE
|
|
143
|
+
"",
|
|
144
|
+
"## Notes",
|
|
145
|
+
"",
|
|
146
|
+
"Trailing prose with no list bullets.",
|
|
147
|
+
"",
|
|
148
|
+
].join("\n");
|
|
149
|
+
|
|
150
|
+
const result = await inProjectDir(base, () => executeSummarySave({ artifact_type: "PROJECT", content: malformed }, base));
|
|
151
|
+
|
|
152
|
+
// Non-fatal: the save succeeds and reports the self-heal.
|
|
153
|
+
assert.notEqual(result.isError, true);
|
|
154
|
+
assert.equal(result.details.milestoneSequenceSelfHealed, true);
|
|
155
|
+
assert.deepEqual(result.details.registeredMilestones, ["M001"]);
|
|
156
|
+
assert.equal(getAllMilestones().length, 1);
|
|
157
|
+
|
|
158
|
+
// The persisted PROJECT.md now parses canonically and preserves status + prose.
|
|
159
|
+
const persisted = getArtifact("PROJECT.md");
|
|
160
|
+
assert.ok(persisted);
|
|
161
|
+
const parsed = parseProject(persisted!.full_content);
|
|
162
|
+
assert.equal(parsed.milestones.length, 1);
|
|
163
|
+
const m001 = parsed.milestones.find(m => m.id === "M001");
|
|
164
|
+
assert.ok(m001);
|
|
165
|
+
// Status comes from the DB (M001 complete), not the unchecked box in the
|
|
166
|
+
// malformed content.
|
|
167
|
+
assert.equal(m001!.done, true);
|
|
168
|
+
assert.equal(m001!.title, "Foo");
|
|
169
|
+
assert.match(m001!.oneLiner, /shipped bar/);
|
|
170
|
+
// The HTML comment hint survives the rebuild.
|
|
171
|
+
assert.match(persisted!.full_content, /Check off milestones as they complete/);
|
|
172
|
+
});
|
|
@@ -38,6 +38,7 @@ test("execute-task prompt renders compact execution and completion gates", async
|
|
|
38
38
|
planPath: ".gsd/milestones/M001/slices/S01/S01-PLAN.md",
|
|
39
39
|
taskPlanPath: ".gsd/milestones/M001/slices/S01/tasks/T01-PLAN.md",
|
|
40
40
|
priorTaskLines: "- None",
|
|
41
|
+
onDemandContext: "",
|
|
41
42
|
skillActivation: "Load relevant skills.",
|
|
42
43
|
inlinedTemplates: "### Output Template: Task Summary\nSource: `templates/task-summary.md`",
|
|
43
44
|
templatesDir: join(fixtureRoot, "templates"),
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import { describe, test, beforeEach, afterEach } from "node:test";
|
|
5
5
|
import assert from "node:assert/strict";
|
|
6
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
6
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { join } from "node:path";
|
|
8
8
|
import { tmpdir } from "node:os";
|
|
9
9
|
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
insertSlice,
|
|
19
19
|
} from "../gsd-db.ts";
|
|
20
20
|
import type { GateVerdict } from "../types.ts";
|
|
21
|
+
import { closeQualityGatesFromEvidence } from "../quality-gate-closure.ts";
|
|
21
22
|
|
|
22
23
|
describe("gate-state canonicalization (#4950)", () => {
|
|
23
24
|
let tmpDir: string;
|
|
@@ -99,4 +100,50 @@ describe("gate-state canonicalization (#4950)", () => {
|
|
|
99
100
|
assert.notEqual(g.verdict, "", `gate ${g.gate_id} verdict must not be empty string`);
|
|
100
101
|
}
|
|
101
102
|
});
|
|
103
|
+
|
|
104
|
+
test("closeQualityGatesFromEvidence repairs pending gate from durable section", () => {
|
|
105
|
+
insertGateRow({ milestoneId: "M001", sliceId: "S01", gateId: "Q3", scope: "slice" });
|
|
106
|
+
mkdirSync(join(tmpDir, ".gsd", "milestones", "M001", "slices", "S01"), { recursive: true });
|
|
107
|
+
writeFileSync(
|
|
108
|
+
join(tmpDir, ".gsd", "milestones", "M001", "slices", "S01", "S01-PLAN.md"),
|
|
109
|
+
[
|
|
110
|
+
"# S01",
|
|
111
|
+
"",
|
|
112
|
+
"## Threat Surface",
|
|
113
|
+
"",
|
|
114
|
+
"- Credential stuffing is rate-limited.",
|
|
115
|
+
].join("\n"),
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
const result = closeQualityGatesFromEvidence("M001", { artifactBasePath: tmpDir });
|
|
119
|
+
|
|
120
|
+
assert.deepEqual(result.unresolved, []);
|
|
121
|
+
assert.deepEqual(result.repaired, [{ gateId: "Q3", sliceId: "S01", verdict: "pass" }]);
|
|
122
|
+
assert.equal(getPendingGates("M001", "S01").length, 0);
|
|
123
|
+
assert.equal(getGateResults("M001", "S01")[0].verdict, "pass");
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test("closeQualityGatesFromEvidence omits stale pending gate after validation pass", () => {
|
|
127
|
+
insertGateRow({ milestoneId: "M001", sliceId: "S01", gateId: "Q4", scope: "slice" });
|
|
128
|
+
|
|
129
|
+
const result = closeQualityGatesFromEvidence("M001", {
|
|
130
|
+
artifactBasePath: tmpDir,
|
|
131
|
+
milestoneValidationPassed: true,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
assert.deepEqual(result.unresolved, []);
|
|
135
|
+
assert.deepEqual(result.repaired, [{ gateId: "Q4", sliceId: "S01", verdict: "omitted" }]);
|
|
136
|
+
assert.equal(getGateResults("M001", "S01")[0].verdict, "omitted");
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test("closeQualityGatesFromEvidence leaves pending gate unresolved without evidence", () => {
|
|
140
|
+
insertGateRow({ milestoneId: "M001", sliceId: "S01", gateId: "Q3", scope: "slice" });
|
|
141
|
+
|
|
142
|
+
const result = closeQualityGatesFromEvidence("M001", { artifactBasePath: tmpDir });
|
|
143
|
+
|
|
144
|
+
assert.deepEqual(result.repaired, []);
|
|
145
|
+
assert.equal(result.unresolved.length, 1);
|
|
146
|
+
assert.equal(result.unresolved[0].gate_id, "Q3");
|
|
147
|
+
assert.equal(getPendingGates("M001", "S01").length, 1);
|
|
148
|
+
});
|
|
102
149
|
});
|