@opengsd/gsd-pi 1.2.0-dev.84c56d87 → 1.2.0-dev.9ad8ae33
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/headless-events.js +7 -5
- package/dist/mcp-server.js +2 -1
- package/dist/resource-loader.d.ts +10 -5
- package/dist/resource-loader.js +121 -6
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +5 -4
- package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
- package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
- package/dist/resources/extensions/async-jobs/index.js +65 -0
- package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
- package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
- package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
- package/dist/resources/extensions/bg-shell/overlay.js +9 -6
- package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
- package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
- package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
- package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
- package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
- package/dist/resources/extensions/gsd/auto/loop.js +4 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +89 -54
- package/dist/resources/extensions/gsd/auto/phases.js +49 -6
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
- package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
- package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
- package/dist/resources/extensions/gsd/auto-post-unit.js +30 -12
- package/dist/resources/extensions/gsd/auto-prompts.js +78 -19
- package/dist/resources/extensions/gsd/auto-start.js +35 -15
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +5 -4
- package/dist/resources/extensions/gsd/auto-verification.js +23 -30
- package/dist/resources/extensions/gsd/auto-worktree.js +14 -1
- package/dist/resources/extensions/gsd/auto.js +37 -1
- package/dist/resources/extensions/gsd/blocked-models.js +28 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +26 -6
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +23 -6
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +145 -50
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +302 -80
- package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
- package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
- package/dist/resources/extensions/gsd/commands/context.js +16 -2
- package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
- package/dist/resources/extensions/gsd/consent-question.js +353 -0
- package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
- package/dist/resources/extensions/gsd/constants.js +0 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +8 -3
- package/dist/resources/extensions/gsd/db/queries.js +26 -0
- package/dist/resources/extensions/gsd/db-writer.js +8 -17
- package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
- package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
- package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
- package/dist/resources/extensions/gsd/files.js +33 -19
- package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
- package/dist/resources/extensions/gsd/gsd-db.js +2 -1
- package/dist/resources/extensions/gsd/guidance.js +60 -0
- package/dist/resources/extensions/gsd/guided-flow.js +6 -3
- package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
- package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
- package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
- package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
- package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
- package/dist/resources/extensions/gsd/preferences-models.js +2 -2
- package/dist/resources/extensions/gsd/projection-flush.js +7 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +3 -3
- package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +7 -5
- package/dist/resources/extensions/gsd/prompts/system.md +5 -2
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
- package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
- package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
- package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
- package/dist/resources/extensions/gsd/session-lock.js +1 -1
- package/dist/resources/extensions/gsd/state.js +5 -0
- package/dist/resources/extensions/gsd/tool-contract.js +14 -3
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +22 -12
- package/dist/resources/extensions/gsd/tools/complete-task.js +3 -2
- package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -2
- package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
- package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
- package/dist/resources/extensions/gsd/uat-policy.js +40 -15
- package/dist/resources/extensions/gsd/unit-context-composer.js +65 -0
- package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
- package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
- package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
- package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
- package/dist/resources/extensions/gsd/workflow-events.js +6 -18
- package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
- package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
- package/dist/resources/extensions/gsd/worktree.js +8 -1
- package/dist/resources/extensions/shared/gsd-browser-cli.js +45 -3
- package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
- package/dist/resources/shared/package-manager-detection.js +1 -1
- package/dist/resources/shared/package.json +3 -0
- package/dist/resources/skills/create-skill/SKILL.md +3 -0
- package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/update-check.d.ts +2 -0
- package/dist/update-check.js +24 -1
- package/dist/update-cmd.js +20 -3
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +6 -6
- 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 +1 -1
- 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/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/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 +6 -6
- 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/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +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/package.json +2 -2
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/rpc.d.ts +1 -0
- package/packages/contracts/dist/rpc.d.ts.map +1 -1
- package/packages/contracts/dist/rpc.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
- 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 +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.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 +7 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/cli.js +10 -5
- package/packages/mcp-server/dist/cli.js.map +1 -1
- package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
- package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
- package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
- package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +4 -0
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +18 -18
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +99 -38
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +5 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
- package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
- package/packages/pi-agent-core/dist/index.d.ts +1 -0
- package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/index.js +3 -0
- package/packages/pi-agent-core/dist/index.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/README.md +1 -0
- package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
- package/packages/pi-ai/dist/image-models.generated.js +6 -6
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/index.d.ts +2 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +2 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +419 -221
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +460 -261
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +12 -7
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
- package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-shared.js +12 -3
- package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/packages/pi-ai/package.json +3 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
- package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
- package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
- package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +5 -4
- package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
- package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
- package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
- package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
- package/src/resources/extensions/async-jobs/index.ts +79 -0
- package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
- package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
- package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
- package/src/resources/extensions/bg-shell/overlay.ts +9 -5
- package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
- package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
- package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
- package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
- package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
- package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
- package/src/resources/extensions/gsd/auto/loop.ts +4 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +98 -56
- package/src/resources/extensions/gsd/auto/phases.ts +65 -26
- package/src/resources/extensions/gsd/auto/session.ts +3 -0
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
- package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
- package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
- package/src/resources/extensions/gsd/auto-post-unit.ts +33 -12
- package/src/resources/extensions/gsd/auto-prompts.ts +115 -35
- package/src/resources/extensions/gsd/auto-start.ts +36 -18
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +4 -4
- package/src/resources/extensions/gsd/auto-verification.ts +26 -28
- package/src/resources/extensions/gsd/auto-worktree.ts +14 -1
- package/src/resources/extensions/gsd/auto.ts +44 -1
- package/src/resources/extensions/gsd/blocked-models.ts +49 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -5
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +23 -6
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +163 -55
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +350 -86
- package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
- package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
- package/src/resources/extensions/gsd/commands/context.ts +16 -2
- package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
- package/src/resources/extensions/gsd/consent-question.ts +431 -0
- package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
- package/src/resources/extensions/gsd/constants.ts +0 -3
- package/src/resources/extensions/gsd/crash-recovery.ts +10 -2
- package/src/resources/extensions/gsd/db/queries.ts +37 -0
- package/src/resources/extensions/gsd/db-writer.ts +11 -19
- package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
- package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
- package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
- package/src/resources/extensions/gsd/files.ts +33 -12
- package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
- package/src/resources/extensions/gsd/gsd-db.ts +4 -3
- package/src/resources/extensions/gsd/guidance.ts +78 -0
- package/src/resources/extensions/gsd/guided-flow.ts +21 -26
- package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
- package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
- package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
- package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
- package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
- package/src/resources/extensions/gsd/preferences-models.ts +2 -1
- package/src/resources/extensions/gsd/projection-flush.ts +20 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +3 -3
- package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +7 -5
- package/src/resources/extensions/gsd/prompts/system.md +5 -2
- package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
- package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
- package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
- package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
- package/src/resources/extensions/gsd/session-lock.ts +1 -1
- package/src/resources/extensions/gsd/state.ts +5 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +198 -26
- package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
- package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
- package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
- package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
- package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
- package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/guidance.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +2 -6
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +138 -0
- package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +19 -1
- package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +273 -38
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
- package/src/resources/extensions/gsd/tool-contract.ts +38 -3
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
- package/src/resources/extensions/gsd/tools/complete-slice.ts +22 -12
- package/src/resources/extensions/gsd/tools/complete-task.ts +3 -2
- package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
- package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
- package/src/resources/extensions/gsd/uat-policy.ts +60 -15
- package/src/resources/extensions/gsd/unit-context-composer.ts +99 -0
- package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
- package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
- package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
- package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
- package/src/resources/extensions/gsd/workflow-events.ts +12 -20
- package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
- package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
- package/src/resources/extensions/gsd/worktree.ts +7 -1
- package/src/resources/extensions/shared/gsd-browser-cli.ts +54 -3
- package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
- package/src/resources/shared/package-manager-detection.ts +1 -1
- package/src/resources/shared/package.json +3 -0
- package/src/resources/skills/create-skill/SKILL.md +3 -0
- package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
- package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
- package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
- package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
- package/src/resources/skills/gsd-browser/SKILL.md +0 -41
- /package/dist/web/standalone/.next/static/{AOpDeK_gJHU8OZjRo31gQ → FBNo5cT_chy7YNoAQsU3o}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{AOpDeK_gJHU8OZjRo31gQ → FBNo5cT_chy7YNoAQsU3o}/_ssgManifest.js +0 -0
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
// File Purpose: Declarative auto-mode dispatch rules and dispatch resolver.
|
|
3
3
|
import { loadFile, extractUatType, loadActiveOverrides } from "./files.js";
|
|
4
4
|
import { getUatBrowserToolSupportError } from "./uat-policy.js";
|
|
5
|
-
import { isDbAvailable, getMilestoneSlices, getPendingGatesForTurn, markPendingGatesOmittedForTurn, getMilestone, insertArtifact, insertAssessment, setSliceSketchFlag, transaction, getAssessment, } from "./gsd-db.js";
|
|
5
|
+
import { isDbAvailable, getMilestoneSlices, getMilestoneSliceSummaries, getClosedSliceIds, getPendingGatesForTurn, markPendingGatesOmittedForTurn, getMilestone, insertArtifact, insertAssessment, setSliceSketchFlag, transaction, getAssessment, } from "./gsd-db.js";
|
|
6
6
|
import { isClosedStatus } from "./status-guards.js";
|
|
7
7
|
import { extractVerdict, isAcceptableUatVerdict } from "./verdict-parser.js";
|
|
8
8
|
import { gsdRoot, resolveGsdPathContract, resolveMilestoneFile, resolveMilestonePath, resolveSliceFile, resolveSlicePath, resolveTaskFile, relTaskFile, relSliceFile, buildMilestoneFileName, buildSliceFileName, buildTaskFileName, gsdProjectionRoot, } from "./paths.js";
|
|
9
|
-
import { parseRoadmap } from "./parsers-legacy.js";
|
|
10
9
|
import { validateArtifact } from "./schemas/validate.js";
|
|
11
10
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, readdirSync } from "node:fs";
|
|
12
11
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
@@ -19,10 +18,15 @@ import { selectReactiveDispatchBatch } from "./uok/execution-graph.js";
|
|
|
19
18
|
import { getMilestonePipelineVariant } from "./milestone-scope-classifier.js";
|
|
20
19
|
import { EXECUTION_ENTRY_PHASES, hasFinalizedMilestoneContext } from "./uok/plan-v2.js";
|
|
21
20
|
import { isAutoActive } from "./auto.js";
|
|
22
|
-
|
|
21
|
+
// Host adapter explicitly: auto-dispatch runs in the extension host, and the
|
|
22
|
+
// ambient write-gate exports env-sniff the adapter per call (they are reserved
|
|
23
|
+
// for the workflow MCP child's dynamic-import surface).
|
|
24
|
+
import { hostWriteGateAdapter } from "./bootstrap/write-gate.js";
|
|
23
25
|
import { ensureWorkflowPreferencesCaptured } from "./planning-depth.js";
|
|
24
26
|
import { MILESTONE_ID_RE } from "./milestone-ids.js";
|
|
25
|
-
import {
|
|
27
|
+
import { resolveWorkflowMcpProjectRoot } from "./workflow-mcp.js";
|
|
28
|
+
import { getUnitWorkflowDispatchReadinessError } from "./tool-contract.js";
|
|
29
|
+
import { prepareBrowserDaemonForUat } from "./browser-daemon-auto-prep.js";
|
|
26
30
|
import { PROJECT_RESEARCH_INFLIGHT_MARKER, } from "./project-research-policy.js";
|
|
27
31
|
import { isWorkflowPrefsCaptured, resolveDeepProjectSetupState, } from "./deep-project-setup-policy.js";
|
|
28
32
|
import { annotateBackgroundable } from "./delegation-policy.js";
|
|
@@ -289,30 +293,13 @@ function persistSliceAssessmentBackfill(assessmentRelPath, mid, sliceId, content
|
|
|
289
293
|
});
|
|
290
294
|
}
|
|
291
295
|
function backfillMissingAssessmentsFromSummaries(basePath, mid) {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
}
|
|
300
|
-
else {
|
|
301
|
-
const roadmapFile = resolveMilestoneFile(basePath, mid, "ROADMAP");
|
|
302
|
-
if (!roadmapFile)
|
|
303
|
-
return;
|
|
304
|
-
try {
|
|
305
|
-
const roadmap = parseRoadmap(readFileSync(roadmapFile, "utf-8"));
|
|
306
|
-
for (const slice of roadmap.slices) {
|
|
307
|
-
if (slice.done)
|
|
308
|
-
completedSliceIds.add(slice.id);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
catch {
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
for (const sliceId of completedSliceIds) {
|
|
296
|
+
// DB-authoritative (ADR-017): no markdown fallback. Without DB rows there
|
|
297
|
+
// is nothing to backfill.
|
|
298
|
+
if (!isDbAvailable())
|
|
299
|
+
return;
|
|
300
|
+
// Canonical closed vocabulary (complete/done/skipped/closed) — a skipped or
|
|
301
|
+
// closed slice with a SUMMARY gets the same assessment backfill treatment.
|
|
302
|
+
for (const sliceId of getClosedSliceIds(mid)) {
|
|
316
303
|
const summaryPath = resolveSliceFile(basePath, mid, sliceId, "SUMMARY");
|
|
317
304
|
if (!summaryPath || !existsSync(summaryPath))
|
|
318
305
|
continue;
|
|
@@ -488,7 +475,7 @@ export const DISPATCH_RULES = [
|
|
|
488
475
|
// deadlock. Deep planning is still user-driven even inside auto-mode,
|
|
489
476
|
// so it must wait for explicit approval instead of taking this bypass.
|
|
490
477
|
if (shouldBypassMilestoneDepthGateInAuto(prefs)) {
|
|
491
|
-
markDepthVerified(mid, basePath);
|
|
478
|
+
hostWriteGateAdapter.markDepthVerified(mid, basePath);
|
|
492
479
|
}
|
|
493
480
|
return {
|
|
494
481
|
action: "dispatch",
|
|
@@ -526,7 +513,15 @@ export const DISPATCH_RULES = [
|
|
|
526
513
|
// Transport preflight: verify required MCP tools are actually connected
|
|
527
514
|
// before consuming a retry attempt. Fixes tool-starved sessions burning
|
|
528
515
|
// all MAX_UAT_ATTEMPTS before stopping (#477).
|
|
529
|
-
const transportError =
|
|
516
|
+
const transportError = getUnitWorkflowDispatchReadinessError({
|
|
517
|
+
provider: sessionProvider,
|
|
518
|
+
projectRoot: basePath,
|
|
519
|
+
surface: "auto-mode",
|
|
520
|
+
unitType: "run-uat",
|
|
521
|
+
authMode: sessionAuthMode,
|
|
522
|
+
baseUrl: sessionBaseUrl,
|
|
523
|
+
activeTools,
|
|
524
|
+
});
|
|
530
525
|
if (transportError) {
|
|
531
526
|
return { action: "stop", reason: transportError, level: "warning" };
|
|
532
527
|
}
|
|
@@ -540,6 +535,16 @@ export const DISPATCH_RULES = [
|
|
|
540
535
|
if (browserToolError) {
|
|
541
536
|
return { action: "stop", reason: browserToolError, level: "warning" };
|
|
542
537
|
}
|
|
538
|
+
const browserDaemonError = prepareBrowserDaemonForUat({
|
|
539
|
+
uatType,
|
|
540
|
+
sessionProvider,
|
|
541
|
+
sessionAuthMode,
|
|
542
|
+
sessionBaseUrl,
|
|
543
|
+
projectRoot: resolveWorkflowMcpProjectRoot(basePath),
|
|
544
|
+
});
|
|
545
|
+
if (browserDaemonError) {
|
|
546
|
+
return { action: "stop", reason: browserDaemonError, level: "warning" };
|
|
547
|
+
}
|
|
543
548
|
// Cap run-uat dispatch attempts to prevent infinite replay (#3624).
|
|
544
549
|
// Check before incrementing so an exhausted counter cannot create a
|
|
545
550
|
// no-progress skip loop that starves later dispatch rules.
|
|
@@ -569,24 +574,11 @@ export const DISPATCH_RULES = [
|
|
|
569
574
|
// Only applies when UAT dispatch is enabled
|
|
570
575
|
if (!prefs?.uat_dispatch)
|
|
571
576
|
return null;
|
|
572
|
-
// DB-
|
|
573
|
-
|
|
574
|
-
if (isDbAvailable())
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
.map(s => s.id);
|
|
578
|
-
}
|
|
579
|
-
else {
|
|
580
|
-
// Filesystem fallback for degraded / unmigrated projects.
|
|
581
|
-
// `slice.done` in the parsed ROADMAP is the disk-level closed signal.
|
|
582
|
-
const roadmapFile = resolveMilestoneFile(basePath, mid, "ROADMAP");
|
|
583
|
-
const roadmapContent = roadmapFile ? await loadFile(roadmapFile) : null;
|
|
584
|
-
if (!roadmapContent)
|
|
585
|
-
return null;
|
|
586
|
-
const roadmap = parseRoadmap(roadmapContent);
|
|
587
|
-
closedSliceIds = roadmap.slices.filter(s => s.done).map(s => s.id);
|
|
588
|
-
}
|
|
589
|
-
for (const sliceId of closedSliceIds) {
|
|
577
|
+
// DB-authoritative (ADR-017): closed slices come from the DB only; the
|
|
578
|
+
// ROADMAP projection is never parsed for gate decisions.
|
|
579
|
+
if (!isDbAvailable())
|
|
580
|
+
return null;
|
|
581
|
+
for (const sliceId of getClosedSliceIds(mid)) {
|
|
590
582
|
const result = await readUatGateVerdict(basePath, mid, sliceId);
|
|
591
583
|
if (!result)
|
|
592
584
|
continue;
|
|
@@ -641,7 +633,7 @@ export const DISPATCH_RULES = [
|
|
|
641
633
|
// H6 fix (#4973): keep the non-deep auto-mode bypass, but do not
|
|
642
634
|
// pre-verify deep planning's user-facing milestone approval gate.
|
|
643
635
|
if (shouldBypassMilestoneDepthGateInAuto(prefs)) {
|
|
644
|
-
markDepthVerified(mid, basePath);
|
|
636
|
+
hostWriteGateAdapter.markDepthVerified(mid, basePath);
|
|
645
637
|
}
|
|
646
638
|
return {
|
|
647
639
|
action: "dispatch",
|
|
@@ -823,7 +815,7 @@ export const DISPATCH_RULES = [
|
|
|
823
815
|
// H6 fix (#4973): keep the non-deep auto-mode bypass, but do not
|
|
824
816
|
// pre-verify deep planning's user-facing milestone approval gate.
|
|
825
817
|
if (shouldBypassMilestoneDepthGateInAuto(prefs)) {
|
|
826
|
-
markDepthVerified(mid, basePath);
|
|
818
|
+
hostWriteGateAdapter.markDepthVerified(mid, basePath);
|
|
827
819
|
}
|
|
828
820
|
return {
|
|
829
821
|
action: "dispatch",
|
|
@@ -905,18 +897,18 @@ export const DISPATCH_RULES = [
|
|
|
905
897
|
// behavior.
|
|
906
898
|
if (await getMilestonePipelineVariant(mid) === "trivial")
|
|
907
899
|
return null;
|
|
908
|
-
//
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
900
|
+
// DB-authoritative slice list (ADR-017): the ROADMAP projection is
|
|
901
|
+
// never parsed for dispatch decisions. No DB / no rows → skip this rule.
|
|
902
|
+
if (!isDbAvailable())
|
|
903
|
+
return null;
|
|
904
|
+
const dbSlices = getMilestoneSliceSummaries(mid);
|
|
905
|
+
if (dbSlices.length === 0)
|
|
913
906
|
return null;
|
|
914
|
-
const roadmap = parseRoadmap(roadmapContent);
|
|
915
907
|
// Find slices that need research (no RESEARCH file, dependencies done)
|
|
916
908
|
const milestoneResearchFile = resolveExistingExpectedArtifact("research-milestone", mid, basePath) ??
|
|
917
909
|
resolveMilestoneFile(basePath, mid, "RESEARCH");
|
|
918
910
|
const researchReadySlices = [];
|
|
919
|
-
for (const slice of
|
|
911
|
+
for (const slice of dbSlices) {
|
|
920
912
|
if (slice.done)
|
|
921
913
|
continue;
|
|
922
914
|
// Skip S01 when milestone research exists
|
|
@@ -926,7 +918,7 @@ export const DISPATCH_RULES = [
|
|
|
926
918
|
if (resolveExistingExpectedArtifact("research-slice", `${mid}/${slice.id}`, basePath))
|
|
927
919
|
continue;
|
|
928
920
|
// Skip if dependencies aren't done (check for SUMMARY files)
|
|
929
|
-
const depsComplete =
|
|
921
|
+
const depsComplete = slice.depends.every((depId) => !!resolveExistingExpectedArtifact("complete-slice", `${mid}/${depId}`, basePath));
|
|
930
922
|
if (!depsComplete)
|
|
931
923
|
continue;
|
|
932
924
|
researchReadySlices.push({ id: slice.id, title: slice.title });
|
|
@@ -13,7 +13,7 @@ import { getSessionModelOverride } from "./session-model-override.js";
|
|
|
13
13
|
import { logWarning } from "./workflow-logger.js";
|
|
14
14
|
import { resolveUokFlags } from "./uok/flags.js";
|
|
15
15
|
import { applyModelPolicyFilter } from "./uok/model-policy.js";
|
|
16
|
-
import { isModelBlocked } from "./blocked-models.js";
|
|
16
|
+
import { isModelBlocked, isModelTemporarilyUnavailable } from "./blocked-models.js";
|
|
17
17
|
import { getRequiredWorkflowToolsForAutoUnit, isWorkflowMcpSurfaceTool } from "./workflow-mcp.js";
|
|
18
18
|
/**
|
|
19
19
|
* Thrown when the model-policy gate rejects every candidate model for a unit
|
|
@@ -218,6 +218,10 @@ function buildModelPolicyBlockReasons(policyDenyReasons, availableModels, routin
|
|
|
218
218
|
reason: `configured model(s) did not resolve against policy-eligible registry [${eligibleSummary}]`,
|
|
219
219
|
}];
|
|
220
220
|
}
|
|
221
|
+
function isModelUnavailable(basePath, provider, id) {
|
|
222
|
+
return isModelBlocked(basePath, provider, id) ||
|
|
223
|
+
isModelTemporarilyUnavailable(basePath, provider, id);
|
|
224
|
+
}
|
|
221
225
|
function restoreToolBaseline(pi) {
|
|
222
226
|
const key = pi;
|
|
223
227
|
const baseline = TOOL_BASELINE.get(key);
|
|
@@ -657,8 +661,8 @@ autoModeStartThinkingLevel) {
|
|
|
657
661
|
// (issue #4513). The block is persisted in .gsd/runtime/blocked-models.json
|
|
658
662
|
// so it survives /gsd auto restarts — without this, the same dead model
|
|
659
663
|
// gets reselected after every restart.
|
|
660
|
-
if (
|
|
661
|
-
ctx.ui.notify(`Skipping
|
|
664
|
+
if (isModelUnavailable(basePath, model.provider, model.id)) {
|
|
665
|
+
ctx.ui.notify(`Skipping unavailable model ${model.provider}/${model.id}.`, "warning");
|
|
662
666
|
continue;
|
|
663
667
|
}
|
|
664
668
|
// Warn if the ID is ambiguous across providers
|
|
@@ -724,7 +728,7 @@ autoModeStartThinkingLevel) {
|
|
|
724
728
|
const key = `${model.provider.toLowerCase()}/${model.id.toLowerCase()}`;
|
|
725
729
|
if (!policyAllowedModelKeys.has(key))
|
|
726
730
|
continue;
|
|
727
|
-
if (
|
|
731
|
+
if (isModelUnavailable(basePath, model.provider, model.id))
|
|
728
732
|
continue;
|
|
729
733
|
const ok = await pi.setModel(model, { persist: false });
|
|
730
734
|
if (!ok)
|
|
@@ -746,16 +750,16 @@ autoModeStartThinkingLevel) {
|
|
|
746
750
|
// No model preference for this unit type — re-apply the model captured
|
|
747
751
|
// at auto-mode start to prevent bleed from shared global settings.json (#650).
|
|
748
752
|
const availableModels = buildModelPolicyCandidates(ctx, autoModeStartModel, effectiveSessionModelOverride);
|
|
749
|
-
const startBlocked =
|
|
753
|
+
const startBlocked = isModelUnavailable(basePath, autoModeStartModel.provider, autoModeStartModel.id);
|
|
750
754
|
if (startBlocked) {
|
|
751
|
-
ctx.ui.notify(`Auto-mode start model ${autoModeStartModel.provider}/${autoModeStartModel.id} is
|
|
755
|
+
ctx.ui.notify(`Auto-mode start model ${autoModeStartModel.provider}/${autoModeStartModel.id} is unavailable. Using current session model instead.`, "warning");
|
|
752
756
|
}
|
|
753
757
|
else {
|
|
754
758
|
const startModel = availableModels.find(m => m.provider === autoModeStartModel.provider && m.id === autoModeStartModel.id);
|
|
755
759
|
if (startModel) {
|
|
756
760
|
const ok = await pi.setModel(startModel, { persist: false });
|
|
757
761
|
if (!ok) {
|
|
758
|
-
const byId = availableModels.find(m => m.id === autoModeStartModel.id && !
|
|
762
|
+
const byId = availableModels.find(m => m.id === autoModeStartModel.id && !isModelUnavailable(basePath, m.provider, m.id));
|
|
759
763
|
if (byId) {
|
|
760
764
|
const fallbackOk = await pi.setModel(byId, { persist: false });
|
|
761
765
|
if (fallbackOk) {
|
|
@@ -839,15 +843,34 @@ export function resolveModelId(modelId, availableModels, currentProvider) {
|
|
|
839
843
|
if (providerMatch)
|
|
840
844
|
return providerMatch;
|
|
841
845
|
}
|
|
842
|
-
//
|
|
843
|
-
//
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
846
|
+
// Subscription/OAuth routes beat pay-per-token API when the same model ID
|
|
847
|
+
// exists on multiple providers. Order matters — first match wins.
|
|
848
|
+
for (const provider of BARE_ID_SUBSCRIPTION_PROVIDER_PRECEDENCE) {
|
|
849
|
+
const match = candidates.find(m => m.provider === provider);
|
|
850
|
+
if (match)
|
|
851
|
+
return match;
|
|
852
|
+
}
|
|
848
853
|
// Fall back to first non-extension candidate, or any candidate
|
|
849
854
|
return candidates.find(m => !EXTENSION_PROVIDERS.has(m.provider)) ?? candidates[0];
|
|
850
855
|
}
|
|
856
|
+
/**
|
|
857
|
+
* When a bare model ID exists on multiple providers, prefer subscription/OAuth
|
|
858
|
+
* routes over pay-per-token API keys. Matches PROVIDER_ROUTES in doctor-providers
|
|
859
|
+
* but applies when *both* sides are authenticated.
|
|
860
|
+
*
|
|
861
|
+
* Order rationale:
|
|
862
|
+
* - openai-codex before github-copilot: ChatGPT-native for shared GPT IDs
|
|
863
|
+
* - google-gemini-cli before github-copilot: first-party Gemini CLI
|
|
864
|
+
* - anthropic before github-copilot: first-party Claude API/OAuth over Copilot
|
|
865
|
+
* - github-copilot before openai/google: Copilot OAuth over platform API keys
|
|
866
|
+
*/
|
|
867
|
+
export const BARE_ID_SUBSCRIPTION_PROVIDER_PRECEDENCE = [
|
|
868
|
+
"openai-codex",
|
|
869
|
+
"google-gemini-cli",
|
|
870
|
+
"anthropic",
|
|
871
|
+
"github-copilot",
|
|
872
|
+
"google-antigravity",
|
|
873
|
+
];
|
|
851
874
|
/**
|
|
852
875
|
* Flat-rate providers charge the same per request regardless of model.
|
|
853
876
|
* Dynamic routing provides no cost benefit — it only degrades quality (#3453).
|
|
@@ -16,7 +16,7 @@ import { deriveState } from "./state.js";
|
|
|
16
16
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
17
17
|
import { loadFile, parseSummary, resolveAllOverrides } from "./files.js";
|
|
18
18
|
import { loadPrompt } from "./prompt-loader.js";
|
|
19
|
-
import { isAwaitingUserInput } from "./
|
|
19
|
+
import { isAwaitingUserInput } from "./consent-question.js";
|
|
20
20
|
import { resolveMilestonePath, resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveMilestoneFile, resolveTasksDir, buildTaskFileName, } from "./paths.js";
|
|
21
21
|
import { invalidateAllCaches } from "./cache.js";
|
|
22
22
|
import { rebuildState } from "./doctor.js";
|
|
@@ -30,8 +30,7 @@ import { createWorkspace, scopeMilestone } from "./workspace.js";
|
|
|
30
30
|
import { normalizeWorktreePathForCompare } from "./worktree-root.js";
|
|
31
31
|
import { isDbAvailable, getTask, getSlice, getMilestone, getMilestoneSlices, updateTaskStatus, _getAdapter, getVerificationEvidence } from "./gsd-db.js";
|
|
32
32
|
import { getWorkflowDatabasePath, refreshWorkflowDatabaseFromDisk } from "./db-workspace.js";
|
|
33
|
-
import { renderPlanCheckboxes, renderRoadmapFromDb } from "./markdown-renderer.js";
|
|
34
|
-
import { parseRoadmap as parseLegacyRoadmap } from "./parsers-legacy.js";
|
|
33
|
+
import { renderPlanCheckboxes, renderRoadmapFromDb, roadmapRenderMarksSliceDone } from "./markdown-renderer.js";
|
|
35
34
|
import { consumeSignal } from "./session-status-io.js";
|
|
36
35
|
import { checkPostUnitHooks, consumeHookFailure, isRetryPending, consumeRetryTrigger, consumeGateBlock, persistHookState, resolveHookArtifactPath, } from "./post-unit-hooks.js";
|
|
37
36
|
import { hasPendingCaptures, loadPendingCaptures, revertExecutorResolvedCaptures } from "./captures.js";
|
|
@@ -60,6 +59,7 @@ import { formatConnectedStepStack, formatPostUnitStatusCard } from "./auto-statu
|
|
|
60
59
|
import { clearProjectResearchInflightMarker, finalizeProjectResearchTimeout, } from "./project-research-policy.js";
|
|
61
60
|
import { validateArtifact } from "./schemas/validate.js";
|
|
62
61
|
import { verificationRetryKey } from "./auto/verification-retry-policy.js";
|
|
62
|
+
import { saveCustomVerifyRetryCounts } from "./auto/custom-verify-retry-store.js";
|
|
63
63
|
import { getLedger } from "./metrics.js";
|
|
64
64
|
import { getUnitCostSpikeAction, resolveUnitCostSpikeMultiplier } from "./auto-budget.js";
|
|
65
65
|
import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
|
|
@@ -722,7 +722,7 @@ export const USER_DRIVEN_DEEP_UNITS = new Set([
|
|
|
722
722
|
"discuss-milestone",
|
|
723
723
|
"research-decision",
|
|
724
724
|
]);
|
|
725
|
-
export { isAwaitingUserInput } from "./
|
|
725
|
+
export { isAwaitingUserInput } from "./consent-question.js";
|
|
726
726
|
function artifactValidationKind(unitType) {
|
|
727
727
|
if (unitType === "discuss-project")
|
|
728
728
|
return "project";
|
|
@@ -800,11 +800,13 @@ async function repairCompleteSliceRoadmapProjection(unitType, unitId, basePath)
|
|
|
800
800
|
if (!summaryPath || !existsSync(summaryPath) || !uatPath || !existsSync(uatPath)) {
|
|
801
801
|
return false;
|
|
802
802
|
}
|
|
803
|
+
// Stale-render detection (ADR-017): the DB already says the slice is closed;
|
|
804
|
+
// this only checks whether the rendered ROADMAP projection reflects it, to
|
|
805
|
+
// decide whether a repair re-render is needed.
|
|
803
806
|
const roadmapPath = resolveMilestoneFile(artifactBase, mid, "ROADMAP");
|
|
804
807
|
if (roadmapPath && existsSync(roadmapPath)) {
|
|
805
808
|
try {
|
|
806
|
-
|
|
807
|
-
if (roadmap.slices.find((roadmapSlice) => roadmapSlice.id === sid)?.done) {
|
|
809
|
+
if (roadmapRenderMarksSliceDone(readFileSync(roadmapPath, "utf-8"), sid)) {
|
|
808
810
|
return false;
|
|
809
811
|
}
|
|
810
812
|
}
|
|
@@ -1702,13 +1704,24 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
1702
1704
|
}
|
|
1703
1705
|
else if (!triggerArtifactVerified) {
|
|
1704
1706
|
if (s.lastToolInvocationError && isToolUnavailableError(s.lastToolInvocationError)) {
|
|
1705
|
-
// Tool-unavailable is the
|
|
1706
|
-
//
|
|
1707
|
-
//
|
|
1708
|
-
//
|
|
1709
|
-
|
|
1710
|
-
|
|
1707
|
+
// Tool-unavailable is transient: the workflow MCP server registers
|
|
1708
|
+
// its surface asynchronously, so a Unit's first call can race the
|
|
1709
|
+
// registration. Retry with escalating delay, bounded at 3 attempts.
|
|
1710
|
+
// ponytail: MAX constant so the guard, log, and display all agree
|
|
1711
|
+
const MAX_TOOL_UNAVAIL_RETRIES = 3;
|
|
1712
|
+
if (s.toolUnavailableRetries >= MAX_TOOL_UNAVAIL_RETRIES) {
|
|
1713
|
+
debugLog("postUnit", { phase: "tool-unavailable-exhausted", unitType: s.currentUnit.type, unitId: s.currentUnit.id, retries: s.toolUnavailableRetries });
|
|
1714
|
+
ctx.ui.notify(`Tool unavailable for ${s.currentUnit.type} after ${MAX_TOOL_UNAVAIL_RETRIES} retries: ${s.lastToolInvocationError}. MCP server may not be starting — pausing auto-mode.`, "error");
|
|
1715
|
+
s.lastToolInvocationError = null;
|
|
1716
|
+
await pauseAuto(ctx, pi);
|
|
1717
|
+
return "dispatched";
|
|
1718
|
+
}
|
|
1719
|
+
s.toolUnavailableRetries++;
|
|
1720
|
+
const delayMs = s.toolUnavailableRetries * 1000;
|
|
1721
|
+
debugLog("postUnit", { phase: "tool-unavailable-retry", unitType: s.currentUnit.type, unitId: s.currentUnit.id, error: s.lastToolInvocationError, attempt: s.toolUnavailableRetries, delayMs });
|
|
1722
|
+
ctx.ui.notify(`Tool unavailable for ${s.currentUnit.type}: ${s.lastToolInvocationError}. Waiting ${delayMs}ms for MCP server — retry ${s.toolUnavailableRetries}/${MAX_TOOL_UNAVAIL_RETRIES}.`, "warning");
|
|
1711
1723
|
s.lastToolInvocationError = null;
|
|
1724
|
+
await new Promise(r => setTimeout(r, delayMs));
|
|
1712
1725
|
}
|
|
1713
1726
|
else if (s.lastToolInvocationError) {
|
|
1714
1727
|
const isUserSkip = /queued user message/i.test(s.lastToolInvocationError);
|
|
@@ -1798,12 +1811,14 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
1798
1811
|
}
|
|
1799
1812
|
}
|
|
1800
1813
|
s.exhaustedVerificationUnits.add(retryKey);
|
|
1814
|
+
saveCustomVerifyRetryCounts(s, { logFailure: err => debugLog("postUnit", { phase: "save-verify-retries-failed", error: err instanceof Error ? err.message : String(err) }) });
|
|
1801
1815
|
debugLog("postUnit", { phase: "artifact-verify-exhausted", unitType: s.currentUnit.type, unitId: s.currentUnit.id, attempt });
|
|
1802
1816
|
ctx.ui.notify(`${failureDetails} Pausing auto-mode after ${MAX_ARTIFACT_VERIFICATION_RETRIES} retries.`, "error");
|
|
1803
1817
|
await pauseAuto(ctx, pi);
|
|
1804
1818
|
return "dispatched";
|
|
1805
1819
|
}
|
|
1806
1820
|
s.verificationRetryCount.set(retryKey, attempt);
|
|
1821
|
+
saveCustomVerifyRetryCounts(s, { logFailure: err => debugLog("postUnit", { phase: "save-verify-retries-failed", error: err instanceof Error ? err.message : String(err) }) });
|
|
1807
1822
|
s.pendingVerificationRetry = {
|
|
1808
1823
|
unitId: s.currentUnit.id,
|
|
1809
1824
|
failureContext: `${failureDetails} (attempt ${attempt}/${MAX_ARTIFACT_VERIFICATION_RETRIES}).`,
|
|
@@ -1821,8 +1836,11 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
1821
1836
|
if (s.pendingVerificationRetry?.unitId === s.currentUnit.id) {
|
|
1822
1837
|
s.pendingVerificationRetry = null;
|
|
1823
1838
|
}
|
|
1839
|
+
s.toolUnavailableRetries = 0;
|
|
1824
1840
|
s.verificationRetryCount.delete(retryKey);
|
|
1825
1841
|
s.verificationRetryFailureHashes.delete(retryKey);
|
|
1842
|
+
s.exhaustedVerificationUnits.delete(retryKey);
|
|
1843
|
+
saveCustomVerifyRetryCounts(s, { logFailure: err => debugLog("postUnit", { phase: "save-verify-retries-failed", error: err instanceof Error ? err.message : String(err) }) });
|
|
1826
1844
|
if (s.currentUnit.type === "complete-milestone") {
|
|
1827
1845
|
const { milestone: mid } = parseUnitId(s.currentUnit.id);
|
|
1828
1846
|
if (mid) {
|
|
@@ -21,7 +21,7 @@ import { getPendingGatesForTurn } from "./gsd-db.js";
|
|
|
21
21
|
import { assertGateCoverage, getGatesForTurn, } from "./gate-registry.js";
|
|
22
22
|
import { formatDecisionsCompact, formatRequirementsCompact } from "./structured-data-formatter.js";
|
|
23
23
|
import { readPhaseAnchor, formatAnchorForPrompt } from "./phase-anchor.js";
|
|
24
|
-
import { composeContextModeInstructions, composeContractedUnitContext, composeInlinedContext, composeUnitContext, } from "./unit-context-composer.js";
|
|
24
|
+
import { composeContextModeInstructions, composeContractedUnitContext, composeInlinedContext, composeToolSurfaceInstructions, composeUnitContext, } from "./unit-context-composer.js";
|
|
25
25
|
import { resolveManifest } from "./unit-context-manifest.js";
|
|
26
26
|
import { compileUnitContextContract } from "./tool-contract.js";
|
|
27
27
|
import { readCompactionSnapshot } from "./compaction-snapshot.js";
|
|
@@ -33,7 +33,7 @@ import { debugLog } from "./debug-logger.js";
|
|
|
33
33
|
import { buildSkillActivationBlock, buildSkillDiscoveryVars } from "./skill-activation.js";
|
|
34
34
|
import { findMilestoneIds } from "./milestone-ids.js";
|
|
35
35
|
import { buildRunUatPresentationForType, RUN_UAT_TOOL_PRESENTATION_PLAN_ID } from "./tool-presentation-plan.js";
|
|
36
|
-
import {
|
|
36
|
+
import { classifyUatContentForRun, shouldDispatchUatForContent, } from "./uat-policy.js";
|
|
37
37
|
import { buildWebAppUatGuidanceBlock } from "./web-app-uat.js";
|
|
38
38
|
export { buildSkillActivationBlock, buildSkillDiscoveryVars };
|
|
39
39
|
// ─── Preamble Cap ─────────────────────────────────────────────────────────────
|
|
@@ -224,12 +224,14 @@ function renderContextModeBlockForPrompt(unitType, base, renderMode = "standalon
|
|
|
224
224
|
return `${contextMode}\n\n## Context Snapshot\nSource: \`.gsd/last-snapshot.md\`\n\n${snapshot.trimEnd()}`;
|
|
225
225
|
}
|
|
226
226
|
function prependContextModeToBlock(unitType, base, block, renderMode = "standalone") {
|
|
227
|
+
const toolSurface = composeToolSurfaceInstructions(unitType, { renderMode });
|
|
227
228
|
const contextMode = renderContextModeBlockForPrompt(unitType, base, renderMode);
|
|
228
|
-
|
|
229
|
+
const guidance = [toolSurface, contextMode].filter(Boolean).join("\n\n");
|
|
230
|
+
if (!guidance)
|
|
229
231
|
return block;
|
|
230
232
|
if (!block.trim())
|
|
231
|
-
return
|
|
232
|
-
return `${
|
|
233
|
+
return guidance;
|
|
234
|
+
return `${guidance}\n\n${block}`;
|
|
233
235
|
}
|
|
234
236
|
function requireUnitPromptContextContract(unitType) {
|
|
235
237
|
const result = compileUnitContextContract(unitType);
|
|
@@ -841,7 +843,7 @@ export async function inlineDecisionsFromDb(base, milestoneId, scope, level) {
|
|
|
841
843
|
}
|
|
842
844
|
/**
|
|
843
845
|
* Inline requirements with optional milestone and slice scoping from the DB.
|
|
844
|
-
* Falls back to filesystem via inlineGsdRootFile when DB unavailable
|
|
846
|
+
* Falls back to filesystem via inlineGsdRootFile only when DB is unavailable.
|
|
845
847
|
*/
|
|
846
848
|
export async function inlineRequirementsFromDb(base, milestoneId, sliceId, level) {
|
|
847
849
|
const inlineLevel = level ?? resolveInlineLevel();
|
|
@@ -849,14 +851,28 @@ export async function inlineRequirementsFromDb(base, milestoneId, sliceId, level
|
|
|
849
851
|
const { isDbAvailable } = await import("./gsd-db.js");
|
|
850
852
|
if (isDbAvailable()) {
|
|
851
853
|
const { queryRequirements, formatRequirementsForPrompt } = await import("./context-store.js");
|
|
852
|
-
|
|
854
|
+
let requirements = queryRequirements({ milestoneId, sliceId });
|
|
855
|
+
let broadenedScope = false;
|
|
856
|
+
if (requirements.length === 0 && sliceId) {
|
|
857
|
+
requirements = queryRequirements({ milestoneId });
|
|
858
|
+
broadenedScope = true;
|
|
859
|
+
}
|
|
860
|
+
if (requirements.length === 0 && milestoneId) {
|
|
861
|
+
requirements = queryRequirements({ status: "active" });
|
|
862
|
+
broadenedScope = true;
|
|
863
|
+
}
|
|
853
864
|
if (requirements.length > 0) {
|
|
854
|
-
// Use compact format for non-full levels
|
|
855
|
-
|
|
865
|
+
// Use compact format for non-full levels, milestone-scoped calls, and
|
|
866
|
+
// any cascade stage that broadened past the originally requested scope —
|
|
867
|
+
// a slice-scoped "full" call that fell through to the project-wide
|
|
868
|
+
// active fallback must not format those rows as full requirements.
|
|
869
|
+
const useCompact = inlineLevel !== "full" || !sliceId || broadenedScope;
|
|
870
|
+
const formatted = useCompact
|
|
856
871
|
? formatRequirementsCompact(requirements)
|
|
857
872
|
: formatRequirementsForPrompt(requirements);
|
|
858
873
|
return `### Requirements\nSource: \`.gsd/REQUIREMENTS.md\`\n\n${formatted}`;
|
|
859
874
|
}
|
|
875
|
+
return null;
|
|
860
876
|
}
|
|
861
877
|
}
|
|
862
878
|
catch (err) {
|
|
@@ -1265,6 +1281,32 @@ export async function checkNeedsReassessment(base, mid, state) {
|
|
|
1265
1281
|
* - No UAT file exists for the slice
|
|
1266
1282
|
* - UAT result file already exists (idempotent — already ran)
|
|
1267
1283
|
*/
|
|
1284
|
+
/**
|
|
1285
|
+
* Resolve the effective UAT mode for the dispatch gate the same way
|
|
1286
|
+
* `buildRunUatPrompt` does: classify the UAT body with the slice's SUMMARY as
|
|
1287
|
+
* supplemental context, so a `browser-executable` UAT whose slice references a
|
|
1288
|
+
* self-contained harness (`npm run test:uat`, `search-uat.mjs`, `npx
|
|
1289
|
+
* playwright test`) is promoted to `runtime-executable` for the gate too.
|
|
1290
|
+
*
|
|
1291
|
+
* Without this, `checkNeedsRunUat` returns `browser-executable` while the
|
|
1292
|
+
* prompt instructs runtime-only execution, causing the dispatch gate to
|
|
1293
|
+
* require browser tools / warm up the browser daemon (or stop dispatch when
|
|
1294
|
+
* browser MCP is unavailable) for UAT runs that never touch the browser. See
|
|
1295
|
+
* cursor[bot] review on PR #696 for the M007/S01 regression.
|
|
1296
|
+
*/
|
|
1297
|
+
async function resolveRunUatEffectiveType(base, mid, sliceId, uatContent) {
|
|
1298
|
+
let summaryContent = "";
|
|
1299
|
+
try {
|
|
1300
|
+
const summaryPath = resolveSliceFile(base, mid, sliceId, "SUMMARY");
|
|
1301
|
+
if (summaryPath) {
|
|
1302
|
+
summaryContent = (await loadFile(summaryPath)) ?? "";
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
catch (err) {
|
|
1306
|
+
logWarning("prompt", `resolveRunUatEffectiveType SUMMARY load failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1307
|
+
}
|
|
1308
|
+
return classifyUatContentForRun(uatContent, summaryContent).effectiveType;
|
|
1309
|
+
}
|
|
1268
1310
|
export async function checkNeedsRunUat(base, mid, state, prefs) {
|
|
1269
1311
|
// DB primary path — fall through to file-based when DB has no data for this milestone
|
|
1270
1312
|
try {
|
|
@@ -1297,7 +1339,8 @@ export async function checkNeedsRunUat(base, mid, state, prefs) {
|
|
|
1297
1339
|
}
|
|
1298
1340
|
if (!shouldDispatchUatForContent(uatContent, prefs))
|
|
1299
1341
|
continue;
|
|
1300
|
-
|
|
1342
|
+
const uatType = await resolveRunUatEffectiveType(base, mid, sid, uatContent);
|
|
1343
|
+
return { sliceId: sid, uatType };
|
|
1301
1344
|
}
|
|
1302
1345
|
return null;
|
|
1303
1346
|
}
|
|
@@ -1338,7 +1381,8 @@ export async function checkNeedsRunUat(base, mid, state, prefs) {
|
|
|
1338
1381
|
}
|
|
1339
1382
|
if (!shouldDispatchUatForContent(uatContentFb, prefs))
|
|
1340
1383
|
continue;
|
|
1341
|
-
|
|
1384
|
+
const uatType = await resolveRunUatEffectiveType(base, mid, uatSid, uatContentFb);
|
|
1385
|
+
return { sliceId: uatSid, uatType };
|
|
1342
1386
|
}
|
|
1343
1387
|
return null;
|
|
1344
1388
|
}
|
|
@@ -3097,10 +3141,25 @@ export async function buildRunUatPrompt(mid, sliceId, uatPath, uatContent, base)
|
|
|
3097
3141
|
const rawInlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${composedBody}`;
|
|
3098
3142
|
const cappedInlinedContext = capPreamble(rawInlinedContext);
|
|
3099
3143
|
trackPromptContext(contextTelemetry, "cap", cappedInlinedContext.length < rawInlinedContext.length ? "skipped" : "inline", null, cappedInlinedContext.length < rawInlinedContext.length ? `dropped ${rawInlinedContext.length - cappedInlinedContext.length} chars` : "within budget");
|
|
3100
|
-
const
|
|
3144
|
+
const uatPolicy = classifyUatContentForRun(uatContent, cappedInlinedContext);
|
|
3145
|
+
const uatType = uatPolicy.effectiveType;
|
|
3146
|
+
const runtimeHarnessOverride = uatPolicy.declaredType === "browser-executable" && uatType === "runtime-executable"
|
|
3147
|
+
? [
|
|
3148
|
+
"## Runtime harness override",
|
|
3149
|
+
"",
|
|
3150
|
+
"This UAT declares `browser-executable` but the slice references a self-contained verification command (`npm run test:uat`, `search-uat.mjs`, or similar).",
|
|
3151
|
+
"Run **only** that command via `gsd_uat_exec` with `uat-runtime-check` intent.",
|
|
3152
|
+
"Do **not** call `uat-service-start`, do **not** run `npm run start`, `npm run test:server`, or any separate server command.",
|
|
3153
|
+
"Do **not** use `browser_navigate` or other `browser_*` tools — the harness already exercises the browser.",
|
|
3154
|
+
"When the harness exits 0, save **PASS** with `uatType: \"runtime-executable\"` (the effective mode above, not the UAT file header) and **runtime** check modes only.",
|
|
3155
|
+
"",
|
|
3156
|
+
].join("\n")
|
|
3157
|
+
: "";
|
|
3158
|
+
const inlinedContext = prependContextModeToBlock("run-uat", base, runtimeHarnessOverride
|
|
3159
|
+
? `${runtimeHarnessOverride}\n${cappedInlinedContext}`
|
|
3160
|
+
: cappedInlinedContext);
|
|
3101
3161
|
emitPromptContextTelemetry("run-uat", contextTelemetry, inlinedContext);
|
|
3102
3162
|
const uatResultPath = join(base, relSliceFile(base, mid, sliceId, "ASSESSMENT"));
|
|
3103
|
-
const uatType = resolveEffectiveUatType(uatContent);
|
|
3104
3163
|
const canonicalPresentation = JSON.stringify(buildRunUatPresentationForType(uatType), null, 2);
|
|
3105
3164
|
return loadPrompt("run-uat", {
|
|
3106
3165
|
workingDirectory: base,
|
|
@@ -3341,18 +3400,18 @@ opts) {
|
|
|
3341
3400
|
}
|
|
3342
3401
|
const inlinedTemplates = inlineTemplate("task-summary", "Task Summary");
|
|
3343
3402
|
trackPromptContext(contextTelemetry, "templates", "inline", inlinedTemplates);
|
|
3344
|
-
const prompt = loadPrompt("reactive-execute", {
|
|
3403
|
+
const prompt = prependContextModeToBlock("reactive-execute", base, loadPrompt("reactive-execute", {
|
|
3345
3404
|
workingDirectory: base,
|
|
3346
3405
|
milestoneId: mid,
|
|
3347
3406
|
milestoneTitle: midTitle,
|
|
3348
3407
|
sliceId: sid,
|
|
3349
3408
|
sliceTitle: sTitle,
|
|
3350
|
-
graphContext
|
|
3409
|
+
graphContext,
|
|
3351
3410
|
readyTaskCount: String(readyTaskIds.length),
|
|
3352
3411
|
readyTaskList: readyTaskListLines.join("\n"),
|
|
3353
3412
|
subagentPrompts: subagentSections.join("\n\n---\n\n"),
|
|
3354
3413
|
inlinedTemplates,
|
|
3355
|
-
});
|
|
3414
|
+
}));
|
|
3356
3415
|
emitPromptContextTelemetry("reactive-execute", contextTelemetry, prompt);
|
|
3357
3416
|
return prompt;
|
|
3358
3417
|
}
|
|
@@ -3492,17 +3551,17 @@ export async function buildGateEvaluatePrompt(mid, midTitle, sid, sTitle, base,
|
|
|
3492
3551
|
"```",
|
|
3493
3552
|
].join("\n"));
|
|
3494
3553
|
}
|
|
3495
|
-
return loadPrompt("gate-evaluate", {
|
|
3554
|
+
return prependContextModeToBlock("gate-evaluate", base, loadPrompt("gate-evaluate", {
|
|
3496
3555
|
workingDirectory: base,
|
|
3497
3556
|
milestoneId: mid,
|
|
3498
3557
|
milestoneTitle: midTitle,
|
|
3499
3558
|
sliceId: sid,
|
|
3500
3559
|
sliceTitle: sTitle,
|
|
3501
|
-
slicePlanContent:
|
|
3560
|
+
slicePlanContent: planContent,
|
|
3502
3561
|
gateCount: String(pending.length),
|
|
3503
3562
|
gateList: gateListLines.join("\n"),
|
|
3504
3563
|
subagentPrompts: subagentSections.join("\n\n---\n\n"),
|
|
3505
|
-
});
|
|
3564
|
+
}));
|
|
3506
3565
|
}
|
|
3507
3566
|
export async function buildRewriteDocsPrompt(mid, midTitle, activeSlice, base, overrides) {
|
|
3508
3567
|
const sid = activeSlice?.id;
|