@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
|
@@ -13,7 +13,7 @@ function isNonEmptyString(value) {
|
|
|
13
13
|
function mergeBlockedTools(current, canonical) {
|
|
14
14
|
const merged = new Map();
|
|
15
15
|
for (const entry of [...(current ?? []), ...canonical]) {
|
|
16
|
-
merged.set(canonicalWorkflowToolName(parseMcpToolName(entry.name)?.
|
|
16
|
+
merged.set(canonicalWorkflowToolName(parseMcpToolName(entry.name)?.toolName ?? entry.name), entry);
|
|
17
17
|
}
|
|
18
18
|
return [...merged.values()];
|
|
19
19
|
}
|
|
@@ -204,20 +204,15 @@ function quoteToolNames(toolNames) {
|
|
|
204
204
|
return toolNames.map((toolName) => `"${toolName}"`).join(", ");
|
|
205
205
|
}
|
|
206
206
|
function validateCanonicalPresentation(params) {
|
|
207
|
-
const aliasHints = {
|
|
208
|
-
gsd_save_summary: "gsd_summary_save",
|
|
209
|
-
gsd_complete_task: "gsd_task_complete",
|
|
210
|
-
gsd_complete_slice: "gsd_slice_complete",
|
|
211
|
-
gsd_milestone_complete: "gsd_complete_milestone",
|
|
212
|
-
};
|
|
213
207
|
const errors = [];
|
|
214
208
|
for (const toolName of params.presentation.presentedTools) {
|
|
215
|
-
const baseName = parseMcpToolName(toolName)?.
|
|
216
|
-
const canonical =
|
|
217
|
-
if (canonical)
|
|
209
|
+
const baseName = parseMcpToolName(toolName)?.toolName ?? toolName;
|
|
210
|
+
const canonical = canonicalWorkflowToolName(baseName);
|
|
211
|
+
if (canonical !== baseName) {
|
|
218
212
|
errors.push(`presentation tool "${toolName}" uses an alias; use canonical "${canonical}"`);
|
|
213
|
+
}
|
|
219
214
|
}
|
|
220
|
-
const presentedCanonical = new Set(params.presentation.presentedTools.map((toolName) => canonicalWorkflowToolName(parseMcpToolName(toolName)?.
|
|
215
|
+
const presentedCanonical = new Set(params.presentation.presentedTools.map((toolName) => canonicalWorkflowToolName(parseMcpToolName(toolName)?.toolName ?? toolName)));
|
|
221
216
|
const missingRequiredTools = RUN_UAT_WORKFLOW_TOOL_NAMES.filter((requiredTool) => !presentedCanonical.has(requiredTool));
|
|
222
217
|
if (missingRequiredTools.length === 1) {
|
|
223
218
|
errors.push(`presentation is missing required UAT tool "${missingRequiredTools[0]}"`);
|
|
@@ -227,10 +222,10 @@ function validateCanonicalPresentation(params) {
|
|
|
227
222
|
}
|
|
228
223
|
const forbiddenCanonical = new Set(RUN_UAT_FORBIDDEN_TOOL_NAMES
|
|
229
224
|
.filter((toolName) => !toolName.includes("*"))
|
|
230
|
-
.map((toolName) => canonicalWorkflowToolName(parseMcpToolName(toolName)?.
|
|
225
|
+
.map((toolName) => canonicalWorkflowToolName(parseMcpToolName(toolName)?.toolName ?? toolName)));
|
|
231
226
|
const forbiddenPresentedTools = [];
|
|
232
227
|
for (const toolName of params.presentation.presentedTools) {
|
|
233
|
-
const canonical = canonicalWorkflowToolName(parseMcpToolName(toolName)?.
|
|
228
|
+
const canonical = canonicalWorkflowToolName(parseMcpToolName(toolName)?.toolName ?? toolName);
|
|
234
229
|
if (toolName === "mcp__gsd-workflow__*" || forbiddenCanonical.has(canonical)) {
|
|
235
230
|
forbiddenPresentedTools.push(toolName);
|
|
236
231
|
}
|
|
@@ -241,7 +236,7 @@ function validateCanonicalPresentation(params) {
|
|
|
241
236
|
else if (forbiddenPresentedTools.length > 1) {
|
|
242
237
|
errors.push(`presentation includes forbidden run-uat tools ${quoteToolNames(forbiddenPresentedTools)}`);
|
|
243
238
|
}
|
|
244
|
-
const blockedCanonical = new Set(params.presentation.blockedTools.map((entry) => canonicalWorkflowToolName(parseMcpToolName(entry.name)?.
|
|
239
|
+
const blockedCanonical = new Set(params.presentation.blockedTools.map((entry) => canonicalWorkflowToolName(parseMcpToolName(entry.name)?.toolName ?? entry.name)));
|
|
245
240
|
const missingBlockedTools = ["gsd_exec", "gsd_summary_save", "gsd_save_gate_result"].filter((blockedTool) => !blockedCanonical.has(blockedTool));
|
|
246
241
|
if (missingBlockedTools.length === 1) {
|
|
247
242
|
errors.push(`presentation must record "${missingBlockedTools[0]}" as blocked during run-uat`);
|
|
@@ -135,37 +135,56 @@ export async function composeUnitContext(unitType, opts) {
|
|
|
135
135
|
const manifest = resolveManifest(unitType);
|
|
136
136
|
if (!manifest)
|
|
137
137
|
return { prepend: "", inline: "" };
|
|
138
|
-
|
|
138
|
+
const composed = await composeDeclaredUnitContext({
|
|
139
|
+
unitType,
|
|
140
|
+
artifacts: {
|
|
141
|
+
inline: manifest.artifacts.inline,
|
|
142
|
+
excerpt: manifest.artifacts.excerpt,
|
|
143
|
+
onDemand: manifest.artifacts.onDemand,
|
|
144
|
+
computed: manifest.artifacts.computed ?? [],
|
|
145
|
+
prepend: manifest.prepend ?? [],
|
|
146
|
+
},
|
|
147
|
+
}, opts);
|
|
148
|
+
return {
|
|
149
|
+
prepend: composed.prepend,
|
|
150
|
+
inline: composed.inline,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export async function composeContractedUnitContext(contract, opts) {
|
|
154
|
+
return composeDeclaredUnitContext(contract, opts);
|
|
155
|
+
}
|
|
156
|
+
async function composeDeclaredUnitContext(contract, opts) {
|
|
157
|
+
// Single-source `unitType`: contract/manifest selection comes from the
|
|
139
158
|
// function arg, but computed builders read it from `base.unitType`.
|
|
140
|
-
//
|
|
141
|
-
// but a different one in opts.base), the composer would silently
|
|
142
|
-
// mix one unit's manifest with another unit's computed context.
|
|
143
|
-
// Normalize here so the composer dispatches a consistent identity
|
|
144
|
-
// through to every builder.
|
|
159
|
+
// Normalize here so every builder sees the same Unit identity.
|
|
145
160
|
const normalizedOpts = {
|
|
146
161
|
...opts,
|
|
147
|
-
base: { ...opts.base, unitType },
|
|
162
|
+
base: { ...opts.base, unitType: contract.unitType },
|
|
148
163
|
};
|
|
149
|
-
const prependBlocks = await
|
|
164
|
+
const prependBlocks = await runComputedBlocks(contract.artifacts.prepend, normalizedOpts, "prepend");
|
|
150
165
|
const inlineBlocks = [];
|
|
151
|
-
for (const key of
|
|
166
|
+
for (const key of contract.artifacts.inline) {
|
|
152
167
|
if (!normalizedOpts.resolveArtifact)
|
|
153
168
|
break;
|
|
154
169
|
const body = await normalizedOpts.resolveArtifact(key);
|
|
155
|
-
if (body && body.length > 0)
|
|
156
|
-
inlineBlocks.push(body);
|
|
170
|
+
if (body && body.length > 0) {
|
|
171
|
+
inlineBlocks.push({ key, mode: "inline", body });
|
|
172
|
+
}
|
|
157
173
|
}
|
|
158
|
-
for (const key of
|
|
174
|
+
for (const key of contract.artifacts.excerpt) {
|
|
159
175
|
if (!normalizedOpts.resolveExcerpt)
|
|
160
176
|
break;
|
|
161
177
|
const body = await normalizedOpts.resolveExcerpt(key);
|
|
162
|
-
if (body && body.length > 0)
|
|
163
|
-
inlineBlocks.push(body);
|
|
178
|
+
if (body && body.length > 0) {
|
|
179
|
+
inlineBlocks.push({ key, mode: "excerpt", body });
|
|
180
|
+
}
|
|
164
181
|
}
|
|
165
|
-
inlineBlocks.push(...await
|
|
182
|
+
inlineBlocks.push(...await runComputedBlocks(contract.artifacts.computed, normalizedOpts, "computed"));
|
|
166
183
|
return {
|
|
167
|
-
prepend: prependBlocks.join(SECTION_SEPARATOR),
|
|
168
|
-
inline: inlineBlocks.join(SECTION_SEPARATOR),
|
|
184
|
+
prepend: prependBlocks.map((block) => block.body).join(SECTION_SEPARATOR),
|
|
185
|
+
inline: inlineBlocks.map((block) => block.body).join(SECTION_SEPARATOR),
|
|
186
|
+
blocks: [...prependBlocks, ...inlineBlocks],
|
|
187
|
+
onDemand: contract.artifacts.onDemand,
|
|
169
188
|
};
|
|
170
189
|
}
|
|
171
190
|
/**
|
|
@@ -173,7 +192,7 @@ export async function composeUnitContext(unitType, opts) {
|
|
|
173
192
|
* Missing registry entries (manifest declares the id but caller didn't
|
|
174
193
|
* register it) are skipped silently — see composeUnitContext rationale.
|
|
175
194
|
*/
|
|
176
|
-
async function
|
|
195
|
+
async function runComputedBlocks(ids, opts, mode) {
|
|
177
196
|
if (ids.length === 0 || !opts.computed)
|
|
178
197
|
return [];
|
|
179
198
|
const registry = opts.computed;
|
|
@@ -183,8 +202,9 @@ async function runComputed(ids, opts) {
|
|
|
183
202
|
if (!entry)
|
|
184
203
|
continue;
|
|
185
204
|
const body = await entry.build(entry.inputs, opts.base);
|
|
186
|
-
if (body && body.length > 0)
|
|
187
|
-
out.push(body);
|
|
205
|
+
if (body && body.length > 0) {
|
|
206
|
+
out.push({ key: id, mode, body });
|
|
207
|
+
}
|
|
188
208
|
}
|
|
189
209
|
return out;
|
|
190
210
|
}
|
|
@@ -4,7 +4,8 @@ import { atomicWriteSync } from "./atomic-write.js";
|
|
|
4
4
|
import { gsdRoot, relSliceFile, relTaskFile, resolveSliceFile, resolveTaskFile, } from "./paths.js";
|
|
5
5
|
import { loadFile, parseTaskPlanMustHaves, countMustHavesMentionedInSummary } from "./files.js";
|
|
6
6
|
import { parseUnitId } from "./unit-id.js";
|
|
7
|
-
import { getTask, isDbAvailable
|
|
7
|
+
import { getTask, isDbAvailable } from "./gsd-db.js";
|
|
8
|
+
import { refreshWorkflowDatabaseFromDisk } from "./db-workspace.js";
|
|
8
9
|
import { isClosedStatus } from "./status-guards.js";
|
|
9
10
|
// Per-record advisory lock — prevents read-modify-write races between
|
|
10
11
|
// concurrent writers updating disjoint fields of the same runtime record.
|
|
@@ -169,7 +170,7 @@ export async function inspectExecuteTaskDurability(basePath, unitId) {
|
|
|
169
170
|
const nextActionAdvanced = !new RegExp(`Execute ${tid}\\b`).test(stateContent);
|
|
170
171
|
let dbComplete = false;
|
|
171
172
|
if (isDbAvailable()) {
|
|
172
|
-
|
|
173
|
+
refreshWorkflowDatabaseFromDisk();
|
|
173
174
|
const task = getTask(mid, sid, tid);
|
|
174
175
|
dbComplete = !!task && isClosedStatus(task.status);
|
|
175
176
|
}
|
|
@@ -60,6 +60,7 @@ export const UNIT_TOOL_CONTRACTS = {
|
|
|
60
60
|
"gsd_milestone_generate_id",
|
|
61
61
|
],
|
|
62
62
|
requiredWorkflowTools: [
|
|
63
|
+
"ask_user_questions",
|
|
63
64
|
"gsd_summary_save",
|
|
64
65
|
"gsd_requirement_save",
|
|
65
66
|
"gsd_requirement_update",
|
|
@@ -69,7 +70,7 @@ export const UNIT_TOOL_CONTRACTS = {
|
|
|
69
70
|
},
|
|
70
71
|
"discuss-slice": {
|
|
71
72
|
allowedGsdTools: ["gsd_summary_save", "gsd_decision_save"],
|
|
72
|
-
requiredWorkflowTools: ["gsd_summary_save"],
|
|
73
|
+
requiredWorkflowTools: ["ask_user_questions", "gsd_summary_save"],
|
|
73
74
|
},
|
|
74
75
|
"validate-milestone": {
|
|
75
76
|
allowedGsdTools: ["gsd_milestone_status", "gsd_validate_milestone", "gsd_reassess_roadmap", "subagent"],
|
|
@@ -10,6 +10,26 @@ const APPROVAL_QUESTION_RE = /\b(?:confirm|confirmation|approve|approval|approve
|
|
|
10
10
|
const APPROVAL_RIGHT_QUESTION_RE = /\b(?:does|do|is|are|was|were|did)\b[^\n?]{0,120}\bright\b/i;
|
|
11
11
|
const APPROVAL_CHANGE_QUESTION_RE = /\b(?:anything\s+else|anything|something)\s+to\s+(?:adjust|add|remove|reclassify)\b/i;
|
|
12
12
|
const RESEARCH_DECISION_QUESTION_RE = /\b(?:research|skip)\b/i;
|
|
13
|
+
function extractVisibleTextFromMessage(msg) {
|
|
14
|
+
if (!msg || typeof msg !== "object")
|
|
15
|
+
return "";
|
|
16
|
+
const content = msg.content;
|
|
17
|
+
if (typeof content === "string")
|
|
18
|
+
return content;
|
|
19
|
+
if (!Array.isArray(content))
|
|
20
|
+
return "";
|
|
21
|
+
const parts = [];
|
|
22
|
+
for (const block of content) {
|
|
23
|
+
if (!block || typeof block !== "object")
|
|
24
|
+
continue;
|
|
25
|
+
const typed = block;
|
|
26
|
+
if (typed.type === "text" && typeof typed.text === "string") {
|
|
27
|
+
parts.push(typed.text);
|
|
28
|
+
}
|
|
29
|
+
// thinking blocks intentionally excluded — they are internal reasoning, not user-visible
|
|
30
|
+
}
|
|
31
|
+
return parts.join("\n");
|
|
32
|
+
}
|
|
13
33
|
function extractTextFromMessage(msg) {
|
|
14
34
|
if (!msg || typeof msg !== "object")
|
|
15
35
|
return "";
|
|
@@ -26,6 +46,9 @@ function extractTextFromMessage(msg) {
|
|
|
26
46
|
if (typed.type === "text" && typeof typed.text === "string") {
|
|
27
47
|
parts.push(typed.text);
|
|
28
48
|
}
|
|
49
|
+
if (typed.type === "thinking" && typeof typed.thinking === "string") {
|
|
50
|
+
parts.push(typed.thinking);
|
|
51
|
+
}
|
|
29
52
|
}
|
|
30
53
|
return parts.join("\n");
|
|
31
54
|
}
|
|
@@ -44,6 +67,21 @@ export function lastAssistantText(messages) {
|
|
|
44
67
|
}
|
|
45
68
|
return "";
|
|
46
69
|
}
|
|
70
|
+
function lastAssistantVisibleText(messages) {
|
|
71
|
+
if (!Array.isArray(messages))
|
|
72
|
+
return "";
|
|
73
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
74
|
+
const msg = messages[i];
|
|
75
|
+
if (!msg || typeof msg !== "object")
|
|
76
|
+
continue;
|
|
77
|
+
if (msg.role !== "assistant")
|
|
78
|
+
continue;
|
|
79
|
+
const text = extractVisibleTextFromMessage(msg).trim();
|
|
80
|
+
if (text)
|
|
81
|
+
return text;
|
|
82
|
+
}
|
|
83
|
+
return "";
|
|
84
|
+
}
|
|
47
85
|
function anyMessageMatches(messages, pattern) {
|
|
48
86
|
if (!Array.isArray(messages))
|
|
49
87
|
return false;
|
|
@@ -52,7 +90,7 @@ function anyMessageMatches(messages, pattern) {
|
|
|
52
90
|
return false;
|
|
53
91
|
if (msg.role === "user")
|
|
54
92
|
return false;
|
|
55
|
-
return pattern.test(
|
|
93
|
+
return pattern.test(extractVisibleTextFromMessage(msg));
|
|
56
94
|
});
|
|
57
95
|
}
|
|
58
96
|
function hasApprovalQuestion(text) {
|
|
@@ -117,7 +155,7 @@ export function isAwaitingUserInput(messages) {
|
|
|
117
155
|
return true;
|
|
118
156
|
if (anyMessageMatches(messages, REMOTE_QUESTION_FAILURE_RE))
|
|
119
157
|
return true;
|
|
120
|
-
const text =
|
|
158
|
+
const text = lastAssistantVisibleText(messages);
|
|
121
159
|
if (!text)
|
|
122
160
|
return false;
|
|
123
161
|
if (APPROVAL_WAIT_RE.test(text))
|
|
@@ -132,13 +170,36 @@ export function isAwaitingApprovalBoundary(messages) {
|
|
|
132
170
|
return true;
|
|
133
171
|
if (anyMessageMatches(messages, REMOTE_QUESTION_FAILURE_RE))
|
|
134
172
|
return true;
|
|
135
|
-
const text =
|
|
173
|
+
const text = lastAssistantVisibleText(messages);
|
|
136
174
|
if (!text)
|
|
137
175
|
return false;
|
|
138
176
|
if (APPROVAL_WAIT_RE.test(text))
|
|
139
177
|
return true;
|
|
140
178
|
return hasApprovalQuestion(text);
|
|
141
179
|
}
|
|
180
|
+
/** True when an assistant message already has an in-flight ask_user_questions tool call. */
|
|
181
|
+
export function messageHasPendingAskUserQuestionsTool(message) {
|
|
182
|
+
if (!message || typeof message !== "object")
|
|
183
|
+
return false;
|
|
184
|
+
const content = message.content;
|
|
185
|
+
if (!Array.isArray(content))
|
|
186
|
+
return false;
|
|
187
|
+
return content.some((block) => {
|
|
188
|
+
if (!block || typeof block !== "object")
|
|
189
|
+
return false;
|
|
190
|
+
// Claude Code marks completion by attaching externalResult, not by setting state.
|
|
191
|
+
// Streaming blocks often carry no state; serverToolUse is the claude-code-cli MCP path.
|
|
192
|
+
const tool = block;
|
|
193
|
+
if (tool.type !== "toolCall" && tool.type !== "serverToolUse")
|
|
194
|
+
return false;
|
|
195
|
+
const name = String(tool.name ?? "").toLowerCase();
|
|
196
|
+
if (!name.includes("ask_user_questions"))
|
|
197
|
+
return false;
|
|
198
|
+
if (tool.externalResult !== undefined)
|
|
199
|
+
return false;
|
|
200
|
+
return tool.state !== "completed" && tool.state !== "done";
|
|
201
|
+
});
|
|
202
|
+
}
|
|
142
203
|
export function shouldPauseForUserApprovalQuestion(unitType, messages) {
|
|
143
204
|
if (!unitType || !USER_APPROVAL_UNIT_TYPES.has(unitType))
|
|
144
205
|
return false;
|
|
@@ -146,7 +207,7 @@ export function shouldPauseForUserApprovalQuestion(unitType, messages) {
|
|
|
146
207
|
return true;
|
|
147
208
|
if (anyMessageMatches(messages, REMOTE_QUESTION_FAILURE_RE))
|
|
148
209
|
return true;
|
|
149
|
-
const text =
|
|
210
|
+
const text = lastAssistantVisibleText(messages);
|
|
150
211
|
if (!text)
|
|
151
212
|
return false;
|
|
152
213
|
if (APPROVAL_WAIT_RE.test(text))
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
import { getAutoWorktreePath, isInAutoWorktree } from "./auto-worktree.js";
|
|
5
5
|
import { ensureDbOpen } from "./bootstrap/dynamic-tools.js";
|
|
6
|
+
import { refreshWorkflowDatabaseFromDisk } from "./db-workspace.js";
|
|
6
7
|
import { getIsolationMode } from "./preferences.js";
|
|
7
8
|
import { deriveState } from "./state.js";
|
|
8
9
|
import { detectWorktreeName } from "./worktree.js";
|
|
@@ -72,6 +73,7 @@ export function formatValidationBlockedMessage(state, attemptedCommand = "") {
|
|
|
72
73
|
}
|
|
73
74
|
export async function getValidationBlockMessageForBase(base, attemptedCommand = "") {
|
|
74
75
|
await ensureDbOpen(base);
|
|
76
|
+
refreshWorkflowDatabaseFromDisk();
|
|
75
77
|
let state = await deriveState(base);
|
|
76
78
|
if (state.activeMilestone &&
|
|
77
79
|
getIsolationMode(base) === "worktree" &&
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Web-app detection and Playwright/UAT guidance for planning and slice closeout.
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { detectWebApp } from "../browser-tools/web-app-detect.js";
|
|
6
|
+
export { detectWebApp };
|
|
7
|
+
function readPackageJson(projectRoot) {
|
|
8
|
+
const packageJsonPath = resolve(projectRoot, "package.json");
|
|
9
|
+
if (!existsSync(packageJsonPath))
|
|
10
|
+
return null;
|
|
11
|
+
try {
|
|
12
|
+
const parsed = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
13
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function hasPlaywrightTestDependency(projectRoot) {
|
|
20
|
+
const pkg = readPackageJson(projectRoot);
|
|
21
|
+
if (!pkg)
|
|
22
|
+
return false;
|
|
23
|
+
const names = [
|
|
24
|
+
...Object.keys(pkg.dependencies ?? {}),
|
|
25
|
+
...Object.keys(pkg.devDependencies ?? {}),
|
|
26
|
+
];
|
|
27
|
+
return names.some((name) => name === "playwright" || name === "@playwright/test");
|
|
28
|
+
}
|
|
29
|
+
export function findPlaywrightTestScript(projectRoot) {
|
|
30
|
+
const pkg = readPackageJson(projectRoot);
|
|
31
|
+
if (!pkg?.scripts)
|
|
32
|
+
return null;
|
|
33
|
+
for (const [name, value] of Object.entries(pkg.scripts)) {
|
|
34
|
+
if (typeof value !== "string")
|
|
35
|
+
continue;
|
|
36
|
+
if (/\bplaywright\s+test\b/.test(value)) {
|
|
37
|
+
return `npm run ${name}`;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Markdown block injected into plan/complete-slice prompts when the project
|
|
44
|
+
* looks browser-facing. Returns null for CLI/library-only repos.
|
|
45
|
+
*/
|
|
46
|
+
export function buildWebAppUatGuidanceBlock(projectRoot) {
|
|
47
|
+
if (!detectWebApp(projectRoot))
|
|
48
|
+
return null;
|
|
49
|
+
const playwrightScript = findPlaywrightTestScript(projectRoot);
|
|
50
|
+
const hasPlaywright = hasPlaywrightTestDependency(projectRoot) || playwrightScript !== null;
|
|
51
|
+
const lines = [
|
|
52
|
+
"### Web App UAT (detected)",
|
|
53
|
+
"",
|
|
54
|
+
"This project looks browser-facing. GSD exposes Playwright-backed `browser_*` tools by default for run-uat.",
|
|
55
|
+
"",
|
|
56
|
+
"**UAT modes (pick one per slice — do not use `artifact-driven` for browser steps):**",
|
|
57
|
+
"- `browser-executable` — navigate to `http://localhost:…`, click, screenshot, assert via `browser_*` tools during run-uat",
|
|
58
|
+
"- `runtime-executable` — run an automated browser test command via `gsd_uat_exec` (for example `npx playwright test`)",
|
|
59
|
+
"- `mixed` / `live-runtime` — combine runtime startup checks with interactive browser verification",
|
|
60
|
+
"",
|
|
61
|
+
"**Planning / closeout rules:**",
|
|
62
|
+
"- Preconditions must name the dev-server command and URL (for example `npm run dev` → `http://localhost:3000`)",
|
|
63
|
+
"- Slice Verification and UAT test cases must not say \"open in browser\" under `artifact-driven` — complete-slice rejects that",
|
|
64
|
+
"- Milestone `Verification Classes` → UAT row must describe browser-observable acceptance, not \"manual spot check\" alone",
|
|
65
|
+
];
|
|
66
|
+
if (hasPlaywright) {
|
|
67
|
+
lines.push("", "**Playwright:** dependency detected.");
|
|
68
|
+
if (playwrightScript) {
|
|
69
|
+
lines.push(`- Prefer slice verification and runtime-executable UAT referencing \`${playwrightScript}\` or a focused \`npx playwright test <spec>\` command`);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
lines.push("- Prefer runtime-executable UAT with `npx playwright test` (or a focused spec path) when UI behavior is covered by specs");
|
|
73
|
+
}
|
|
74
|
+
lines.push("- Name concrete spec paths in slice Verification (for example `e2e/smoke.spec.ts`)");
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
lines.push("", "**Playwright scaffolding (first UI slice):** no `playwright` / `@playwright/test` dependency yet.", "- Add a planning task that installs Playwright, adds `playwright.config.ts`, and creates a minimal smoke spec (for example `e2e/smoke.spec.ts`)", "- Task `verify` should run `npx playwright test` (or the focused spec) with a safe, simple command", "- Until specs exist, use `browser-executable` UAT with localhost preconditions and interactive `browser_*` checks at slice closeout");
|
|
78
|
+
}
|
|
79
|
+
return lines.join("\n");
|
|
80
|
+
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
2
|
import { existsSync, realpathSync } from "node:fs";
|
|
3
|
-
import { dirname, resolve, sep } from "node:path";
|
|
3
|
+
import { basename, dirname, resolve, sep } from "node:path";
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
5
|
import { getRequiredWorkflowToolsForUnit } from "./unit-tool-contracts.js";
|
|
6
|
+
import { mcpToolMatchesBaseName } from "./mcp-tool-name.js";
|
|
7
|
+
import { supportsStructuredQuestions, usesWorkflowMcpTransport, } from "./question-transport.js";
|
|
8
|
+
import { WORKFLOW_TOOL_SURFACE_NAMES, isWorkflowToolSurfaceName, } from "./workflow-tool-surface.js";
|
|
9
|
+
export { supportsStructuredQuestions, usesWorkflowMcpTransport };
|
|
6
10
|
/** Session cwd may be a milestone worktree; MCP config and server discovery use the project root. */
|
|
7
11
|
export function resolveWorkflowMcpProjectRoot(sessionCwd) {
|
|
8
12
|
let resolved;
|
|
@@ -19,72 +23,9 @@ export function resolveWorkflowMcpProjectRoot(sessionCwd) {
|
|
|
19
23
|
}
|
|
20
24
|
return resolved;
|
|
21
25
|
}
|
|
22
|
-
const MCP_WORKFLOW_TOOL_SURFACE = new Set([
|
|
23
|
-
"gsd_cancel",
|
|
24
|
-
"gsd_captures",
|
|
25
|
-
"ask_user_questions",
|
|
26
|
-
"gsd_capture_thought",
|
|
27
|
-
"gsd_doctor",
|
|
28
|
-
"gsd_execute",
|
|
29
|
-
"gsd_memory_query",
|
|
30
|
-
"gsd_memory_graph",
|
|
31
|
-
"gsd_decision_save",
|
|
32
|
-
"gsd_exec",
|
|
33
|
-
"gsd_exec_search",
|
|
34
|
-
"gsd_graph",
|
|
35
|
-
"gsd_history",
|
|
36
|
-
"gsd_knowledge",
|
|
37
|
-
"gsd_progress",
|
|
38
|
-
"gsd_query",
|
|
39
|
-
"gsd_resume",
|
|
40
|
-
"gsd_result",
|
|
41
|
-
"gsd_resolve_blocker",
|
|
42
|
-
"gsd_roadmap",
|
|
43
|
-
"gsd_status",
|
|
44
|
-
"gsd_complete_milestone",
|
|
45
|
-
"gsd_complete_task",
|
|
46
|
-
"gsd_complete_slice",
|
|
47
|
-
"gsd_generate_milestone_id",
|
|
48
|
-
"gsd_journal_query",
|
|
49
|
-
"gsd_milestone_complete",
|
|
50
|
-
"gsd_milestone_generate_id",
|
|
51
|
-
"gsd_milestone_reopen",
|
|
52
|
-
"gsd_checkpoint_db",
|
|
53
|
-
"gsd_milestone_plan",
|
|
54
|
-
"gsd_milestone_status",
|
|
55
|
-
"gsd_milestone_validate",
|
|
56
|
-
"gsd_plan_task",
|
|
57
|
-
"gsd_plan_milestone",
|
|
58
|
-
"gsd_plan_slice",
|
|
59
|
-
"gsd_replan_slice",
|
|
60
|
-
"gsd_reassess_roadmap",
|
|
61
|
-
"gsd_reopen_milestone",
|
|
62
|
-
"gsd_reopen_slice",
|
|
63
|
-
"gsd_reopen_task",
|
|
64
|
-
"gsd_requirement_save",
|
|
65
|
-
"gsd_requirement_update",
|
|
66
|
-
"gsd_roadmap_reassess",
|
|
67
|
-
"gsd_save_decision",
|
|
68
|
-
"gsd_save_gate_result",
|
|
69
|
-
"gsd_save_requirement",
|
|
70
|
-
"gsd_save_summary",
|
|
71
|
-
"gsd_skip_slice",
|
|
72
|
-
"gsd_slice_plan",
|
|
73
|
-
"gsd_slice_replan",
|
|
74
|
-
"gsd_slice_complete",
|
|
75
|
-
"gsd_slice_reopen",
|
|
76
|
-
"gsd_summary_save",
|
|
77
|
-
"gsd_task_plan",
|
|
78
|
-
"gsd_task_complete",
|
|
79
|
-
"gsd_task_reopen",
|
|
80
|
-
"gsd_update_requirement",
|
|
81
|
-
"gsd_uat_exec",
|
|
82
|
-
"gsd_uat_result_save",
|
|
83
|
-
"gsd_validate_milestone",
|
|
84
|
-
]);
|
|
85
26
|
/** Workflow MCP tools are validated by transport compatibility, not pi tool-compat profiles. */
|
|
86
27
|
export function isWorkflowMcpSurfaceTool(toolName) {
|
|
87
|
-
return
|
|
28
|
+
return isWorkflowToolSurfaceName(toolName);
|
|
88
29
|
}
|
|
89
30
|
function parseLookupOutput(output) {
|
|
90
31
|
return output
|
|
@@ -239,8 +180,12 @@ function getBundledWorkflowWriteGateModulePath() {
|
|
|
239
180
|
}
|
|
240
181
|
function getResolveTsHookPath() {
|
|
241
182
|
const repoRoot = findGsdPiRepoRoot(dirname(fileURLToPath(import.meta.url)));
|
|
183
|
+
const sourceRepoRoot = repoRoot && basename(repoRoot) === "dist-test" ? dirname(repoRoot) : repoRoot;
|
|
242
184
|
return firstExistingPath([
|
|
243
|
-
...(
|
|
185
|
+
...(sourceRepoRoot
|
|
186
|
+
? [resolve(sourceRepoRoot, "src", "resources", "extensions", "gsd", "tests", "resolve-ts.mjs")]
|
|
187
|
+
: []),
|
|
188
|
+
...(repoRoot && repoRoot !== sourceRepoRoot
|
|
244
189
|
? [resolve(repoRoot, "src", "resources", "extensions", "gsd", "tests", "resolve-ts.mjs")]
|
|
245
190
|
: []),
|
|
246
191
|
resolve(fileURLToPath(new URL("./tests/resolve-ts.mjs", import.meta.url))),
|
|
@@ -355,45 +300,13 @@ export function getRequiredWorkflowToolsForGuidedUnit(unitType) {
|
|
|
355
300
|
export function getRequiredWorkflowToolsForAutoUnit(unitType) {
|
|
356
301
|
return getRequiredWorkflowToolsForUnit(unitType);
|
|
357
302
|
}
|
|
358
|
-
export function usesWorkflowMcpTransport(authMode, baseUrl) {
|
|
359
|
-
return authMode === "externalCli" && typeof baseUrl === "string" && baseUrl.startsWith("local://");
|
|
360
|
-
}
|
|
361
|
-
function hasAskUserQuestionsTool(activeTools) {
|
|
362
|
-
return activeTools.some((toolName) => {
|
|
363
|
-
if (toolName === "ask_user_questions")
|
|
364
|
-
return true;
|
|
365
|
-
if (!toolName.startsWith("mcp__"))
|
|
366
|
-
return false;
|
|
367
|
-
const toolSeparator = toolName.indexOf("__", "mcp__".length);
|
|
368
|
-
return toolSeparator >= 0 && toolName.slice(toolSeparator + 2) === "ask_user_questions";
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
303
|
function hasRequiredTool(requiredTool, activeTools) {
|
|
372
304
|
return activeTools.some((toolName) => {
|
|
373
305
|
if (toolName === requiredTool)
|
|
374
306
|
return true;
|
|
375
|
-
|
|
376
|
-
return false;
|
|
377
|
-
const toolSeparator = toolName.indexOf("__", "mcp__".length);
|
|
378
|
-
return toolSeparator >= 0 && toolName.slice(toolSeparator + 2) === requiredTool;
|
|
307
|
+
return mcpToolMatchesBaseName(toolName, requiredTool);
|
|
379
308
|
});
|
|
380
309
|
}
|
|
381
|
-
function workflowMcpStructuredQuestionsOptIn(env = process.env) {
|
|
382
|
-
const value = env.GSD_WORKFLOW_MCP_STRUCTURED_QUESTIONS;
|
|
383
|
-
return value === "1" || value === "true";
|
|
384
|
-
}
|
|
385
|
-
export function supportsStructuredQuestions(activeTools, options = {}) {
|
|
386
|
-
if (!hasAskUserQuestionsTool(activeTools))
|
|
387
|
-
return false;
|
|
388
|
-
if (usesWorkflowMcpTransport(options.authMode, options.baseUrl)) {
|
|
389
|
-
// Claude Code local workflow-MCP exposes ask_user_questions, but form
|
|
390
|
-
// elicitation can return an immediate cancel outside GSD's chat turn. Keep
|
|
391
|
-
// checkpoints in plain chat unless a caller deliberately opts into testing
|
|
392
|
-
// that transport.
|
|
393
|
-
return workflowMcpStructuredQuestionsOptIn(options.env);
|
|
394
|
-
}
|
|
395
|
-
return true;
|
|
396
|
-
}
|
|
397
310
|
export function getWorkflowTransportSupportError(provider, requiredTools, options = {}) {
|
|
398
311
|
if (!provider || requiredTools.length === 0)
|
|
399
312
|
return null;
|
|
@@ -410,12 +323,12 @@ export function getWorkflowTransportSupportError(provider, requiredTools, option
|
|
|
410
323
|
}
|
|
411
324
|
const uniqueRequired = [...new Set(requiredTools)];
|
|
412
325
|
const missing = (options.activeTools && options.activeTools.length > 0)
|
|
413
|
-
? uniqueRequired.filter((tool) => !hasRequiredTool(tool, options.activeTools))
|
|
414
|
-
: uniqueRequired.filter((tool) => !
|
|
326
|
+
? uniqueRequired.filter((tool) => !isWorkflowToolSurfaceName(tool) && !hasRequiredTool(tool, options.activeTools))
|
|
327
|
+
: uniqueRequired.filter((tool) => !isWorkflowToolSurfaceName(tool));
|
|
415
328
|
if (missing.length === 0)
|
|
416
329
|
return null;
|
|
417
330
|
if (options.activeTools && options.activeTools.length > 0) {
|
|
418
331
|
return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: this unit requires ${missing.join(", ")}, but the active runtime toolset currently exposes only ${options.activeTools.slice().sort().join(", ")}.`;
|
|
419
332
|
}
|
|
420
|
-
return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: this unit requires ${missing.join(", ")}, but the workflow MCP transport currently exposes only ${
|
|
333
|
+
return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: this unit requires ${missing.join(", ")}, but the workflow MCP transport currently exposes only ${[...WORKFLOW_TOOL_SURFACE_NAMES].sort().join(", ")}.`;
|
|
421
334
|
}
|
|
@@ -2,7 +2,8 @@ import { join } from "node:path";
|
|
|
2
2
|
import { mkdirSync, existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
3
3
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
4
4
|
import { readEvents, findForkPoint, getSessionId } from "./workflow-events.js";
|
|
5
|
-
import { transaction, updateTaskStatus, updateSliceStatus, updateMilestoneStatus, getSliceTasks, insertMilestone, getMilestoneSlices, insertVerificationEvidence, upsertDecision,
|
|
5
|
+
import { transaction, updateTaskStatus, updateSliceStatus, updateMilestoneStatus, getSliceTasks, insertMilestone, getMilestoneSlices, insertVerificationEvidence, upsertDecision, setTaskBlockerDiscovered, insertOrIgnoreSlice, insertOrIgnoreTask, } from "./gsd-db.js";
|
|
6
|
+
import { openWorkflowDatabasePath } from "./db-workspace.js";
|
|
6
7
|
import { isClosedStatus } from "./status-guards.js";
|
|
7
8
|
import { invalidateStateCache } from "./state.js";
|
|
8
9
|
import { clearPathCache, resolveGsdPathContract } from "./paths.js";
|
|
@@ -415,7 +416,7 @@ function _reconcileWorktreeLogsInner(mainBasePath, worktreeBasePath) {
|
|
|
415
416
|
mkdirSync(join(mainBasePath, ".gsd"), { recursive: true });
|
|
416
417
|
atomicWriteSync(join(mainBasePath, ".gsd", "event-log.jsonl"), logContent);
|
|
417
418
|
// Step 8: Replay into DB (wrapped in a transaction by replayEvents)
|
|
418
|
-
|
|
419
|
+
openWorkflowDatabasePath(resolveGsdPathContract(mainBasePath).projectDb);
|
|
419
420
|
replayEvents(merged);
|
|
420
421
|
// Step 9: Write manifest
|
|
421
422
|
try {
|
|
@@ -548,7 +549,7 @@ pick) {
|
|
|
548
549
|
const targetBaseEvents = pick === "main" ? wtBaseEvents : mainBaseEvents;
|
|
549
550
|
writeEventLog(targetBasePath, targetBaseEvents.concat(rewrittenTargetEvents));
|
|
550
551
|
// Replay resolved events through the DB (updates DB state)
|
|
551
|
-
|
|
552
|
+
openWorkflowDatabasePath(resolveGsdPathContract(basePath).projectDb);
|
|
552
553
|
replayEvents(eventsToReplay);
|
|
553
554
|
invalidateStateCache();
|
|
554
555
|
clearPathCache();
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Adapts shared workflow tool contracts into the extension runtime surface.
|
|
3
|
+
import { CANONICAL_WORKFLOW_TOOL_NAMES as CONTRACT_CANONICAL_WORKFLOW_TOOL_NAMES, WORKFLOW_TOOL_ALIAS_NAMES as CONTRACT_WORKFLOW_TOOL_ALIAS_NAMES, WORKFLOW_TOOL_CONTRACTS as CONTRACT_WORKFLOW_TOOL_CONTRACTS, WORKFLOW_TOOL_NAMES as CONTRACT_WORKFLOW_TOOL_NAMES, } from "@opengsd/contracts";
|
|
4
|
+
import { stripMcpToolPrefix } from "./mcp-tool-name.js";
|
|
5
|
+
export const WORKFLOW_TOOL_CONTRACTS = CONTRACT_WORKFLOW_TOOL_CONTRACTS;
|
|
6
|
+
export const CANONICAL_WORKFLOW_TOOL_NAMES = CONTRACT_CANONICAL_WORKFLOW_TOOL_NAMES;
|
|
7
|
+
export const WORKFLOW_TOOL_ALIAS_NAMES = CONTRACT_WORKFLOW_TOOL_ALIAS_NAMES;
|
|
8
|
+
export const DB_WORKFLOW_TOOL_NAMES = CONTRACT_WORKFLOW_TOOL_NAMES;
|
|
9
|
+
export const WORKFLOW_TOOL_ALIAS_PAIRS = WORKFLOW_TOOL_CONTRACTS.flatMap((tool) => tool.aliases.map((alias) => ({ canonical: tool.canonicalName, alias })));
|
|
10
|
+
export const WORKFLOW_TOOL_ALIAS_TO_CANONICAL = Object.fromEntries(WORKFLOW_TOOL_ALIAS_PAIRS.map(({ alias, canonical }) => [alias, canonical]));
|
|
11
|
+
const WORKFLOW_MCP_ADAPTER_TOOL_NAMES = [
|
|
12
|
+
"gsd_cancel",
|
|
13
|
+
"gsd_captures",
|
|
14
|
+
"ask_user_questions",
|
|
15
|
+
"gsd_doctor",
|
|
16
|
+
"gsd_execute",
|
|
17
|
+
"gsd_graph",
|
|
18
|
+
"gsd_history",
|
|
19
|
+
"gsd_knowledge",
|
|
20
|
+
"gsd_progress",
|
|
21
|
+
"gsd_query",
|
|
22
|
+
"gsd_result",
|
|
23
|
+
"gsd_resolve_blocker",
|
|
24
|
+
"gsd_roadmap",
|
|
25
|
+
"gsd_status",
|
|
26
|
+
];
|
|
27
|
+
export const WORKFLOW_TOOL_SURFACE_NAMES = [
|
|
28
|
+
...WORKFLOW_MCP_ADAPTER_TOOL_NAMES,
|
|
29
|
+
...DB_WORKFLOW_TOOL_NAMES,
|
|
30
|
+
];
|
|
31
|
+
const WORKFLOW_TOOL_SURFACE_NAME_SET = new Set(WORKFLOW_TOOL_SURFACE_NAMES);
|
|
32
|
+
export { stripMcpToolPrefix } from "./mcp-tool-name.js";
|
|
33
|
+
export function canonicalWorkflowSurfaceToolName(toolName) {
|
|
34
|
+
const baseName = stripMcpToolPrefix(toolName);
|
|
35
|
+
return WORKFLOW_TOOL_ALIAS_TO_CANONICAL[baseName] ?? baseName;
|
|
36
|
+
}
|
|
37
|
+
export function isWorkflowSurfaceAliasTool(toolName) {
|
|
38
|
+
const baseName = stripMcpToolPrefix(toolName);
|
|
39
|
+
return WORKFLOW_TOOL_ALIAS_TO_CANONICAL[baseName] !== undefined;
|
|
40
|
+
}
|
|
41
|
+
export function isWorkflowToolSurfaceName(toolName) {
|
|
42
|
+
return WORKFLOW_TOOL_SURFACE_NAME_SET.has(stripMcpToolPrefix(toolName));
|
|
43
|
+
}
|
|
44
|
+
export function aliasesForWorkflowTool(canonicalName) {
|
|
45
|
+
return WORKFLOW_TOOL_CONTRACTS.find((tool) => tool.canonicalName === canonicalName)?.aliases ?? [];
|
|
46
|
+
}
|
|
@@ -12,6 +12,8 @@ export function isWorkspaceGitAllowedCommand(trimmed) {
|
|
|
12
12
|
const [name, subcommand] = command.split(/\s+/, 2);
|
|
13
13
|
if (name === "doctor")
|
|
14
14
|
return true;
|
|
15
|
+
if (name === "forensics")
|
|
16
|
+
return true;
|
|
15
17
|
if (name === "closeout" || command.startsWith("closeout"))
|
|
16
18
|
return true;
|
|
17
19
|
if (name === "dispatch") {
|