@opengsd/gsd-pi 1.1.1-dev.3ea310e → 1.1.1-dev.595401e
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/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +0 -1
- package/dist/resources/extensions/gsd/auto/phases.js +4 -3
- package/dist/resources/extensions/gsd/auto-dashboard.js +92 -17
- package/dist/resources/extensions/gsd/auto-dispatch.js +5 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +132 -8
- package/dist/resources/extensions/gsd/auto-prompts.js +68 -22
- package/dist/resources/extensions/gsd/auto-start.js +41 -12
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +2 -1
- package/dist/resources/extensions/gsd/auto.js +12 -5
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +82 -3
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +43 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +30 -9
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +16 -10
- package/dist/resources/extensions/gsd/browser-evidence.js +29 -2
- package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -1
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +3 -1
- package/dist/resources/extensions/gsd/commands-verdict.js +1 -1
- package/dist/resources/extensions/gsd/config-overlay.js +2 -1
- package/dist/resources/extensions/gsd/dashboard-overlay.js +21 -7
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +2 -2
- package/dist/resources/extensions/gsd/error-classifier.js +2 -1
- package/dist/resources/extensions/gsd/escalation.js +4 -4
- package/dist/resources/extensions/gsd/exec-sandbox.js +2 -0
- package/dist/resources/extensions/gsd/forensics.js +74 -2
- package/dist/resources/extensions/gsd/gsd-db.js +5 -2
- package/dist/resources/extensions/gsd/guided-flow.js +29 -68
- package/dist/resources/extensions/gsd/memory-store.js +4 -1
- package/dist/resources/extensions/gsd/post-unit-hooks.js +9 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +39 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
- package/dist/resources/extensions/gsd/prompts/forensics.md +61 -1
- package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +48 -24
- package/dist/resources/extensions/gsd/prompts/system.md +3 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
- package/dist/resources/extensions/gsd/rule-registry.js +428 -52
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +3 -0
- package/dist/resources/extensions/gsd/skill-activation.js +20 -3
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +18 -1
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +6 -0
- package/dist/resources/extensions/gsd/state.js +3 -3
- package/dist/resources/extensions/gsd/templates/plan.md +3 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +11 -1
- package/dist/resources/extensions/gsd/tools/exec-tool.js +109 -0
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +46 -16
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +403 -3
- package/dist/resources/extensions/gsd/unit-context-manifest.js +8 -3
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
- package/dist/resources/extensions/gsd/verdict-parser.js +59 -15
- package/dist/resources/extensions/gsd/verification-gate.js +72 -1
- package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +1 -1
- package/dist/resources/extensions/gsd/workflow-mcp.js +5 -1
- package/dist/rtk.d.ts +7 -1
- package/dist/rtk.js +27 -11
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
- 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 +7 -7
- 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/package.json +3 -2
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/workflow.d.ts +14 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +16 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/agent-session.d.ts +9 -0
- package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/agent-session.js +32 -0
- package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
- package/packages/gsd-agent-core/dist/index.d.ts +1 -0
- package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/index.js +1 -0
- package/packages/gsd-agent-core/dist/index.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts +2 -0
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.js +8 -2
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +7 -0
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +69 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
- package/packages/gsd-agent-core/dist/turn-latency.d.ts +47 -0
- package/packages/gsd-agent-core/dist/turn-latency.d.ts.map +1 -0
- package/packages/gsd-agent-core/dist/turn-latency.js +123 -0
- package/packages/gsd-agent-core/dist/turn-latency.js.map +1 -0
- package/packages/gsd-agent-core/package.json +6 -6
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +21 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +213 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +1 -0
- 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 +89 -31
- 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 +7 -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-command-handlers.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js +6 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
- package/packages/mcp-server/dist/remote-questions.js +23 -9
- package/packages/mcp-server/dist/remote-questions.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +84 -2
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +38 -0
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +5 -1
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +3 -0
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/api-registry.d.ts +2 -0
- package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
- package/packages/pi-ai/dist/api-registry.js +23 -0
- package/packages/pi-ai/dist/api-registry.js.map +1 -1
- package/packages/pi-ai/dist/image-models.generated.d.ts +15 -0
- package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/image-models.generated.js +15 -0
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +86 -18
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +108 -40
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/stream.js +6 -6
- package/packages/pi-ai/dist/stream.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/terminal.d.ts +1 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +8 -4
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +0 -1
- package/src/resources/extensions/gsd/auto/phases.ts +5 -3
- package/src/resources/extensions/gsd/auto-dashboard.ts +98 -18
- package/src/resources/extensions/gsd/auto-dispatch.ts +5 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +164 -7
- package/src/resources/extensions/gsd/auto-prompts.ts +102 -15
- package/src/resources/extensions/gsd/auto-start.ts +54 -14
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +2 -1
- package/src/resources/extensions/gsd/auto.ts +15 -4
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +89 -3
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +51 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +51 -14
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +21 -10
- package/src/resources/extensions/gsd/browser-evidence.ts +26 -2
- package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -1
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +4 -1
- package/src/resources/extensions/gsd/commands-verdict.ts +1 -1
- package/src/resources/extensions/gsd/config-overlay.ts +3 -1
- package/src/resources/extensions/gsd/dashboard-overlay.ts +28 -7
- package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +2 -2
- package/src/resources/extensions/gsd/error-classifier.ts +2 -1
- package/src/resources/extensions/gsd/escalation.ts +4 -4
- package/src/resources/extensions/gsd/exec-sandbox.ts +4 -0
- package/src/resources/extensions/gsd/forensics.ts +99 -5
- package/src/resources/extensions/gsd/gsd-db.ts +5 -2
- package/src/resources/extensions/gsd/guided-flow.ts +90 -82
- package/src/resources/extensions/gsd/memory-store.ts +4 -1
- package/src/resources/extensions/gsd/post-unit-hooks.ts +14 -1
- package/src/resources/extensions/gsd/preferences-types.ts +1 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +36 -0
- package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
- package/src/resources/extensions/gsd/prompts/forensics.md +61 -1
- package/src/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +48 -24
- package/src/resources/extensions/gsd/prompts/system.md +3 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
- package/src/resources/extensions/gsd/rule-registry.ts +558 -58
- package/src/resources/extensions/gsd/rule-types.ts +2 -0
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +3 -0
- package/src/resources/extensions/gsd/skill-activation.ts +20 -2
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +20 -0
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +6 -0
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +1 -0
- package/src/resources/extensions/gsd/state.ts +3 -3
- package/src/resources/extensions/gsd/templates/plan.md +3 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +156 -4
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +16 -3
- package/src/resources/extensions/gsd/tests/browser-evidence.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/commands-dispatcher-validation-block.test.ts +38 -3
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +6 -2
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/deep-planning-mode-dispatch.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/doctor-runtime-checks.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/escalation.test.ts +16 -27
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/forensics-prompt-rendering.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/forensics-tool-scope.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +40 -1
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +86 -0
- package/src/resources/extensions/gsd/tests/guided-flow.test.ts +12 -9
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +66 -10
- package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +39 -8
- package/src/resources/extensions/gsd/tests/new-milestone-discuss-routing.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +54 -7
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +53 -1
- package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +18 -1
- package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +191 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +84 -10
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +29 -6
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +29 -6
- package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +213 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +25 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +20 -2
- package/src/resources/extensions/gsd/tools/exec-tool.ts +130 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +46 -15
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +489 -3
- package/src/resources/extensions/gsd/types.ts +67 -4
- package/src/resources/extensions/gsd/unit-context-manifest.ts +14 -5
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
- package/src/resources/extensions/gsd/verdict-parser.ts +54 -13
- package/src/resources/extensions/gsd/verification-gate.ts +87 -1
- package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +1 -1
- package/src/resources/extensions/gsd/workflow-mcp.ts +5 -1
- /package/dist/web/standalone/.next/static/{xACmObbrDjwLriepRgaa9 → IDKjyRHLIaumjgonPcYiX}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{xACmObbrDjwLriepRgaa9 → IDKjyRHLIaumjgonPcYiX}/_ssgManifest.js +0 -0
|
@@ -277,7 +277,6 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
277
277
|
this.status.activeUnit = { unitType: decision.unitType, unitId: decision.unitId };
|
|
278
278
|
this.status.phase = "running";
|
|
279
279
|
this.lastAdvanceKey = nextKey;
|
|
280
|
-
this.lastFinalizedUnitKey = null;
|
|
281
280
|
this.bumpTransition();
|
|
282
281
|
|
|
283
282
|
await this.deps.runtime.journalTransition({
|
|
@@ -88,7 +88,7 @@ import { resolveManifest } from "../unit-context-manifest.js";
|
|
|
88
88
|
import { createWorktreeSafetyModule, type WorktreeSafetyResult } from "../worktree-safety.js";
|
|
89
89
|
import { isSuspiciousGhostCompletion } from "../auto-unit-closeout.js";
|
|
90
90
|
import { decideVerificationRetry, verificationRetryKey } from "./verification-retry-policy.js";
|
|
91
|
-
import { buildPhaseHandoffOutcome, setAutoOutcomeWidget } from "../auto-dashboard.js";
|
|
91
|
+
import { buildPhaseHandoffOutcome, setAutoActiveStatus, setAutoOutcomeWidget } from "../auto-dashboard.js";
|
|
92
92
|
import { getConsecutiveDispatchBlocker } from "../dispatch-guard.js";
|
|
93
93
|
import {
|
|
94
94
|
captureRootDirtySnapshot,
|
|
@@ -100,7 +100,7 @@ import { classifyError, isTransient } from "../error-classifier.js";
|
|
|
100
100
|
export const STUCK_WINDOW_SIZE = 6;
|
|
101
101
|
const STUCK_RECOVERY_ATTEMPTS_KEY = "stuck_recovery_attempts";
|
|
102
102
|
const ZERO_TOOL_PROVIDER_ERROR_PREFIX_RE =
|
|
103
|
-
/^(?:api error(?::|$|\s*\()|provider error(?::|$|\s*\()|request failed\b|(?:http\s*)?(?:429|500|502|503)\b|\b(?:econnreset|etimedout|econnrefused|epipe)\b|socket hang up\b|fetch failed\b|(?:network|connection|server) error(?::|$)|connection (?:reset|refused)(?::|$|\s+by\b)|dns\b.*(?:fail|error|timeout)|unexpected eof\b|stream idle timeout\b|partial response received\b|stream_exhausted\b|terminated(?::|$)|(?:connection|stream|request)\b.{0,40}\bterminated\b|other side closed\b|rate.?limit(?:ed| exceeded| reached| error)|too many requests\b|you(?:'ve| have) hit your limit\b|
|
|
103
|
+
/^(?:api error(?::|$|\s*\()|provider error(?::|$|\s*\()|request failed\b|(?:http\s*)?(?:429|500|502|503)\b|\b(?:econnreset|etimedout|econnrefused|epipe)\b|socket hang up\b|fetch failed\b|(?:network|connection|server) error(?::|$)|connection (?:reset|refused)(?::|$|\s+by\b)|dns\b.*(?:fail|error|timeout)|unexpected eof\b|stream idle timeout\b|partial response received\b|stream_exhausted\b|terminated(?::|$)|(?:connection|stream|request)\b.{0,40}\bterminated\b|other side closed\b|rate.?limit(?:ed| exceeded| reached| error)|too many requests\b|you(?:'ve| have) (?:hit|reached) your (?:\w+ )?limit\b|.*\b(?:usage|session|weekly|daily|monthly|quota) limit\b|limit\b.{0,40}\bresets?\b|out of extra usage\b|service.?unavailable\b|internal(?: server)? error(?::|$)|internal(?:[_-]server)?[_-]error\b|server[_-]error\b|(?:provider|server|api|model|codex|claude|openai|anthropic|gemini)\b.{0,80}\boverloaded\b|overloaded\b.{0,80}\b(?:provider|server|api|model)\b|context (?:window|length) exceed|context window exceed)/i;
|
|
104
104
|
const ZERO_TOOL_PROVIDER_ERROR_SIGNAL_RE =
|
|
105
105
|
/(?:\b(?:http|status(?: code)?|code|error:)\s*(?:429|500|502|503)\b|\b(?:api|provider) error\s*[:(]?\s*(?:429|500|502|503)\b|\b(?:typeerror|error):\s*(?:fetch failed\b|socket hang up\b|terminated(?::|$)|connection (?:reset|refused)(?::|$|\s+by\b)|(?:network|connection|server) error(?::|$)|stream idle timeout\b|partial response received\b|unexpected eof\b)|\b(?:server_error|api_error|stream_exhausted(?:_without_result)?)\b|\b(?:econnreset|etimedout|econnrefused|epipe)\b|context (?:window|length) exceed|context window exceed)/i;
|
|
106
106
|
|
|
@@ -114,6 +114,8 @@ function classifyZeroToolProviderMessage(message: string): ReturnType<typeof cla
|
|
|
114
114
|
return classifyError(firstLine);
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
export const _classifyZeroToolProviderMessageForTest = classifyZeroToolProviderMessage;
|
|
118
|
+
|
|
117
119
|
export function resolveDispatchRecoveryAttempts(
|
|
118
120
|
unitRecoveryCount: Map<string, number>,
|
|
119
121
|
unitType: string,
|
|
@@ -2092,7 +2094,7 @@ export async function runUnitPhase(
|
|
|
2092
2094
|
const nextDispatchCount = (s.unitDispatchCount.get(dispatchKey) ?? 0) + 1;
|
|
2093
2095
|
|
|
2094
2096
|
// Status bar (widget + preconditions deferred until after model selection — see #2899)
|
|
2095
|
-
ctx
|
|
2097
|
+
setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
|
|
2096
2098
|
if (mid)
|
|
2097
2099
|
deps.updateSliceProgressCache(s.basePath, mid, state.activeSlice?.id);
|
|
2098
2100
|
|
|
@@ -13,10 +13,11 @@ import type {
|
|
|
13
13
|
ExtensionCommandContext,
|
|
14
14
|
ReadonlyFooterDataProvider,
|
|
15
15
|
Theme,
|
|
16
|
+
ThemeColor,
|
|
16
17
|
} from "@gsd/pi-coding-agent";
|
|
17
18
|
import type { GSDState } from "./types.js";
|
|
18
19
|
import { getActiveHook } from "./post-unit-hooks.js";
|
|
19
|
-
import { getLedger } from "./metrics.js";
|
|
20
|
+
import { getLedger, getProjectTotals } from "./metrics.js";
|
|
20
21
|
import { getErrorMessage } from "./error-utils.js";
|
|
21
22
|
import { nativeIsRepo } from "./native-git-bridge.js";
|
|
22
23
|
import {
|
|
@@ -304,6 +305,40 @@ export function shouldRenderRoadmapProgress(
|
|
|
304
305
|
return !!progress && progress.total > 0;
|
|
305
306
|
}
|
|
306
307
|
|
|
308
|
+
function widgetGridLabel(theme: Theme, text: string, color: ThemeColor = "borderAccent"): string {
|
|
309
|
+
return theme.fg(color, theme.bold(text.toUpperCase()));
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function widgetGridColumn(content: string, width: number): string {
|
|
313
|
+
return padRightVisible(truncateToWidth(content, width, "…"), width);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function widgetGridColumns(theme: Theme, width: number, parts: string[]): string {
|
|
317
|
+
if (parts.length === 0) return "";
|
|
318
|
+
const gap = theme.fg("dim", " │ ");
|
|
319
|
+
const gapWidth = visibleWidth(gap) * (parts.length - 1);
|
|
320
|
+
const available = Math.max(parts.length * 8, width - gapWidth);
|
|
321
|
+
const base = Math.floor(available / parts.length);
|
|
322
|
+
let remaining = available - base * parts.length;
|
|
323
|
+
const columns = parts.map((part) => {
|
|
324
|
+
const columnWidth = base + (remaining > 0 ? 1 : 0);
|
|
325
|
+
remaining--;
|
|
326
|
+
return widgetGridColumn(part, columnWidth);
|
|
327
|
+
});
|
|
328
|
+
return truncateToWidth(columns.join(gap), width, "…");
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
function formatSmallWidgetSpend(): string {
|
|
332
|
+
const ledger = getLedger();
|
|
333
|
+
if (!ledger || ledger.units.length === 0) return "--";
|
|
334
|
+
|
|
335
|
+
const totals = getProjectTotals(ledger.units);
|
|
336
|
+
const parts: string[] = [];
|
|
337
|
+
if (totals.tokens.total > 0) parts.push(formatWidgetTokens(totals.tokens.total));
|
|
338
|
+
if (totals.cost > 0) parts.push(`$${totals.cost.toFixed(2)}`);
|
|
339
|
+
return parts.length > 0 ? parts.join(" · ") : "--";
|
|
340
|
+
}
|
|
341
|
+
|
|
307
342
|
// ─── ETA Estimation ──────────────────────────────────────────────────────────
|
|
308
343
|
|
|
309
344
|
/**
|
|
@@ -516,8 +551,9 @@ export const hideFooter = (_tui: unknown, theme: Theme, footerData: ReadonlyFoot
|
|
|
516
551
|
|
|
517
552
|
/** Widget display modes: full → small → min → off → full */
|
|
518
553
|
export type WidgetMode = "full" | "small" | "min" | "off";
|
|
554
|
+
export const DEFAULT_WIDGET_MODE: WidgetMode = "small";
|
|
519
555
|
const WIDGET_MODES: WidgetMode[] = ["full", "small", "min", "off"];
|
|
520
|
-
let widgetMode: WidgetMode =
|
|
556
|
+
let widgetMode: WidgetMode = DEFAULT_WIDGET_MODE;
|
|
521
557
|
let widgetModeInitialized = false;
|
|
522
558
|
let widgetModePreferencePath: string | null = null;
|
|
523
559
|
|
|
@@ -628,7 +664,7 @@ export function getWidgetMode(projectPath?: string, globalPath?: string): Widget
|
|
|
628
664
|
|
|
629
665
|
/** Test-only reset for widget mode caching. */
|
|
630
666
|
export function _resetWidgetModeForTests(): void {
|
|
631
|
-
widgetMode =
|
|
667
|
+
widgetMode = DEFAULT_WIDGET_MODE;
|
|
632
668
|
widgetModeInitialized = false;
|
|
633
669
|
widgetModePreferencePath = null;
|
|
634
670
|
}
|
|
@@ -648,6 +684,16 @@ export interface WidgetStateAccessors {
|
|
|
648
684
|
getCurrentDispatchedModelId(): string | null;
|
|
649
685
|
}
|
|
650
686
|
|
|
687
|
+
function clearAutoOutcomeWidget(ctx: ExtensionContext): void {
|
|
688
|
+
if (!ctx.hasUI) return;
|
|
689
|
+
ctx.ui.setWidget("gsd-outcome", undefined);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
export function setAutoActiveStatus(ctx: ExtensionContext, status: "auto" | "next"): void {
|
|
693
|
+
ctx.ui.setStatus("gsd-auto", status);
|
|
694
|
+
clearAutoOutcomeWidget(ctx);
|
|
695
|
+
}
|
|
696
|
+
|
|
651
697
|
export function updateProgressWidget(
|
|
652
698
|
ctx: ExtensionContext,
|
|
653
699
|
unitType: string,
|
|
@@ -673,7 +719,7 @@ export function updateProgressWidget(
|
|
|
673
719
|
ctx.ui.setStatus("gsd-step", undefined);
|
|
674
720
|
}
|
|
675
721
|
if (!accessors.isSessionSwitching()) {
|
|
676
|
-
ctx
|
|
722
|
+
clearAutoOutcomeWidget(ctx);
|
|
677
723
|
}
|
|
678
724
|
|
|
679
725
|
const verb = unitVerb(unitType);
|
|
@@ -732,6 +778,7 @@ export function updateProgressWidget(
|
|
|
732
778
|
logWarning("dashboard", `DB status update failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
733
779
|
}
|
|
734
780
|
}, 15_000);
|
|
781
|
+
progressRefreshTimer.unref?.();
|
|
735
782
|
|
|
736
783
|
return {
|
|
737
784
|
render(width: number): string[] {
|
|
@@ -824,29 +871,62 @@ export function updateProgressWidget(
|
|
|
824
871
|
return lines;
|
|
825
872
|
}
|
|
826
873
|
|
|
827
|
-
// ── Mode: small —
|
|
874
|
+
// ── Mode: small — dense horizontal grid ───────────────────────
|
|
828
875
|
if (widgetMode === "small") {
|
|
829
|
-
lines.
|
|
830
|
-
|
|
831
|
-
// Action line
|
|
832
|
-
const target = task ? `${task.id}: ${task.title}` : unitId;
|
|
833
|
-
const actionLeft = `${pad}${theme.fg("accent", "▸")} ${theme.fg("accent", verb)} ${theme.fg("text", target)}`;
|
|
834
|
-
lines.push(rightAlign(actionLeft, theme.fg("dim", phaseLabel), width));
|
|
876
|
+
lines.length = 0;
|
|
877
|
+
lines.push(...ui.bar());
|
|
835
878
|
|
|
836
|
-
// Progress bar
|
|
837
879
|
const roadmapSlices = mid ? getRoadmapSlicesSync() : null;
|
|
880
|
+
const unitLabel = unitId || [mid?.id, slice?.id, task?.id].filter(Boolean).join("/");
|
|
881
|
+
const statusParts = [
|
|
882
|
+
spinner,
|
|
883
|
+
theme.fg("success", modeTag),
|
|
884
|
+
theme.fg(stateColor, activeState),
|
|
885
|
+
];
|
|
886
|
+
if (runtimeSignal?.summary) {
|
|
887
|
+
statusParts.push(theme.fg(healthColor, healthSummary));
|
|
888
|
+
} else if (healthLevel !== "green") {
|
|
889
|
+
statusParts.push(`${theme.fg(healthColor, healthIcon)} ${theme.fg(healthColor, healthSummary)}`);
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
const timeValue = [elapsed, etaShort].filter(Boolean).join(" · ") || "--";
|
|
893
|
+
const rowOne = widgetGridColumns(theme, width, [
|
|
894
|
+
`${widgetGridLabel(theme, "status", "border")} ${statusParts.join(" ")}`,
|
|
895
|
+
`${widgetGridLabel(theme, "unit")} ${theme.fg("text", unitLabel || "--")}`,
|
|
896
|
+
`${widgetGridLabel(theme, "spend", "border")} ${theme.fg("dim", formatSmallWidgetSpend())}`,
|
|
897
|
+
`${widgetGridLabel(theme, "time")} ${theme.fg("dim", timeValue)}`,
|
|
898
|
+
]);
|
|
899
|
+
|
|
900
|
+
const target = task
|
|
901
|
+
? `${task.id}: ${task.title}`
|
|
902
|
+
: slice
|
|
903
|
+
? `${slice.id}: ${slice.title}`
|
|
904
|
+
: unitId;
|
|
905
|
+
|
|
906
|
+
let taskValue = task?.id ?? "--";
|
|
907
|
+
let sliceValue = slice?.id ?? "--";
|
|
838
908
|
if (shouldRenderRoadmapProgress(roadmapSlices)) {
|
|
839
909
|
const { done, total, activeSliceTasks } = roadmapSlices;
|
|
840
|
-
const barWidth = Math.max(
|
|
910
|
+
const barWidth = Math.max(4, Math.min(14, Math.floor(width * 0.12)));
|
|
841
911
|
const bar = renderProgressBar(theme, done, total, barWidth);
|
|
842
|
-
|
|
912
|
+
sliceValue = `${bar} ${theme.fg("text", `${done}/${total}`)}`;
|
|
843
913
|
if (activeSliceTasks && activeSliceTasks.total > 0) {
|
|
844
|
-
const
|
|
845
|
-
|
|
914
|
+
const taskNum = isHook
|
|
915
|
+
? Math.max(activeSliceTasks.done, 1)
|
|
916
|
+
: Math.min(activeSliceTasks.done + 1, activeSliceTasks.total);
|
|
917
|
+
taskValue = `${theme.fg("accent", `${taskNum}`)}${theme.fg("dim", `/${activeSliceTasks.total}`)}`;
|
|
846
918
|
}
|
|
847
|
-
lines.push(`${pad}${bar} ${meta}`);
|
|
848
919
|
}
|
|
849
920
|
|
|
921
|
+
const rowTwo = widgetGridColumns(theme, width, [
|
|
922
|
+
`${widgetGridLabel(theme, "phase", "border")} ${theme.fg("dim", unitType)}`,
|
|
923
|
+
`${widgetGridLabel(theme, "work")} ${theme.fg("text", target || "--")}`,
|
|
924
|
+
`${widgetGridLabel(theme, "task", "border")} ${taskValue}`,
|
|
925
|
+
`${widgetGridLabel(theme, "slice")} ${sliceValue}`,
|
|
926
|
+
]);
|
|
927
|
+
|
|
928
|
+
lines.push(rowOne);
|
|
929
|
+
lines.push(rowTwo);
|
|
850
930
|
lines.push(...ui.bar());
|
|
851
931
|
cachedLines = lines;
|
|
852
932
|
cachedWidth = width;
|
|
@@ -1003,7 +1083,7 @@ export function setCompletionProgressWidget(
|
|
|
1003
1083
|
): void {
|
|
1004
1084
|
if (!ctx.hasUI) return;
|
|
1005
1085
|
const widgetKey = "gsd-progress";
|
|
1006
|
-
ctx
|
|
1086
|
+
clearAutoOutcomeWidget(ctx);
|
|
1007
1087
|
|
|
1008
1088
|
if (typeof ctx.ui?.setHeader === "function") {
|
|
1009
1089
|
ctx.ui.setHeader(() => ({
|
|
@@ -622,6 +622,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
622
622
|
structuredQuestionsAvailable,
|
|
623
623
|
{ headless: !!process.env.GSD_HEADLESS },
|
|
624
624
|
),
|
|
625
|
+
pauseAfterDispatch: !process.env.GSD_HEADLESS,
|
|
625
626
|
};
|
|
626
627
|
},
|
|
627
628
|
},
|
|
@@ -772,6 +773,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
772
773
|
structuredQuestionsAvailable,
|
|
773
774
|
{ headless: !!process.env.GSD_HEADLESS },
|
|
774
775
|
),
|
|
776
|
+
pauseAfterDispatch: !process.env.GSD_HEADLESS,
|
|
775
777
|
};
|
|
776
778
|
},
|
|
777
779
|
},
|
|
@@ -805,6 +807,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
805
807
|
unitType: "discuss-project",
|
|
806
808
|
unitId: "PROJECT",
|
|
807
809
|
prompt: await buildDiscussProjectPrompt(basePath, structuredQuestionsAvailable),
|
|
810
|
+
pauseAfterDispatch: !process.env.GSD_HEADLESS,
|
|
808
811
|
};
|
|
809
812
|
},
|
|
810
813
|
},
|
|
@@ -826,6 +829,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
826
829
|
unitType: "discuss-requirements",
|
|
827
830
|
unitId: "REQUIREMENTS",
|
|
828
831
|
prompt: await buildDiscussRequirementsPrompt(basePath, structuredQuestionsAvailable),
|
|
832
|
+
pauseAfterDispatch: !process.env.GSD_HEADLESS,
|
|
829
833
|
};
|
|
830
834
|
},
|
|
831
835
|
},
|
|
@@ -940,6 +944,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
940
944
|
structuredQuestionsAvailable,
|
|
941
945
|
{ headless: !!process.env.GSD_HEADLESS },
|
|
942
946
|
),
|
|
947
|
+
pauseAfterDispatch: !process.env.GSD_HEADLESS,
|
|
943
948
|
};
|
|
944
949
|
},
|
|
945
950
|
},
|
|
@@ -55,8 +55,10 @@ import { parseRoadmap as parseLegacyRoadmap } from "./parsers-legacy.js";
|
|
|
55
55
|
import { consumeSignal } from "./session-status-io.js";
|
|
56
56
|
import {
|
|
57
57
|
checkPostUnitHooks,
|
|
58
|
+
consumeHookFailure,
|
|
58
59
|
isRetryPending,
|
|
59
60
|
consumeRetryTrigger,
|
|
61
|
+
consumeGateBlock,
|
|
60
62
|
persistHookState,
|
|
61
63
|
resolveHookArtifactPath,
|
|
62
64
|
} from "./post-unit-hooks.js";
|
|
@@ -394,6 +396,50 @@ function stripKnownIdPrefix(value: string | undefined | null, id: string): strin
|
|
|
394
396
|
return raw;
|
|
395
397
|
}
|
|
396
398
|
|
|
399
|
+
function parseReactiveBatchTaskIds(unitId: string): string[] {
|
|
400
|
+
const { task: batchPart } = parseUnitId(unitId);
|
|
401
|
+
if (!batchPart?.startsWith("reactive+")) return [];
|
|
402
|
+
|
|
403
|
+
const rawIds = batchPart
|
|
404
|
+
.slice("reactive+".length)
|
|
405
|
+
.split(",")
|
|
406
|
+
.map((taskId) => taskId.trim().toUpperCase())
|
|
407
|
+
.filter(Boolean);
|
|
408
|
+
|
|
409
|
+
const unique = new Set<string>();
|
|
410
|
+
for (const taskId of rawIds) {
|
|
411
|
+
unique.add(taskId);
|
|
412
|
+
}
|
|
413
|
+
return [...unique];
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function dedupePaths(values: string[]): string[] {
|
|
417
|
+
const seen = new Set<string>();
|
|
418
|
+
const result: string[] = [];
|
|
419
|
+
for (const value of values) {
|
|
420
|
+
if (!seen.has(value)) {
|
|
421
|
+
seen.add(value);
|
|
422
|
+
result.push(value);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return result;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
function getPlannedKeyFiles(tasks: Array<
|
|
429
|
+
{ expected_output?: string[]; files?: string[]; key_files?: string[] }
|
|
430
|
+
>): string[] {
|
|
431
|
+
return dedupePaths(
|
|
432
|
+
tasks.flatMap((taskRow) => [
|
|
433
|
+
...(taskRow.expected_output ?? []),
|
|
434
|
+
...(taskRow.files ?? []),
|
|
435
|
+
...(taskRow.key_files ?? []),
|
|
436
|
+
]),
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
export const _parseReactiveBatchTaskIdsForTest = parseReactiveBatchTaskIds;
|
|
441
|
+
export const _getPlannedKeyFilesForTest = getPlannedKeyFiles;
|
|
442
|
+
|
|
397
443
|
function resolveVerificationFailureMarkerPath(
|
|
398
444
|
unitType: string,
|
|
399
445
|
unitId: string,
|
|
@@ -481,6 +527,40 @@ async function buildTaskCommitContextForUnit(
|
|
|
481
527
|
};
|
|
482
528
|
}
|
|
483
529
|
|
|
530
|
+
async function buildReactiveTaskCommitContext(
|
|
531
|
+
_basePath: string,
|
|
532
|
+
unitId: string,
|
|
533
|
+
): Promise<TaskCommitContext | undefined> {
|
|
534
|
+
const { milestone: mid, slice: sid } = parseUnitId(unitId);
|
|
535
|
+
if (!mid || !sid || !isDbAvailable()) return undefined;
|
|
536
|
+
|
|
537
|
+
const batchTaskIds = parseReactiveBatchTaskIds(unitId);
|
|
538
|
+
if (batchTaskIds.length === 0) return undefined;
|
|
539
|
+
|
|
540
|
+
const milestone = getMilestone(mid);
|
|
541
|
+
const slice = getSlice(mid, sid);
|
|
542
|
+
const taskRows = batchTaskIds
|
|
543
|
+
.map((tid) => getTask(mid, sid, tid))
|
|
544
|
+
.filter((taskRow): taskRow is NonNullable<ReturnType<typeof getTask>> => taskRow !== null);
|
|
545
|
+
|
|
546
|
+
const keyFiles = getPlannedKeyFiles(taskRows);
|
|
547
|
+
if (taskRows.length === 0 || keyFiles.length === 0) return undefined;
|
|
548
|
+
|
|
549
|
+
const taskLabel = taskRows.map((row) => row.id).join(",");
|
|
550
|
+
|
|
551
|
+
return {
|
|
552
|
+
taskId: `${sid}/${taskLabel}`,
|
|
553
|
+
taskDisplayId: "reactive-batch",
|
|
554
|
+
taskTitle: `Reactive batch: ${taskLabel}`,
|
|
555
|
+
milestoneId: mid,
|
|
556
|
+
milestoneTitle: stripKnownIdPrefix(milestone?.title, mid),
|
|
557
|
+
sliceId: sid,
|
|
558
|
+
sliceTitle: stripKnownIdPrefix(slice?.title, sid),
|
|
559
|
+
oneLiner: `Reactive execute for ${taskLabel}`,
|
|
560
|
+
keyFiles,
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
|
|
484
564
|
async function runPostUnitGitHubSyncIfNeeded(
|
|
485
565
|
basePath: string,
|
|
486
566
|
unit: NonNullable<AutoSession["currentUnit"]>,
|
|
@@ -943,6 +1023,8 @@ export async function autoCommitUnit(
|
|
|
943
1023
|
|
|
944
1024
|
if (unitType === "execute-task") {
|
|
945
1025
|
taskContext = await buildTaskCommitContextForUnit(basePath, unitId);
|
|
1026
|
+
} else if (unitType === "reactive-execute") {
|
|
1027
|
+
taskContext = await buildReactiveTaskCommitContext(basePath, unitId);
|
|
946
1028
|
}
|
|
947
1029
|
|
|
948
1030
|
_resetHasChangesCache();
|
|
@@ -1005,6 +1087,21 @@ async function runCloseoutGitAction(
|
|
|
1005
1087
|
if (mid && sid && tid && isDbAvailable()) {
|
|
1006
1088
|
targetRepositories = getTask(mid, sid, tid)?.target_repositories;
|
|
1007
1089
|
}
|
|
1090
|
+
} else if (turnAction === "commit" && unit.type === "reactive-execute") {
|
|
1091
|
+
taskContext = await buildReactiveTaskCommitContext(s.basePath, unit.id);
|
|
1092
|
+
const { milestone: mid, slice: sid } = parseUnitId(unit.id);
|
|
1093
|
+
if (mid && sid && isDbAvailable()) {
|
|
1094
|
+
const repositories = new Set<string>();
|
|
1095
|
+
for (const tid of parseReactiveBatchTaskIds(unit.id)) {
|
|
1096
|
+
const taskRow = getTask(mid, sid, tid);
|
|
1097
|
+
for (const repoId of taskRow?.target_repositories ?? []) {
|
|
1098
|
+
repositories.add(repoId);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
if (repositories.size > 0) {
|
|
1102
|
+
targetRepositories = [...repositories];
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1008
1105
|
}
|
|
1009
1106
|
|
|
1010
1107
|
// Invalidate the nativeHasChanges cache before auto-commit (#1853).
|
|
@@ -1436,12 +1533,24 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
1436
1533
|
const { milestone: sMid, slice: sSid, task: sTid } = parseUnitId(s.currentUnit.id);
|
|
1437
1534
|
|
|
1438
1535
|
// File change validation (execute-task only, after unit execution)
|
|
1439
|
-
if (safetyConfig.file_change_validation && s.currentUnit.type === "execute-task" && sMid && sSid && sTid
|
|
1536
|
+
if (safetyConfig.file_change_validation && s.currentUnit.type === "execute-task" && sMid && sSid && sTid) {
|
|
1440
1537
|
try {
|
|
1441
|
-
const
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1538
|
+
const sliceTaskRows = isDbAvailable()
|
|
1539
|
+
? getSliceTasks(sMid, sSid).filter((t) => isClosedStatus(t.status) || t.id === sTid)
|
|
1540
|
+
: [];
|
|
1541
|
+
|
|
1542
|
+
if (sliceTaskRows.length > 0) {
|
|
1543
|
+
const expectedOutput = getPlannedKeyFiles(
|
|
1544
|
+
sliceTaskRows.map((taskRow) => ({
|
|
1545
|
+
expected_output: taskRow.expected_output,
|
|
1546
|
+
files: taskRow.files,
|
|
1547
|
+
})),
|
|
1548
|
+
);
|
|
1549
|
+
const plannedFiles = getPlannedKeyFiles(
|
|
1550
|
+
sliceTaskRows.map((taskRow) => ({
|
|
1551
|
+
files: taskRow.files,
|
|
1552
|
+
})),
|
|
1553
|
+
);
|
|
1445
1554
|
const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, safetyConfig.file_change_allowlist);
|
|
1446
1555
|
if (audit && audit.violations.length > 0) {
|
|
1447
1556
|
const warnings = audit.violations.filter(v => v.severity === "warning");
|
|
@@ -1455,6 +1564,30 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
1455
1564
|
);
|
|
1456
1565
|
}
|
|
1457
1566
|
}
|
|
1567
|
+
} else {
|
|
1568
|
+
const taskRow = getTask(sMid, sSid, sTid);
|
|
1569
|
+
if (taskRow) {
|
|
1570
|
+
const expectedOutput = taskRow.expected_output ?? [];
|
|
1571
|
+
const plannedFiles = taskRow.files ?? [];
|
|
1572
|
+
const audit = validateFileChanges(
|
|
1573
|
+
s.basePath,
|
|
1574
|
+
expectedOutput,
|
|
1575
|
+
plannedFiles,
|
|
1576
|
+
safetyConfig.file_change_allowlist,
|
|
1577
|
+
);
|
|
1578
|
+
if (audit && audit.violations.length > 0) {
|
|
1579
|
+
const warnings = audit.violations.filter(v => v.severity === "warning");
|
|
1580
|
+
for (const v of warnings) {
|
|
1581
|
+
logWarning("safety", `file-change: ${v.file} — ${v.reason}`);
|
|
1582
|
+
}
|
|
1583
|
+
if (warnings.length > 0) {
|
|
1584
|
+
ctx.ui.notify(
|
|
1585
|
+
`Safety: ${warnings.length} unexpected file change(s) outside task plan`,
|
|
1586
|
+
"warning",
|
|
1587
|
+
);
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1458
1591
|
}
|
|
1459
1592
|
} catch (e) {
|
|
1460
1593
|
debugLog("postUnit", { phase: "safety-file-change", error: String(e) });
|
|
@@ -2096,11 +2229,11 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
2096
2229
|
// ── Post-unit hooks ──
|
|
2097
2230
|
if (s.currentUnit && !s.stepMode) {
|
|
2098
2231
|
const hookUnit = checkPostUnitHooks(s.currentUnit.type, s.currentUnit.id, s.basePath);
|
|
2232
|
+
persistHookState(s.basePath);
|
|
2099
2233
|
if (hookUnit) {
|
|
2100
2234
|
if (s.currentUnit) {
|
|
2101
2235
|
await closeoutUnit(ctx, s.basePath, s.currentUnit.type, s.currentUnit.id, s.currentUnit.startedAt, buildSnapshotOpts(s.currentUnit.type, s.currentUnit.id));
|
|
2102
2236
|
}
|
|
2103
|
-
persistHookState(s.basePath);
|
|
2104
2237
|
|
|
2105
2238
|
return enqueueSidecar(
|
|
2106
2239
|
s, ctx,
|
|
@@ -2109,12 +2242,23 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
2109
2242
|
);
|
|
2110
2243
|
}
|
|
2111
2244
|
|
|
2245
|
+
const hookFailure = consumeHookFailure();
|
|
2246
|
+
if (hookFailure) {
|
|
2247
|
+
ctx.ui.notify(
|
|
2248
|
+
`Post-unit hook ${hookFailure.hookName} failed for ${hookFailure.unitId}: ${hookFailure.reason}. Pausing auto-mode.`,
|
|
2249
|
+
"warning",
|
|
2250
|
+
);
|
|
2251
|
+
await pauseAuto(ctx, pi);
|
|
2252
|
+
return "stopped";
|
|
2253
|
+
}
|
|
2254
|
+
|
|
2112
2255
|
// Check if a hook requested a retry of the trigger unit
|
|
2113
2256
|
if (isRetryPending()) {
|
|
2114
2257
|
const trigger = consumeRetryTrigger();
|
|
2115
2258
|
if (trigger) {
|
|
2259
|
+
persistHookState(s.basePath);
|
|
2116
2260
|
ctx.ui.notify(
|
|
2117
|
-
`Hook requested retry of ${trigger.unitType} ${trigger.unitId} — resetting
|
|
2261
|
+
`Hook requested retry of ${trigger.unitType} ${trigger.unitId} — resetting trigger unit state.`,
|
|
2118
2262
|
"info",
|
|
2119
2263
|
);
|
|
2120
2264
|
|
|
@@ -2168,6 +2312,19 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
2168
2312
|
// Fall through to normal dispatch — deriveState will re-derive the unit
|
|
2169
2313
|
}
|
|
2170
2314
|
}
|
|
2315
|
+
|
|
2316
|
+
const gateBlock = consumeGateBlock();
|
|
2317
|
+
if (gateBlock) {
|
|
2318
|
+
persistHookState(s.basePath);
|
|
2319
|
+
const verdict = gateBlock.verdict ? ` verdict=${gateBlock.verdict};` : "";
|
|
2320
|
+
const artifact = gateBlock.artifact ? ` artifact=${gateBlock.artifact};` : "";
|
|
2321
|
+
const message =
|
|
2322
|
+
`Post-unit gate "${gateBlock.hookName}" blocked ${gateBlock.triggerUnitType} ${gateBlock.triggerUnitId}:` +
|
|
2323
|
+
`${verdict}${artifact} ${gateBlock.reason}. Run /gsd status to inspect, then /gsd auto after recovery.`;
|
|
2324
|
+
ctx.ui.notify(message, "warning");
|
|
2325
|
+
await pauseAuto(ctx, pi);
|
|
2326
|
+
return "stopped";
|
|
2327
|
+
}
|
|
2171
2328
|
}
|
|
2172
2329
|
|
|
2173
2330
|
// ── Fast-path stop detection (#3487) ──
|