@opengsd/gsd-pi 1.1.1-dev.a5a2de8 → 1.1.1-dev.b2556262
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-recover.js +56 -1
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +18 -2
- package/dist/resources/extensions/browser-tools/engine/selection.js +1 -1
- package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/dist/resources/extensions/browser-tools/index.js +68 -24
- package/dist/resources/extensions/browser-tools/state.js +12 -0
- package/dist/resources/extensions/browser-tools/tools/session.js +3 -2
- package/dist/resources/extensions/browser-tools/utils.js +3 -3
- package/dist/resources/extensions/browser-tools/web-app-detect.js +52 -0
- package/dist/resources/extensions/gsd/auto/loop.js +4 -2
- package/dist/resources/extensions/gsd/auto/phases.js +87 -12
- package/dist/resources/extensions/gsd/auto/session.js +22 -1
- package/dist/resources/extensions/gsd/auto/workflow-kernel.js +1 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +81 -13
- package/dist/resources/extensions/gsd/auto-model-selection.js +154 -9
- package/dist/resources/extensions/gsd/auto-post-unit.js +19 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +26 -21
- package/dist/resources/extensions/gsd/auto-recovery.js +4 -2
- package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
- package/dist/resources/extensions/gsd/auto-start.js +1 -1
- package/dist/resources/extensions/gsd/auto-timers.js +24 -10
- package/dist/resources/extensions/gsd/auto.js +40 -15
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -3
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +192 -77
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
- package/dist/resources/extensions/gsd/closeout-wizard.js +32 -9
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +10 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -9
- package/dist/resources/extensions/gsd/commands-maintenance.js +93 -15
- package/dist/resources/extensions/gsd/commands-mcp-status.js +1 -1
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +2 -2
- package/dist/resources/extensions/gsd/config-overlay.js +1 -0
- package/dist/resources/extensions/gsd/context-masker.js +129 -5
- package/dist/resources/extensions/gsd/db-writer.js +35 -0
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +50 -1
- package/dist/resources/extensions/gsd/gsd-db.js +480 -172
- package/dist/resources/extensions/gsd/guided-flow.js +4 -1
- package/dist/resources/extensions/gsd/markdown-renderer.js +37 -53
- package/dist/resources/extensions/gsd/md-importer.js +38 -3
- package/dist/resources/extensions/gsd/migration-auto-check.js +126 -31
- package/dist/resources/extensions/gsd/parsers-legacy.js +23 -0
- package/dist/resources/extensions/gsd/planner-handoff.js +98 -0
- package/dist/resources/extensions/gsd/planning-path-scope.js +22 -4
- package/dist/resources/extensions/gsd/pre-execution-checks.js +10 -2
- package/dist/resources/extensions/gsd/preferences-models.js +111 -43
- package/dist/resources/extensions/gsd/preferences-types.js +13 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +68 -3
- package/dist/resources/extensions/gsd/preferences.js +4 -1
- package/dist/resources/extensions/gsd/prompts/gate-evaluate.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/refine-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +2 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/roadmap-slices.js +5 -1
- package/dist/resources/extensions/gsd/safety/content-validator.js +6 -4
- package/dist/resources/extensions/gsd/skill-manifest.js +12 -0
- package/dist/resources/extensions/gsd/source-observations.js +306 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +15 -8
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +33 -5
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-worker.js +34 -13
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +39 -14
- package/dist/resources/extensions/gsd/state-reconciliation/spawn-gate.js +4 -4
- package/dist/resources/extensions/gsd/state.js +7 -3
- package/dist/resources/extensions/gsd/tool-contract.js +15 -1
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +24 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +28 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +42 -11
- package/dist/resources/extensions/gsd/tools/plan-task.js +7 -1
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +62 -406
- package/dist/resources/extensions/gsd/uat-policy.js +130 -0
- package/dist/resources/extensions/gsd/uat-run.js +414 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +3 -4
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +38 -14
- package/dist/resources/extensions/gsd/verdict-parser.js +3 -8
- package/dist/resources/extensions/gsd/workflow-manifest.js +132 -5
- package/dist/resources/extensions/gsd/workflow-mcp.js +2 -3
- package/dist/resources/extensions/gsd/workflow-projections.js +8 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +26 -0
- package/dist/resources/extensions/gsd/worktree-reentry.js +96 -0
- package/dist/resources/extensions/gsd/worktree-state-projection.js +18 -17
- package/dist/resources/extensions/shared/gsd-browser-cli.js +6 -0
- package/dist/resources/extensions/subagent/agents.js +1 -0
- package/dist/resources/extensions/subagent/index.js +27 -12
- package/dist/resources/extensions/subagent/launch.js +7 -2
- 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 +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- 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/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 +1 -1
- package/dist/web/standalone/.next/server/middleware-build-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/node_modules/@gsd/native/dist/native.js +22 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/package.json +4 -4
- 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/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js +21 -23
- package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +3 -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 +25 -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.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +66 -12
- 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 +18 -11
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-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 +16 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/workflow-tools.js +1 -1
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/dist/native.js +22 -0
- 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 +174 -29
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +178 -54
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +8 -1
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/theme/themes.js +1 -1
- package/packages/pi-coding-agent/dist/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/utils.d.ts +11 -0
- package/packages/pi-tui/dist/utils.d.ts.map +1 -1
- package/packages/pi-tui/dist/utils.js +119 -6
- package/packages/pi-tui/dist/utils.js.map +1 -1
- package/packages/pi-tui/package.json +2 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/dist/theme/themes.js +1 -1
- package/pkg/dist/theme/themes.js.map +1 -1
- package/pkg/package.json +1 -1
- package/scripts/install/handoff.js +16 -3
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +21 -2
- package/src/resources/extensions/browser-tools/engine/selection.ts +1 -1
- package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/src/resources/extensions/browser-tools/index.ts +75 -27
- package/src/resources/extensions/browser-tools/state.ts +13 -0
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +2 -2
- package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +57 -0
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +37 -0
- package/src/resources/extensions/browser-tools/tests/web-app-detect.test.mjs +68 -0
- package/src/resources/extensions/browser-tools/tools/session.ts +4 -2
- package/src/resources/extensions/browser-tools/utils.ts +3 -3
- package/src/resources/extensions/browser-tools/web-app-detect.ts +63 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/loop.ts +4 -2
- package/src/resources/extensions/gsd/auto/phases.ts +89 -15
- package/src/resources/extensions/gsd/auto/session.ts +24 -1
- package/src/resources/extensions/gsd/auto/workflow-kernel.ts +1 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +117 -12
- package/src/resources/extensions/gsd/auto-model-selection.ts +190 -12
- package/src/resources/extensions/gsd/auto-post-unit.ts +20 -2
- package/src/resources/extensions/gsd/auto-prompts.ts +25 -22
- package/src/resources/extensions/gsd/auto-recovery.ts +22 -3
- package/src/resources/extensions/gsd/auto-runtime-state.ts +5 -0
- package/src/resources/extensions/gsd/auto-start.ts +1 -1
- package/src/resources/extensions/gsd/auto-timers.ts +25 -9
- package/src/resources/extensions/gsd/auto.ts +41 -14
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -3
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +250 -78
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
- package/src/resources/extensions/gsd/closeout-wizard.ts +47 -13
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +2 -17
- package/src/resources/extensions/gsd/commands-maintenance.ts +124 -13
- package/src/resources/extensions/gsd/commands-mcp-status.ts +1 -1
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +2 -2
- package/src/resources/extensions/gsd/config-overlay.ts +1 -0
- package/src/resources/extensions/gsd/context-masker.ts +152 -5
- package/src/resources/extensions/gsd/db-writer.ts +38 -0
- package/src/resources/extensions/gsd/docs/preferences-reference.md +50 -1
- package/src/resources/extensions/gsd/gsd-db.ts +564 -186
- package/src/resources/extensions/gsd/guided-flow.ts +4 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +44 -66
- package/src/resources/extensions/gsd/md-importer.ts +49 -2
- package/src/resources/extensions/gsd/migration-auto-check.ts +154 -34
- package/src/resources/extensions/gsd/parsers-legacy.ts +20 -0
- package/src/resources/extensions/gsd/planner-handoff.ts +149 -0
- package/src/resources/extensions/gsd/planning-path-scope.ts +22 -4
- package/src/resources/extensions/gsd/pre-execution-checks.ts +9 -2
- package/src/resources/extensions/gsd/preferences-models.ts +113 -43
- package/src/resources/extensions/gsd/preferences-types.ts +47 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +76 -2
- package/src/resources/extensions/gsd/preferences.ts +5 -0
- package/src/resources/extensions/gsd/prompts/gate-evaluate.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/refine-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +2 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/roadmap-slices.ts +6 -1
- package/src/resources/extensions/gsd/safety/content-validator.ts +8 -5
- package/src/resources/extensions/gsd/skill-manifest.ts +12 -0
- package/src/resources/extensions/gsd/source-observations.ts +402 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +20 -8
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +44 -5
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-worker.ts +39 -11
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +45 -15
- package/src/resources/extensions/gsd/state-reconciliation/spawn-gate.ts +4 -4
- package/src/resources/extensions/gsd/state.ts +7 -4
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +66 -4
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +299 -1
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +75 -3
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +22 -1
- package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +4 -0
- package/src/resources/extensions/gsd/tests/before-provider-context-management.test.ts +145 -0
- package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/closeout-wizard.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +26 -1
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +118 -0
- package/src/resources/extensions/gsd/tests/content-validator.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/context-masker.test.ts +56 -1
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +17 -2
- package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +1 -11
- package/src/resources/extensions/gsd/tests/gate-dispatch.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +62 -1
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +99 -2
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/planner-handoff.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +101 -1
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/schema-v21-sequence.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +162 -18
- package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/source-observations.test.ts +275 -0
- package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +43 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +76 -21
- package/src/resources/extensions/gsd/tests/thinking-level-resolution.test.ts +203 -0
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +170 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +306 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +77 -10
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +260 -5
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +511 -1
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +44 -0
- package/src/resources/extensions/gsd/tool-contract.ts +29 -1
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +41 -6
- package/src/resources/extensions/gsd/tools/complete-slice.ts +29 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +54 -12
- package/src/resources/extensions/gsd/tools/plan-task.ts +8 -1
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +71 -489
- package/src/resources/extensions/gsd/types.ts +1 -0
- package/src/resources/extensions/gsd/uat-policy.ts +191 -0
- package/src/resources/extensions/gsd/uat-run.ts +550 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +3 -4
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +38 -14
- package/src/resources/extensions/gsd/verdict-parser.ts +3 -10
- package/src/resources/extensions/gsd/workflow-manifest.ts +193 -7
- package/src/resources/extensions/gsd/workflow-mcp.ts +2 -3
- package/src/resources/extensions/gsd/workflow-projections.ts +9 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +32 -0
- package/src/resources/extensions/gsd/worktree-reentry.ts +103 -0
- package/src/resources/extensions/gsd/worktree-state-projection.ts +22 -22
- package/src/resources/extensions/shared/gsd-browser-cli.ts +6 -0
- package/src/resources/extensions/shared/tests/format-utils.test.ts +8 -3
- package/src/resources/extensions/subagent/agents.ts +4 -0
- package/src/resources/extensions/subagent/index.ts +28 -3
- package/src/resources/extensions/subagent/launch.ts +8 -0
- package/src/resources/extensions/subagent/tests/model-override.test.ts +31 -0
- /package/dist/web/standalone/.next/static/{9y3LeeR2uGr2yRj9RjY3D → tJOKQbQRO-9MiFDO8DIDS}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{9y3LeeR2uGr2yRj9RjY3D → tJOKQbQRO-9MiFDO8DIDS}/_ssgManifest.js +0 -0
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* and fallback chains.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { Api, Model } from "@gsd/pi-ai";
|
|
8
|
-
import { getProviderCapabilities } from "@gsd/pi-ai";
|
|
7
|
+
import type { Api, Model, ModelThinkingLevel } from "@gsd/pi-ai";
|
|
8
|
+
import { getProviderCapabilities, clampThinkingLevel } from "@gsd/pi-ai";
|
|
9
9
|
import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
|
|
10
10
|
import type { GSDPreferences } from "./preferences.js";
|
|
11
|
-
import { resolveModelWithFallbacksForUnit, resolveDynamicRoutingConfig } from "./preferences.js";
|
|
11
|
+
import { resolveModelWithFallbacksForUnit, resolveThinkingLevelForUnit, resolveDynamicRoutingConfig } from "./preferences.js";
|
|
12
12
|
import type { ComplexityTier } from "./complexity-classifier.js";
|
|
13
13
|
import { classifyUnitComplexity, extractTaskMetadata, tierLabel } from "./complexity-classifier.js";
|
|
14
14
|
import { resolveModelForComplexity, escalateTier, getEligibleModels, loadCapabilityOverrides, adjustToolSet, filterToolsForProvider } from "./model-router.js";
|
|
@@ -57,6 +57,12 @@ export interface ModelSelectionResult {
|
|
|
57
57
|
routing: { tier: string; modelDowngraded: boolean } | null;
|
|
58
58
|
/** Concrete model applied before dispatch so it can be restored after a fresh session. */
|
|
59
59
|
appliedModel: Model<Api> | null;
|
|
60
|
+
/**
|
|
61
|
+
* Reasoning effort applied for this dispatch after per-phase resolution,
|
|
62
|
+
* floor, and capability clamping (ADR-026). Null when no level was applied
|
|
63
|
+
* (e.g. no start level captured). Surfaced for metrics/telemetry.
|
|
64
|
+
*/
|
|
65
|
+
appliedThinkingLevel?: ReturnType<ExtensionAPI["getThinkingLevel"]> | null;
|
|
60
66
|
}
|
|
61
67
|
|
|
62
68
|
export interface PreferredModelConfig {
|
|
@@ -90,6 +96,32 @@ export function clearToolBaseline(pi: ExtensionAPI | object): void {
|
|
|
90
96
|
TOOL_BASELINE.delete(pi as unknown as object);
|
|
91
97
|
}
|
|
92
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Return the union of the pre-dispatch baseline tool set and the current live
|
|
101
|
+
* active tools, or just the live tools when no baseline has been recorded yet.
|
|
102
|
+
*
|
|
103
|
+
* Use this instead of `pi.getActiveTools()` anywhere you need the full tool
|
|
104
|
+
* surface for a preflight/routing check that runs BEFORE `selectAndApplyModel`
|
|
105
|
+
* restores the baseline — e.g. in `runDispatch` and `decideNextUnit`.
|
|
106
|
+
*
|
|
107
|
+
* The union is intentional:
|
|
108
|
+
* - Baseline covers tools that a prior unit's per-provider narrowing (hook
|
|
109
|
+
* overrides, Groq 128-tool cap, etc.) has removed from the live set.
|
|
110
|
+
* Those tools will be restored by `selectAndApplyModel` before dispatch, so
|
|
111
|
+
* dropping them from the preflight check would be a false negative.
|
|
112
|
+
* - Live set covers tools connected after the baseline was first captured
|
|
113
|
+
* (e.g. MCP servers attached mid-session or after a paused resume).
|
|
114
|
+
* Without the live merge, a stale baseline permanently hides newly
|
|
115
|
+
* connected MCP tools and prevents transport-preflight from clearing on
|
|
116
|
+
* resume (#477 follow-up).
|
|
117
|
+
*/
|
|
118
|
+
export function getToolBaselineSnapshot(pi: ExtensionAPI): string[] {
|
|
119
|
+
const live = typeof pi.getActiveTools === "function" ? pi.getActiveTools() : [];
|
|
120
|
+
const baseline = TOOL_BASELINE.get(pi as unknown as object);
|
|
121
|
+
if (baseline === undefined) return live;
|
|
122
|
+
return [...new Set([...baseline, ...live])];
|
|
123
|
+
}
|
|
124
|
+
|
|
93
125
|
/**
|
|
94
126
|
* Models eligible for the pre-dispatch policy gate. Prefer registry-available
|
|
95
127
|
* models; when that list is empty (common after worktree resume before registry
|
|
@@ -252,12 +284,103 @@ function restoreToolBaseline(pi: ExtensionAPI): void {
|
|
|
252
284
|
}
|
|
253
285
|
}
|
|
254
286
|
|
|
255
|
-
|
|
287
|
+
/**
|
|
288
|
+
* Apply the desired reasoning effort for the just-selected model, clamping to
|
|
289
|
+
* what the model actually supports (ADR-026). An unsupported level is never
|
|
290
|
+
* sent to the provider — it is clamped via `clampThinkingLevel` and the
|
|
291
|
+
* mismatch is surfaced once per (model, requested-level). Returns the level
|
|
292
|
+
* actually applied so callers can record it.
|
|
293
|
+
*/
|
|
294
|
+
export function applyThinkingLevelForModel(
|
|
256
295
|
pi: ExtensionAPI,
|
|
296
|
+
desired: ReturnType<ExtensionAPI["getThinkingLevel"]> | null | undefined,
|
|
297
|
+
model: Model<Api>,
|
|
298
|
+
ctx: ExtensionContext,
|
|
299
|
+
): ReturnType<ExtensionAPI["getThinkingLevel"]> | null | undefined {
|
|
300
|
+
if (!desired) return desired;
|
|
301
|
+
// Capability-clamp only when we have a bare string level AND the model
|
|
302
|
+
// advertises reasoning capability (`reasoning` is always present on real
|
|
303
|
+
// registry models). Richer host snapshot shapes (e.g. `{ effort: "high" }`)
|
|
304
|
+
// and partial model objects are applied verbatim — we never coerce an unknown
|
|
305
|
+
// shape into a string or guess capability we can't see.
|
|
306
|
+
if (typeof desired === "string" && model != null && typeof model === "object" && "reasoning" in model) {
|
|
307
|
+
const clamped = clampThinkingLevel(model, desired as ModelThinkingLevel) as ReturnType<ExtensionAPI["getThinkingLevel"]>;
|
|
308
|
+
pi.setThinkingLevel(clamped);
|
|
309
|
+
if (clamped !== desired) {
|
|
310
|
+
const key = `${model.provider}/${model.id}:${desired}`;
|
|
311
|
+
if (!_warnedThinkingClamp.has(key)) {
|
|
312
|
+
_warnedThinkingClamp.add(key);
|
|
313
|
+
ctx.ui.notify(
|
|
314
|
+
`Thinking level '${desired}' not supported by ${model.provider}/${model.id}; using '${clamped}'.`,
|
|
315
|
+
"warning",
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return clamped;
|
|
320
|
+
}
|
|
321
|
+
pi.setThinkingLevel(desired);
|
|
322
|
+
return desired;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/** Warn-once guard for capability clamps, keyed by `provider/id:requested`. */
|
|
326
|
+
const _warnedThinkingClamp = new Set<string>();
|
|
327
|
+
/** Warn-once guard for the execute-task floor punch-through advisory. */
|
|
328
|
+
let _warnedExecuteTaskFloorBypass = false;
|
|
329
|
+
|
|
330
|
+
type EffectiveThinkingLevel = ReturnType<ExtensionAPI["getThinkingLevel"]>;
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Ascending severity order for reasoning levels (matches @gsd/pi-agent-core
|
|
334
|
+
* `ThinkingLevel`). Used only for floor comparisons below.
|
|
335
|
+
*/
|
|
336
|
+
const THINKING_LEVEL_ORDER: readonly EffectiveThinkingLevel[] = [
|
|
337
|
+
"off",
|
|
338
|
+
"minimal",
|
|
339
|
+
"low",
|
|
340
|
+
"medium",
|
|
341
|
+
"high",
|
|
342
|
+
"xhigh",
|
|
343
|
+
] as EffectiveThinkingLevel[];
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Minimum reasoning level for code-writing units.
|
|
347
|
+
*
|
|
348
|
+
* `execute-task` is the only unit that edits source. With a low/minimal
|
|
349
|
+
* thinking level a model does not plan its edits and compensates by re-reading
|
|
350
|
+
* the same files dozens of times per task (measured: index.html read ~49× in a
|
|
351
|
+
* single task on a minimal-thinking model) and shelling out to `nl`/`sed` to
|
|
352
|
+
* re-locate code after every edit invalidates its line numbers. Flooring the
|
|
353
|
+
* level for this unit type removes that read/bash thrash. Planning, research,
|
|
354
|
+
* and lifecycle units are unaffected.
|
|
355
|
+
*/
|
|
356
|
+
const EXECUTE_TASK_MIN_THINKING_LEVEL: EffectiveThinkingLevel = "medium";
|
|
357
|
+
|
|
358
|
+
function thinkingLevelRank(level: EffectiveThinkingLevel): number {
|
|
359
|
+
const idx = THINKING_LEVEL_ORDER.indexOf(level);
|
|
360
|
+
return idx === -1 ? 0 : idx;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Raise (never lower) the thinking level for code-writing units to a sane
|
|
365
|
+
* floor. Returns the input unchanged for non-`execute-task` units, when no
|
|
366
|
+
* level was captured, or when the captured level already meets the floor.
|
|
367
|
+
*/
|
|
368
|
+
export function floorThinkingLevelForUnit(
|
|
369
|
+
unitType: string,
|
|
257
370
|
level: ReturnType<ExtensionAPI["getThinkingLevel"]> | null | undefined,
|
|
258
|
-
):
|
|
259
|
-
if (
|
|
260
|
-
|
|
371
|
+
): ReturnType<ExtensionAPI["getThinkingLevel"]> | null | undefined {
|
|
372
|
+
if (unitType !== "execute-task") return level;
|
|
373
|
+
if (!level) return level;
|
|
374
|
+
// Only act on the recognized string levels. Any other shape (e.g. a richer
|
|
375
|
+
// host snapshot object) is passed through untouched so we never coerce an
|
|
376
|
+
// unknown representation into a bare string the host can't apply.
|
|
377
|
+
if (!THINKING_LEVEL_ORDER.includes(level as EffectiveThinkingLevel)) {
|
|
378
|
+
return level;
|
|
379
|
+
}
|
|
380
|
+
if (thinkingLevelRank(level as EffectiveThinkingLevel) >= thinkingLevelRank(EXECUTE_TASK_MIN_THINKING_LEVEL)) {
|
|
381
|
+
return level;
|
|
382
|
+
}
|
|
383
|
+
return EXECUTE_TASK_MIN_THINKING_LEVEL;
|
|
261
384
|
}
|
|
262
385
|
|
|
263
386
|
export function resolvePreferredModelConfig(
|
|
@@ -328,6 +451,42 @@ export async function selectAndApplyModel(
|
|
|
328
451
|
autoModeStartThinkingLevel?: ReturnType<ExtensionAPI["getThinkingLevel"]> | null,
|
|
329
452
|
): Promise<ModelSelectionResult> {
|
|
330
453
|
const uokFlags = resolveUokFlags(prefs);
|
|
454
|
+
// Resolve reasoning effort for this dispatch (ADR-026). An explicit per-phase
|
|
455
|
+
// thinking config (inline `models.<phase>.thinking` or the separate `thinking`
|
|
456
|
+
// block) expresses hard user intent: it bypasses the execute-task floor and is
|
|
457
|
+
// honored verbatim, then capability-clamped per model at apply time below.
|
|
458
|
+
// With no explicit level, fall back to the auto-start session level and raise
|
|
459
|
+
// the code-writing floor — preserving prior behavior exactly. Recomputed per
|
|
460
|
+
// dispatch so neither the floor nor a phase override leaks to other units.
|
|
461
|
+
const explicitThinkingLevel =
|
|
462
|
+
resolveThinkingLevelForUnit(unitType) as ReturnType<ExtensionAPI["getThinkingLevel"]> | undefined;
|
|
463
|
+
const desiredThinkingLevel = explicitThinkingLevel
|
|
464
|
+
?? floorThinkingLevelForUnit(unitType, autoModeStartThinkingLevel);
|
|
465
|
+
if (explicitThinkingLevel) {
|
|
466
|
+
if (
|
|
467
|
+
unitType === "execute-task" &&
|
|
468
|
+
thinkingLevelRank(explicitThinkingLevel) < thinkingLevelRank(EXECUTE_TASK_MIN_THINKING_LEVEL) &&
|
|
469
|
+
!_warnedExecuteTaskFloorBypass
|
|
470
|
+
) {
|
|
471
|
+
_warnedExecuteTaskFloorBypass = true;
|
|
472
|
+
ctx.ui.notify(
|
|
473
|
+
`Explicit execution thinking '${explicitThinkingLevel}' is below the measured execute-task floor ` +
|
|
474
|
+
`(${EXECUTE_TASK_MIN_THINKING_LEVEL}); honoring it as configured. Low reasoning on code edits can ` +
|
|
475
|
+
`cause repeated file re-reads.`,
|
|
476
|
+
"warning",
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
} else if (
|
|
480
|
+
verbose &&
|
|
481
|
+
desiredThinkingLevel &&
|
|
482
|
+
desiredThinkingLevel !== autoModeStartThinkingLevel
|
|
483
|
+
) {
|
|
484
|
+
ctx.ui.notify(
|
|
485
|
+
`Thinking level raised to ${desiredThinkingLevel} for ${unitType} (was ${autoModeStartThinkingLevel ?? "unset"})`,
|
|
486
|
+
"info",
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
let appliedThinkingLevel: ReturnType<ExtensionAPI["getThinkingLevel"]> | null | undefined = null;
|
|
331
490
|
const effectiveSessionModelOverride = sessionModelOverride === undefined
|
|
332
491
|
? getSessionModelOverride(ctx.sessionManager.getSessionId())
|
|
333
492
|
: (sessionModelOverride ?? undefined);
|
|
@@ -673,7 +832,7 @@ export async function selectAndApplyModel(
|
|
|
673
832
|
const ok = await pi.setModel(model, { persist: false });
|
|
674
833
|
if (ok) {
|
|
675
834
|
appliedModel = model;
|
|
676
|
-
|
|
835
|
+
appliedThinkingLevel = applyThinkingLevelForModel(pi, desiredThinkingLevel, model, ctx);
|
|
677
836
|
|
|
678
837
|
// ADR-005: Adjust active tool set for the selected model's provider capabilities.
|
|
679
838
|
// Hard-filter incompatible tools, then let extensions override via adjust_tool_set hook.
|
|
@@ -733,7 +892,7 @@ export async function selectAndApplyModel(
|
|
|
733
892
|
const ok = await pi.setModel(model, { persist: false });
|
|
734
893
|
if (!ok) continue;
|
|
735
894
|
appliedModel = model;
|
|
736
|
-
|
|
895
|
+
appliedThinkingLevel = applyThinkingLevelForModel(pi, desiredThinkingLevel, model, ctx);
|
|
737
896
|
attemptedPolicyEligible = true;
|
|
738
897
|
if (verbose) {
|
|
739
898
|
ctx.ui.notify(
|
|
@@ -779,18 +938,37 @@ export async function selectAndApplyModel(
|
|
|
779
938
|
const fallbackOk = await pi.setModel(byId, { persist: false });
|
|
780
939
|
if (fallbackOk) {
|
|
781
940
|
appliedModel = byId;
|
|
782
|
-
|
|
941
|
+
appliedThinkingLevel = applyThinkingLevelForModel(pi, desiredThinkingLevel, byId, ctx);
|
|
783
942
|
}
|
|
784
943
|
}
|
|
785
944
|
} else {
|
|
786
945
|
appliedModel = startModel;
|
|
787
|
-
|
|
946
|
+
appliedThinkingLevel = applyThinkingLevelForModel(pi, desiredThinkingLevel, startModel, ctx);
|
|
788
947
|
}
|
|
789
948
|
}
|
|
790
949
|
}
|
|
791
950
|
}
|
|
792
951
|
|
|
793
|
-
|
|
952
|
+
// If no model branch applied a thinking level (e.g. interactive guided-flow
|
|
953
|
+
// with a `thinking:` block but no per-phase model and no start model), still
|
|
954
|
+
// honor an explicitly configured phase thinking level against the current
|
|
955
|
+
// session model. Only the explicit path runs here — the floored session
|
|
956
|
+
// default is intentionally left untouched so no-config interactive runs keep
|
|
957
|
+
// the user's /model thinking level. (ADR-026)
|
|
958
|
+
if (appliedThinkingLevel == null && explicitThinkingLevel && ctx.model) {
|
|
959
|
+
// Prefer the full registry model (carries reasoning capability so the level
|
|
960
|
+
// can be clamped); fall back to ctx.model. Always route through
|
|
961
|
+
// applyThinkingLevelForModel so the clamp runs whenever capability metadata
|
|
962
|
+
// exists — never a raw verbatim setThinkingLevel that bypasses it (ADR-026).
|
|
963
|
+
const current = resolveModelId(
|
|
964
|
+
`${ctx.model.provider}/${ctx.model.id}`,
|
|
965
|
+
ctx.modelRegistry?.getAvailable?.() ?? [],
|
|
966
|
+
ctx.model.provider,
|
|
967
|
+
) ?? (ctx.model as Model<Api>);
|
|
968
|
+
appliedThinkingLevel = applyThinkingLevelForModel(pi, explicitThinkingLevel, current, ctx);
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
return { routing, appliedModel, appliedThinkingLevel };
|
|
794
972
|
}
|
|
795
973
|
|
|
796
974
|
/**
|
|
@@ -1521,6 +1521,8 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
1521
1521
|
}
|
|
1522
1522
|
}
|
|
1523
1523
|
|
|
1524
|
+
let blockingContentViolation: string | null = null;
|
|
1525
|
+
|
|
1524
1526
|
// ── Safety harness: post-unit validation ──
|
|
1525
1527
|
try {
|
|
1526
1528
|
const { loadEffectiveGSDPreferences } = await import("./preferences.js");
|
|
@@ -1668,8 +1670,14 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
1668
1670
|
const artifactPath = resolveArtifactForContent(s.currentUnit.type, s.currentUnit.id, s.basePath);
|
|
1669
1671
|
const contentViolations = validateContent(s.currentUnit.type, artifactPath);
|
|
1670
1672
|
for (const v of contentViolations) {
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
+
if (v.severity === "error") {
|
|
1674
|
+
blockingContentViolation ??= v.reason;
|
|
1675
|
+
logError("safety", `content: ${v.reason}`);
|
|
1676
|
+
ctx.ui.notify(`Content validation: ${v.reason}`, "error");
|
|
1677
|
+
} else {
|
|
1678
|
+
logWarning("safety", `content: ${v.reason}`);
|
|
1679
|
+
ctx.ui.notify(`Content validation: ${v.reason}`, "warning");
|
|
1680
|
+
}
|
|
1673
1681
|
}
|
|
1674
1682
|
} catch (e) {
|
|
1675
1683
|
debugLog("postUnit", { phase: "safety-content-validation", error: String(e) });
|
|
@@ -1868,6 +1876,16 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
1868
1876
|
}
|
|
1869
1877
|
}
|
|
1870
1878
|
|
|
1879
|
+
if (blockingContentViolation && triggerArtifactVerified) {
|
|
1880
|
+
triggerArtifactVerified = false;
|
|
1881
|
+
debugLog("postUnit", {
|
|
1882
|
+
phase: "content-validation-blocked-artifact",
|
|
1883
|
+
unitType: s.currentUnit.type,
|
|
1884
|
+
unitId: s.currentUnit.id,
|
|
1885
|
+
reason: blockingContentViolation,
|
|
1886
|
+
});
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1871
1889
|
// When artifact verification fails for a unit type that has a known expected
|
|
1872
1890
|
// artifact, ask the caller to retry so it re-dispatches with failure context
|
|
1873
1891
|
// instead of blindly re-dispatching the same unit (#1571).
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { loadFile, parseContinue, parseSummary, loadActiveOverrides, formatOverridesSection, parseTaskPlanFile } from "./files.js";
|
|
13
|
-
import type { Override
|
|
14
|
-
import { hasVerdict,
|
|
13
|
+
import type { Override } from "./files.js";
|
|
14
|
+
import { hasVerdict, extractVerdict } from "./verdict-parser.js";
|
|
15
15
|
import { loadPrompt, inlineTemplate } from "./prompt-loader.js";
|
|
16
16
|
import {
|
|
17
17
|
resolveMilestoneFile, resolveSliceFile, resolveSlicePath,
|
|
@@ -42,11 +42,11 @@ import { logWarning } from "./workflow-logger.js";
|
|
|
42
42
|
import { inlineGraphSubgraph } from "./graph-context.js";
|
|
43
43
|
import { buildExtractionStepsBlock } from "./commands-extract-learnings.js";
|
|
44
44
|
import { classifyProject, type ProjectClassification } from "./detection.js";
|
|
45
|
-
import { hasBrowserRequiredText } from "./browser-evidence.js";
|
|
46
45
|
import { debugLog } from "./debug-logger.js";
|
|
47
46
|
import { buildSkillActivationBlock, buildSkillDiscoveryVars } from "./skill-activation.js";
|
|
48
47
|
import { findMilestoneIds } from "./milestone-ids.js";
|
|
49
|
-
import {
|
|
48
|
+
import { buildRunUatPresentationForType, RUN_UAT_TOOL_PRESENTATION_PLAN_ID } from "./tool-presentation-plan.js";
|
|
49
|
+
import { resolveEffectiveUatType, shouldDispatchUatForContent, type UatType } from "./uat-policy.js";
|
|
50
50
|
|
|
51
51
|
export { buildSkillActivationBlock, buildSkillDiscoveryVars };
|
|
52
52
|
|
|
@@ -286,19 +286,6 @@ function prependContextModeToBlock(
|
|
|
286
286
|
return `${contextMode}\n\n${block}`;
|
|
287
287
|
}
|
|
288
288
|
|
|
289
|
-
function resolveEffectiveUatType(content: string): UatType {
|
|
290
|
-
const uatType = getUatType(content);
|
|
291
|
-
if (uatType === "artifact-driven" && hasBrowserRequiredText(content)) {
|
|
292
|
-
return "browser-executable";
|
|
293
|
-
}
|
|
294
|
-
return uatType;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
function shouldDispatchUatForContent(content: string, prefs: GSDPreferences | undefined): boolean {
|
|
298
|
-
const uatType = resolveEffectiveUatType(content);
|
|
299
|
-
return !!prefs?.uat_dispatch || uatType !== "artifact-driven" || hasBrowserRequiredText(content);
|
|
300
|
-
}
|
|
301
|
-
|
|
302
289
|
// ─── Executor Constraints ─────────────────────────────────────────────────────
|
|
303
290
|
|
|
304
291
|
/**
|
|
@@ -3385,7 +3372,7 @@ export async function buildRunUatPrompt(
|
|
|
3385
3372
|
|
|
3386
3373
|
const uatResultPath = join(base, relSliceFile(base, mid, sliceId, "ASSESSMENT"));
|
|
3387
3374
|
const uatType = resolveEffectiveUatType(uatContent);
|
|
3388
|
-
const canonicalPresentation = JSON.stringify(
|
|
3375
|
+
const canonicalPresentation = JSON.stringify(buildRunUatPresentationForType(uatType), null, 2);
|
|
3389
3376
|
|
|
3390
3377
|
return loadPrompt("run-uat", {
|
|
3391
3378
|
workingDirectory: base,
|
|
@@ -3543,11 +3530,25 @@ export async function buildReassessRoadmapPrompt(
|
|
|
3543
3530
|
|
|
3544
3531
|
// ─── Reactive Execute Prompt ──────────────────────────────────────────────
|
|
3545
3532
|
|
|
3533
|
+
/**
|
|
3534
|
+
* Build the `with model: "…" and thinking: "…"` suffix injected into a prompt
|
|
3535
|
+
* that instructs the coordinator how to dispatch a `subagent` call. Either or
|
|
3536
|
+
* both may be absent (ADR-026 / #508).
|
|
3537
|
+
*/
|
|
3538
|
+
function subagentCallSuffix(model?: string, thinking?: string): string {
|
|
3539
|
+
const parts: string[] = [];
|
|
3540
|
+
if (model) parts.push(`model: "${model}"`);
|
|
3541
|
+
if (thinking) parts.push(`thinking: "${thinking}"`);
|
|
3542
|
+
return parts.length > 0 ? ` with ${parts.join(" and ")}` : "";
|
|
3543
|
+
}
|
|
3544
|
+
|
|
3546
3545
|
export async function buildReactiveExecutePrompt(
|
|
3547
3546
|
mid: string, midTitle: string, sid: string, sTitle: string,
|
|
3548
3547
|
readyTaskIds: string[], base: string,
|
|
3549
3548
|
subagentModel?: string,
|
|
3550
|
-
opts
|
|
3549
|
+
// Reasoning effort travels inside opts here (not as a positional param) so
|
|
3550
|
+
// existing positional `opts` callers don't shift (#508).
|
|
3551
|
+
opts?: { sessionContextWindow?: number; modelRegistry?: MinimalModelRegistry; sessionProvider?: string; subagentThinking?: string },
|
|
3551
3552
|
): Promise<string> {
|
|
3552
3553
|
const { loadSliceTaskIO, deriveTaskGraph, graphMetrics } = await import("./reactive-graph.js");
|
|
3553
3554
|
|
|
@@ -3640,7 +3641,7 @@ export async function buildReactiveExecutePrompt(
|
|
|
3640
3641
|
`When done, say: "Task ${tid} complete."`,
|
|
3641
3642
|
].join("\n");
|
|
3642
3643
|
|
|
3643
|
-
const modelSuffix = subagentModel
|
|
3644
|
+
const modelSuffix = subagentCallSuffix(subagentModel, opts?.subagentThinking);
|
|
3644
3645
|
subagentSections.push([
|
|
3645
3646
|
`### ${tid}: ${tTitle}`,
|
|
3646
3647
|
"",
|
|
@@ -3724,10 +3725,11 @@ export async function buildParallelResearchSlicesPrompt(
|
|
|
3724
3725
|
slices: Array<{ id: string; title: string }>,
|
|
3725
3726
|
basePath: string,
|
|
3726
3727
|
subagentModel?: string,
|
|
3728
|
+
subagentThinking?: string,
|
|
3727
3729
|
): Promise<string> {
|
|
3728
3730
|
// Build individual research-slice prompts for each slice
|
|
3729
3731
|
const subagentSections: string[] = [];
|
|
3730
|
-
const modelSuffix = subagentModel
|
|
3732
|
+
const modelSuffix = subagentCallSuffix(subagentModel, subagentThinking);
|
|
3731
3733
|
for (const slice of slices) {
|
|
3732
3734
|
const slicePrompt = await buildResearchSlicePrompt(mid, midTitle, slice.id, slice.title, basePath, { contextModeRenderMode: "nested" });
|
|
3733
3735
|
subagentSections.push([
|
|
@@ -3755,6 +3757,7 @@ export async function buildGateEvaluatePrompt(
|
|
|
3755
3757
|
mid: string, midTitle: string, sid: string, sTitle: string,
|
|
3756
3758
|
base: string,
|
|
3757
3759
|
subagentModel?: string,
|
|
3760
|
+
subagentThinking?: string,
|
|
3758
3761
|
): Promise<string> {
|
|
3759
3762
|
// Pull only the gates this turn actually owns (Q3/Q4). Filter via the
|
|
3760
3763
|
// registry so that scope:"slice" gates owned by other turns (Q8) can't
|
|
@@ -3811,7 +3814,7 @@ export async function buildGateEvaluatePrompt(
|
|
|
3811
3814
|
"- `findings`: detailed markdown findings (or empty if omitted)",
|
|
3812
3815
|
].join("\n");
|
|
3813
3816
|
|
|
3814
|
-
const modelSuffix = subagentModel
|
|
3817
|
+
const modelSuffix = subagentCallSuffix(subagentModel, subagentThinking);
|
|
3815
3818
|
subagentSections.push([
|
|
3816
3819
|
`### ${def.id}: ${def.question}`,
|
|
3817
3820
|
"",
|
|
@@ -15,7 +15,25 @@ import { appendEvent } from "./workflow-events.js";
|
|
|
15
15
|
import { atomicWriteSync } from "./atomic-write.js";
|
|
16
16
|
import { clearParseCache } from "./files.js";
|
|
17
17
|
import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from "./parsers-legacy.js";
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
isDbAvailable,
|
|
20
|
+
getTask,
|
|
21
|
+
getSlice,
|
|
22
|
+
getSliceTasks,
|
|
23
|
+
getPendingGatesForTurn,
|
|
24
|
+
updateTaskStatus,
|
|
25
|
+
updateSliceStatus,
|
|
26
|
+
insertSlice,
|
|
27
|
+
getMilestone,
|
|
28
|
+
getMilestoneSlices,
|
|
29
|
+
getLatestAssessmentByScope,
|
|
30
|
+
updateMilestoneStatus,
|
|
31
|
+
refreshOpenDatabaseFromDisk,
|
|
32
|
+
getCompletedMilestoneTaskFileHints,
|
|
33
|
+
getMilestoneCommitAttributionShas,
|
|
34
|
+
recordMilestoneCommitAttribution,
|
|
35
|
+
transaction,
|
|
36
|
+
} from "./gsd-db.js";
|
|
19
37
|
import { isValidationTerminal } from "./state.js";
|
|
20
38
|
import { getErrorMessage } from "./error-utils.js";
|
|
21
39
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
@@ -390,8 +408,9 @@ export function verifyExpectedArtifact(
|
|
|
390
408
|
if (gateIds.length === 0) return true;
|
|
391
409
|
|
|
392
410
|
try {
|
|
393
|
-
|
|
394
|
-
const
|
|
411
|
+
if (!isDbAvailable()) return false;
|
|
412
|
+
const pending = getPendingGatesForTurn(mid, sid, "gate-evaluate");
|
|
413
|
+
const pendingIds = new Set<string>(pending.map((g) => g.gate_id));
|
|
395
414
|
// All dispatched gates must no longer be pending
|
|
396
415
|
for (const gid of gateIds) {
|
|
397
416
|
if (pendingIds.has(gid)) return false;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// GSD auto-mode runtime state
|
|
2
2
|
import { AutoSession } from "./auto/session.js";
|
|
3
3
|
import type { CurrentUnit } from "./auto/session.js";
|
|
4
|
+
import type { SourceObservationStore } from "./source-observations.js";
|
|
4
5
|
import {
|
|
5
6
|
isDeterministicPolicyError,
|
|
6
7
|
isQueuedUserMessageSkip,
|
|
@@ -65,3 +66,7 @@ export function clearToolInvocationError(): void {
|
|
|
65
66
|
if (!autoSession.active) return;
|
|
66
67
|
autoSession.lastToolInvocationError = null;
|
|
67
68
|
}
|
|
69
|
+
|
|
70
|
+
export function getSourceObservationStore(): SourceObservationStore {
|
|
71
|
+
return autoSession.sourceObservations;
|
|
72
|
+
}
|
|
@@ -1557,7 +1557,7 @@ export async function bootstrapAutoSession(
|
|
|
1557
1557
|
s.autoStartTime = Date.now();
|
|
1558
1558
|
s.resourceVersionOnStart = readResourceVersion();
|
|
1559
1559
|
s.pendingQuickTasks = [];
|
|
1560
|
-
s.
|
|
1560
|
+
s.clearCurrentUnit();
|
|
1561
1561
|
s.currentMilestoneId ??=
|
|
1562
1562
|
strandedRecoveryAction?.milestoneId ??
|
|
1563
1563
|
(deepProjectStagePending ? null : state.activeMilestone?.id ?? null);
|
|
@@ -147,6 +147,15 @@ export function startUnitSupervision(sctx: SupervisionContext): void {
|
|
|
147
147
|
const softTimeoutMs = supervisionTimeouts.softTimeoutMs;
|
|
148
148
|
const idleTimeoutMs = supervisionTimeouts.idleTimeoutMs;
|
|
149
149
|
const hardTimeoutMs = supervisionTimeouts.hardTimeoutMs;
|
|
150
|
+
// A single hung tool gets its own short budget, NOT the general idle window:
|
|
151
|
+
// a long-but-progressing session is not idle, but a tool stuck for minutes
|
|
152
|
+
// is. Falls back to the idle window only if misconfigured to zero. The
|
|
153
|
+
// hung-tool budget is intentionally not scaled by task estimate — a stuck
|
|
154
|
+
// tool call is stuck regardless of how long the overall task should take.
|
|
155
|
+
const stalledToolTimeoutMs =
|
|
156
|
+
(supervisor.stalled_tool_timeout_minutes ?? 0) > 0
|
|
157
|
+
? supervisor.stalled_tool_timeout_minutes! * 60 * 1000
|
|
158
|
+
: idleTimeoutMs;
|
|
150
159
|
|
|
151
160
|
// ── 1. Soft timeout warning ──
|
|
152
161
|
s.wrapupWarningHandle = setTimeout(() => {
|
|
@@ -189,10 +198,13 @@ export function startUnitSupervision(sctx: SupervisionContext): void {
|
|
|
189
198
|
};
|
|
190
199
|
const runtime = readUnitRuntimeRecord(s.basePath, unitType, unitId);
|
|
191
200
|
if (!runtime) return;
|
|
192
|
-
if (Date.now() - runtime.lastProgressAt < idleTimeoutMs) return;
|
|
193
201
|
|
|
194
|
-
//
|
|
195
|
-
//
|
|
202
|
+
// In-flight tool handling runs on its own dedicated hung-tool budget,
|
|
203
|
+
// independent of the general idle gate below, so a genuinely stuck tool
|
|
204
|
+
// is caught in minutes instead of waiting out the (typically much longer)
|
|
205
|
+
// idle window (#2527, follow-up). A tool actively executing within budget
|
|
206
|
+
// is real progress, so refreshing lastProgressAt here also keeps the idle
|
|
207
|
+
// gate from firing during legitimate long-running tool calls.
|
|
196
208
|
let stalledToolDetected = false;
|
|
197
209
|
if (getInFlightToolCount() > 0) {
|
|
198
210
|
// User-interactive tools (ask_user_questions, secure_env_collect) block
|
|
@@ -206,25 +218,29 @@ export function startUnitSupervision(sctx: SupervisionContext): void {
|
|
|
206
218
|
}
|
|
207
219
|
const oldestStart = getOldestInFlightToolStart()!;
|
|
208
220
|
const toolAgeMs = Date.now() - oldestStart;
|
|
209
|
-
if (toolAgeMs <
|
|
221
|
+
if (toolAgeMs < stalledToolTimeoutMs) {
|
|
210
222
|
writeUnitRuntimeRecord(s.basePath, unitType, unitId, s.currentUnit.startedAt, {
|
|
211
223
|
lastProgressAt: Date.now(),
|
|
212
224
|
lastProgressKind: "tool-in-flight",
|
|
213
225
|
});
|
|
214
226
|
return;
|
|
215
227
|
}
|
|
216
|
-
// Tool has been in-flight longer than
|
|
217
|
-
// Clear the stale entries so subsequent ticks don't re-detect
|
|
218
|
-
// and set the flag so the filesystem-activity check
|
|
219
|
-
// override the stall verdict (#2527).
|
|
228
|
+
// Tool has been in-flight longer than the hung-tool budget — treat as
|
|
229
|
+
// hung. Clear the stale entries so subsequent ticks don't re-detect
|
|
230
|
+
// them, and set the flag so the idle gate and filesystem-activity check
|
|
231
|
+
// below do not override the stall verdict (#2527).
|
|
220
232
|
stalledToolDetected = true;
|
|
221
233
|
clearInFlightTools();
|
|
222
234
|
ctx.ui.notify(
|
|
223
|
-
`Stalled tool detected: a tool has been in-flight for ${Math.round(toolAgeMs / 60000)}min. Treating as hung — attempting idle recovery.`,
|
|
235
|
+
`Stalled tool detected: a tool has been in-flight for ${Math.round(toolAgeMs / 60000)}min (budget ${Math.round(stalledToolTimeoutMs / 60000)}min). Treating as hung — attempting idle recovery.`,
|
|
224
236
|
"warning",
|
|
225
237
|
);
|
|
226
238
|
}
|
|
227
239
|
|
|
240
|
+
// No hung tool — apply the general idle gate. A unit that has made
|
|
241
|
+
// meaningful progress within the idle window is not idle yet.
|
|
242
|
+
if (!stalledToolDetected && Date.now() - runtime.lastProgressAt < idleTimeoutMs) return;
|
|
243
|
+
|
|
228
244
|
// Check if the agent is producing work on disk.
|
|
229
245
|
// Skip this when a stalled tool was just detected — filesystem changes
|
|
230
246
|
// from earlier in the task should not override the stall verdict (#2527).
|