gsd-pi 2.77.0-dev.58d3d4d6c → 2.77.0-dev.cfd69e714
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/README.md +1 -1
- package/dist/claude-cli-check.js +5 -1
- package/dist/headless.js +49 -4
- package/dist/resource-loader.d.ts +40 -0
- package/dist/resource-loader.js +32 -13
- package/dist/resources/extensions/browser-tools/capture.js +9 -0
- package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
- package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
- package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
- package/dist/resources/extensions/browser-tools/tools/forms.js +5 -1
- package/dist/resources/extensions/browser-tools/tools/intent.js +5 -1
- package/dist/resources/extensions/claude-code-cli/readiness.js +5 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +481 -17
- package/dist/resources/extensions/gsd/auto/loop.js +43 -0
- package/dist/resources/extensions/gsd/auto/phases.js +15 -21
- package/dist/resources/extensions/gsd/auto/session.js +0 -2
- package/dist/resources/extensions/gsd/auto-dispatch.js +102 -24
- package/dist/resources/extensions/gsd/auto-model-selection.js +124 -4
- package/dist/resources/extensions/gsd/auto-post-unit.js +71 -64
- package/dist/resources/extensions/gsd/auto-prompts.js +329 -102
- package/dist/resources/extensions/gsd/auto-recovery.js +195 -23
- package/dist/resources/extensions/gsd/auto-start.js +34 -24
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +47 -7
- package/dist/resources/extensions/gsd/auto-worktree.js +122 -26
- package/dist/resources/extensions/gsd/auto.js +31 -20
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +9 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +209 -0
- package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +3 -6
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -3
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +127 -9
- package/dist/resources/extensions/gsd/component-loader.js +447 -0
- package/dist/resources/extensions/gsd/component-types.js +69 -0
- package/dist/resources/extensions/gsd/detection.js +49 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/gate-registry.js +2 -2
- package/dist/resources/extensions/gsd/git-constants.js +28 -1
- package/dist/resources/extensions/gsd/git-self-heal.js +27 -0
- package/dist/resources/extensions/gsd/git-service.js +126 -2
- package/dist/resources/extensions/gsd/gsd-db.js +6 -3
- package/dist/resources/extensions/gsd/guided-flow.js +17 -5
- package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
- package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
- package/dist/resources/extensions/gsd/model-router.js +6 -0
- package/dist/resources/extensions/gsd/native-git-bridge.js +34 -4
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/dist/resources/extensions/gsd/safety/git-checkpoint.js +11 -0
- package/dist/resources/extensions/gsd/service-tier.js +5 -2
- package/dist/resources/extensions/gsd/session-lock.js +19 -10
- package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +278 -8
- package/dist/resources/extensions/gsd/state.js +44 -33
- package/dist/resources/extensions/gsd/sync-lock.js +98 -42
- package/dist/resources/extensions/gsd/unit-context-composer.js +147 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +370 -0
- package/dist/resources/extensions/gsd/uok/gate-runner.js +53 -5
- package/dist/resources/extensions/gsd/workflow-mcp.js +6 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +34 -8
- package/dist/resources/extensions/mcp-client/index.js +3 -1
- package/dist/resources/extensions/ollama/index.js +5 -1
- package/dist/resources/extensions/remote-questions/manager.js +11 -5
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
- package/dist/web/standalone/.next/build-manifest.json +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/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +5 -5
- package/dist/web/standalone/.next/server/chunks/1926.js +1 -1
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- 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 +2 -3
- package/packages/daemon/src/logger.ts +4 -3
- package/packages/mcp-server/dist/server.d.ts +24 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +88 -87
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/src/mcp-server.test.ts +25 -3
- package/packages/mcp-server/src/readers/graph.test.ts +87 -15
- package/packages/mcp-server/src/secure-env-collect.test.ts +232 -237
- package/packages/mcp-server/src/server.ts +131 -105
- package/packages/mcp-server/src/workflow-tools.test.ts +80 -39
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
- package/packages/native/src/__tests__/module-compat.test.mjs +59 -27
- package/packages/native/src/__tests__/ps.test.mjs +14 -8
- package/packages/native/src/__tests__/stream-process.test.mjs +23 -2
- package/packages/native/src/__tests__/truncate.test.mjs +17 -2
- package/packages/pi-agent-core/src/agent-loop.test.ts +5 -15
- package/packages/pi-agent-core/src/agent.test.ts +96 -102
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/capability-patches.js +9 -2
- package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
- package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai.js +17 -0
- package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.test.js +43 -70
- package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
- package/packages/pi-ai/dist/models.test.js +36 -11
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- package/packages/pi-ai/scripts/generate-models.ts +44 -0
- package/packages/pi-ai/src/models/capability-patches.ts +10 -2
- package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
- package/packages/pi-ai/src/models/generated/openai.ts +17 -0
- package/packages/pi-ai/src/models.generated.test.ts +46 -73
- package/packages/pi-ai/src/models.test.ts +48 -11
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js +75 -12
- package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +61 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +30 -4
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +17 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +76 -18
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +2 -6
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +5 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts +18 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.js +18 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +20 -0
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -2
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -0
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +20 -13
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +18 -3
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +125 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +105 -13
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
- package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +58 -0
- package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +35 -4
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +20 -0
- package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +5 -1
- package/packages/pi-coding-agent/src/core/retry-handler.ts +2 -8
- package/packages/pi-coding-agent/src/core/retryable-error-regex.ts +18 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +35 -1
- package/packages/pi-coding-agent/src/index.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +146 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +20 -3
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +2 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +119 -13
- package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js +18 -8
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +128 -17
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +36 -12
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
- package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
- package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
- package/packages/pi-tui/dist/components/editor.d.ts +14 -0
- package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/editor.js +19 -0
- package/packages/pi-tui/dist/components/editor.js.map +1 -1
- package/packages/pi-tui/dist/components/image.test.js +6 -5
- package/packages/pi-tui/dist/components/image.test.js.map +1 -1
- package/packages/pi-tui/dist/editor-component.d.ts +2 -0
- package/packages/pi-tui/dist/editor-component.d.ts.map +1 -1
- package/packages/pi-tui/dist/editor-component.js.map +1 -1
- package/packages/pi-tui/src/__tests__/autocomplete.test.ts +24 -8
- package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
- package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +41 -12
- package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
- package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
- package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
- package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
- package/packages/pi-tui/src/components/editor.ts +22 -0
- package/packages/pi-tui/src/components/image.test.ts +10 -5
- package/packages/pi-tui/src/editor-component.ts +3 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/dist/rpc-client.test.js +101 -51
- package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
- package/packages/rpc-client/src/rpc-client.test.ts +109 -52
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/scripts/install.js +15 -1
- package/src/resources/extensions/browser-tools/capture.ts +12 -0
- package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
- package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
- package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
- package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
- package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
- package/src/resources/extensions/claude-code-cli/readiness.ts +5 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +518 -19
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +919 -75
- package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
- package/src/resources/extensions/github-sync/tests/templates.test.ts +33 -1
- package/src/resources/extensions/gsd/auto/loop.ts +47 -0
- package/src/resources/extensions/gsd/auto/phases.ts +16 -20
- package/src/resources/extensions/gsd/auto/session.ts +0 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +113 -24
- package/src/resources/extensions/gsd/auto-model-selection.ts +131 -4
- package/src/resources/extensions/gsd/auto-post-unit.ts +82 -73
- package/src/resources/extensions/gsd/auto-prompts.ts +330 -90
- package/src/resources/extensions/gsd/auto-recovery.ts +225 -24
- package/src/resources/extensions/gsd/auto-start.ts +54 -6
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +51 -7
- package/src/resources/extensions/gsd/auto-worktree.ts +130 -26
- package/src/resources/extensions/gsd/auto.ts +43 -22
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +9 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +221 -0
- package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +3 -7
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -3
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +158 -9
- package/src/resources/extensions/gsd/component-loader.ts +598 -0
- package/src/resources/extensions/gsd/component-types.ts +362 -0
- package/src/resources/extensions/gsd/detection.ts +58 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/gate-registry.ts +2 -2
- package/src/resources/extensions/gsd/git-constants.ts +30 -1
- package/src/resources/extensions/gsd/git-self-heal.ts +31 -0
- package/src/resources/extensions/gsd/git-service.ts +133 -2
- package/src/resources/extensions/gsd/gsd-db.ts +6 -3
- package/src/resources/extensions/gsd/guided-flow.ts +20 -5
- package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
- package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
- package/src/resources/extensions/gsd/model-router.ts +6 -0
- package/src/resources/extensions/gsd/native-git-bridge.ts +34 -4
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/src/resources/extensions/gsd/safety/git-checkpoint.ts +15 -0
- package/src/resources/extensions/gsd/service-tier.ts +5 -2
- package/src/resources/extensions/gsd/session-lock.ts +20 -10
- package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +309 -8
- package/src/resources/extensions/gsd/state.ts +49 -44
- package/src/resources/extensions/gsd/sync-lock.ts +97 -39
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +270 -0
- package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +341 -0
- package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +264 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +94 -289
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +742 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +61 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -197
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +16 -8
- package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
- package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +50 -1
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +91 -3
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +9 -105
- package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
- package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -57
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
- package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +144 -7
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -16
- package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
- package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +8 -37
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -62
- package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
- package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +6 -49
- package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -133
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +23 -24
- package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +75 -2
- package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
- package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
- package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
- package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +158 -0
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
- package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +164 -1
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +5 -5
- package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
- package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/test-helpers.test.ts +12 -61
- package/src/resources/extensions/gsd/tests/test-helpers.ts +21 -8
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +61 -1
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +258 -0
- package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -81
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -54
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +342 -277
- package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +37 -29
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
- package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
- package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +262 -0
- package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
- package/src/resources/extensions/gsd/types.ts +3 -3
- package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +574 -0
- package/src/resources/extensions/gsd/uok/gate-runner.ts +65 -5
- package/src/resources/extensions/gsd/workflow-mcp.ts +6 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +55 -7
- package/src/resources/extensions/mcp-client/index.ts +3 -1
- package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +70 -36
- package/src/resources/extensions/ollama/index.ts +5 -1
- package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +123 -15
- package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +206 -19
- package/src/resources/extensions/remote-questions/manager.ts +36 -4
- package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +200 -190
- package/src/resources/extensions/shared/tests/interview-preview.test.ts +11 -3
- package/src/resources/extensions/voice/tests/linux-ready.test.ts +129 -113
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +0 -2
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +0 -1
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +0 -289
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +0 -1
- package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +0 -363
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -144
- package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +0 -157
- package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +0 -107
- package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +0 -48
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -159
- package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
- package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +0 -75
- package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
- package/src/resources/extensions/gsd/tests/forensics-worktree-telemetry.test.ts +0 -145
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +0 -38
- package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +0 -73
- package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -130
- package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -43
- /package/dist/web/standalone/.next/static/{Cev5xrAYA3ZGTRLyjR2fX → SvCJDZPQW104bR1KnBQg1}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Cev5xrAYA3ZGTRLyjR2fX → SvCJDZPQW104bR1KnBQg1}/_ssgManifest.js +0 -0
|
@@ -45,6 +45,67 @@ const ROOT_STATE_FILES = [
|
|
|
45
45
|
// Back-sync (worktree → main) must NEVER overwrite the project root's copy
|
|
46
46
|
// because the project root is authoritative for preferences (#2684).
|
|
47
47
|
];
|
|
48
|
+
/**
|
|
49
|
+
* Pop a stash entry by tracking the unique marker embedded in its message so
|
|
50
|
+
* concurrent stash operations against the same project root cannot cause us to
|
|
51
|
+
* pop the wrong entry.
|
|
52
|
+
*
|
|
53
|
+
* If `stashMarker` is null or no longer present in the stash list (e.g. a
|
|
54
|
+
* concurrent process popped/dropped it), leaves the stash list untouched and
|
|
55
|
+
* returns null.
|
|
56
|
+
*
|
|
57
|
+
* Throws on pop failure so callers can handle conflict cases the same way
|
|
58
|
+
* they would with the prior `git stash pop` form. When throwing after a
|
|
59
|
+
* targeted pop attempt, the error is annotated with the targeted stash ref.
|
|
60
|
+
*
|
|
61
|
+
* (Issue #4980 HIGH-6)
|
|
62
|
+
*/
|
|
63
|
+
function popStashByRef(basePath, stashMarker) {
|
|
64
|
+
let popArg = null;
|
|
65
|
+
if (stashMarker) {
|
|
66
|
+
try {
|
|
67
|
+
const list = execFileSync("git", ["stash", "list", "--format=%gd%x00%s"], {
|
|
68
|
+
cwd: basePath,
|
|
69
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
70
|
+
encoding: "utf-8",
|
|
71
|
+
}).trim().split("\n").filter(Boolean);
|
|
72
|
+
for (const entry of list) {
|
|
73
|
+
const [ref, subject] = entry.split("\0");
|
|
74
|
+
if (ref && subject?.includes(stashMarker)) {
|
|
75
|
+
popArg = ref;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
logWarning("worktree", `stash list lookup failed; leaving stash untouched: ${err instanceof Error ? err.message : String(err)}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (!popArg) {
|
|
85
|
+
logWarning("worktree", "recorded stash entry could not be resolved; skipping automatic pop");
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
execFileSync("git", ["stash", "pop", popArg], {
|
|
90
|
+
cwd: basePath,
|
|
91
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
92
|
+
encoding: "utf-8",
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
if (err && typeof err === "object") {
|
|
97
|
+
err.stashRef = popArg;
|
|
98
|
+
}
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
return popArg;
|
|
102
|
+
}
|
|
103
|
+
function stashRefFromError(err) {
|
|
104
|
+
if (!err || typeof err !== "object")
|
|
105
|
+
return null;
|
|
106
|
+
const stashRef = err.stashRef;
|
|
107
|
+
return typeof stashRef === "string" && stashRef.length > 0 ? stashRef : null;
|
|
108
|
+
}
|
|
48
109
|
/**
|
|
49
110
|
* Check if two filesystem paths resolve to the same real location.
|
|
50
111
|
* Returns false if either path cannot be resolved (e.g. doesn't exist).
|
|
@@ -828,6 +889,27 @@ export function enterBranchModeForMilestone(basePath, milestoneId) {
|
|
|
828
889
|
const startPoint = integrationBranch ??
|
|
829
890
|
validatedPrefBranch ??
|
|
830
891
|
nativeDetectMainBranch(basePath);
|
|
892
|
+
// TOCTOU ancestry guard (Issue #4980 HIGH-3).
|
|
893
|
+
//
|
|
894
|
+
// The outer `branchExists` check at line 1012 is racy: a concurrent
|
|
895
|
+
// process (parallel-orchestrator worker, side-by-side `gsd` instance,
|
|
896
|
+
// or manual `git branch` invocation) may have created the branch with
|
|
897
|
+
// real commits between that check and this point. `nativeBranchForceReset`
|
|
898
|
+
// does `git branch -f`, which silently overwrites the branch ref —
|
|
899
|
+
// orphaning any commits not reachable from `startPoint`. Re-check
|
|
900
|
+
// immediately before the destructive call and refuse if the branch
|
|
901
|
+
// suddenly exists with non-ancestor commits.
|
|
902
|
+
//
|
|
903
|
+
// Note: under single-threaded execution this is rarely reached, but it
|
|
904
|
+
// is NOT dead code — it is the only barrier against a TOCTOU-induced
|
|
905
|
+
// commit loss in this code path.
|
|
906
|
+
const concurrentlyCreated = nativeBranchExists(basePath, branch);
|
|
907
|
+
if (concurrentlyCreated &&
|
|
908
|
+
!nativeIsAncestor(basePath, branch, startPoint)) {
|
|
909
|
+
throw new GSDError(GSD_GIT_ERROR, `Branch "${branch}" was created concurrently with commits not reachable from "${startPoint}". ` +
|
|
910
|
+
`Refusing to force-reset — would orphan prior work. ` +
|
|
911
|
+
`Resume the existing milestone or run \`git branch -D ${branch}\` to discard.`);
|
|
912
|
+
}
|
|
831
913
|
// nativeBranchForceReset creates (or resets) branch at startPoint,
|
|
832
914
|
// then checkout switches HEAD to it.
|
|
833
915
|
nativeBranchForceReset(basePath, branch, startPoint);
|
|
@@ -1345,7 +1427,17 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1345
1427
|
clearProjectRootStateFiles(originalBasePath_, milestoneId);
|
|
1346
1428
|
// 5. Checkout integration branch (skip if already current — avoids git error
|
|
1347
1429
|
// when main is already checked out in the project-root worktree, #757)
|
|
1430
|
+
//
|
|
1431
|
+
// Refuse to proceed if the project root is in detached HEAD state. Silently
|
|
1432
|
+
// running `nativeCheckoutBranch(mainBranch)` on a detached HEAD would
|
|
1433
|
+
// abandon the user's deliberately-checked-out commit (mid-bisect, reviewing
|
|
1434
|
+
// a tag, CI checkout-sha) without warning. (Issue #4980 HIGH-10)
|
|
1348
1435
|
const currentBranchAtBase = nativeGetCurrentBranch(originalBasePath_);
|
|
1436
|
+
if (!currentBranchAtBase || currentBranchAtBase.length === 0) {
|
|
1437
|
+
process.chdir(previousCwd);
|
|
1438
|
+
throw new GSDError(GSD_GIT_ERROR, `Project root is in detached HEAD state — cannot perform milestone merge. ` +
|
|
1439
|
+
`Checkout an integration branch (e.g. \`git checkout ${mainBranch}\`) before resuming.`);
|
|
1440
|
+
}
|
|
1349
1441
|
if (currentBranchAtBase !== mainBranch) {
|
|
1350
1442
|
nativeCheckoutBranch(originalBasePath_, mainBranch);
|
|
1351
1443
|
}
|
|
@@ -1534,6 +1626,11 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1534
1626
|
}
|
|
1535
1627
|
}
|
|
1536
1628
|
let stashed = false;
|
|
1629
|
+
// Embed a unique marker in the stash message so subsequent pop/drop targets
|
|
1630
|
+
// the entry we created, not whatever happens to be at stash@{0} (concurrent
|
|
1631
|
+
// milestone merges share the project-root stash list and can shift positions).
|
|
1632
|
+
// (Issue #4980 HIGH-6)
|
|
1633
|
+
let stashMarker = null;
|
|
1537
1634
|
try {
|
|
1538
1635
|
const status = execFileSync("git", ["status", "--porcelain"], {
|
|
1539
1636
|
cwd: originalBasePath_,
|
|
@@ -1541,7 +1638,8 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1541
1638
|
encoding: "utf-8",
|
|
1542
1639
|
}).trim();
|
|
1543
1640
|
if (status) {
|
|
1544
|
-
|
|
1641
|
+
stashMarker = `gsd-pre-merge:${milestoneId}:${process.pid}:${Date.now()}:${process.hrtime.bigint().toString(36)}`;
|
|
1642
|
+
execFileSync("git", ["stash", "push", "--include-untracked", "-m", `gsd: pre-merge stash for ${milestoneId} [${stashMarker}]`], { cwd: originalBasePath_, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" });
|
|
1545
1643
|
stashed = true;
|
|
1546
1644
|
}
|
|
1547
1645
|
}
|
|
@@ -1597,11 +1695,7 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1597
1695
|
// Pop stash before throwing so local work is not lost.
|
|
1598
1696
|
if (stashed) {
|
|
1599
1697
|
try {
|
|
1600
|
-
|
|
1601
|
-
cwd: originalBasePath_,
|
|
1602
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1603
|
-
encoding: "utf-8",
|
|
1604
|
-
});
|
|
1698
|
+
popStashByRef(originalBasePath_, stashMarker);
|
|
1605
1699
|
}
|
|
1606
1700
|
catch (err) { /* stash pop conflict is non-fatal */
|
|
1607
1701
|
logWarning("worktree", `git stash pop failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1669,11 +1763,7 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1669
1763
|
// Pop stash before throwing so local work is not lost (#2151).
|
|
1670
1764
|
if (stashed) {
|
|
1671
1765
|
try {
|
|
1672
|
-
|
|
1673
|
-
cwd: originalBasePath_,
|
|
1674
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1675
|
-
encoding: "utf-8",
|
|
1676
|
-
});
|
|
1766
|
+
popStashByRef(originalBasePath_, stashMarker);
|
|
1677
1767
|
}
|
|
1678
1768
|
catch (err) { /* stash pop conflict is non-fatal */
|
|
1679
1769
|
logWarning("worktree", `git stash pop failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1716,14 +1806,12 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1716
1806
|
// or the commit content. Conflict on pop is non-fatal — the stash entry is
|
|
1717
1807
|
// preserved and the user can resolve manually with `git stash pop`.
|
|
1718
1808
|
if (stashed) {
|
|
1809
|
+
let stashRefForDrop = null;
|
|
1719
1810
|
try {
|
|
1720
|
-
|
|
1721
|
-
cwd: originalBasePath_,
|
|
1722
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1723
|
-
encoding: "utf-8",
|
|
1724
|
-
});
|
|
1811
|
+
stashRefForDrop = popStashByRef(originalBasePath_, stashMarker);
|
|
1725
1812
|
}
|
|
1726
1813
|
catch (e) {
|
|
1814
|
+
stashRefForDrop = stashRefFromError(e);
|
|
1727
1815
|
logWarning("worktree", `git stash pop failed, attempting conflict resolution: ${e.message}`);
|
|
1728
1816
|
// Stash pop after squash merge can conflict on .gsd/ state files that
|
|
1729
1817
|
// diverged between branches. Left unresolved, these UU entries block
|
|
@@ -1751,25 +1839,33 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1751
1839
|
}
|
|
1752
1840
|
}
|
|
1753
1841
|
}
|
|
1754
|
-
if (nonGsdUU.length === 0) {
|
|
1842
|
+
if (gsdUU.length > 0 && nonGsdUU.length === 0) {
|
|
1755
1843
|
// All conflicts were .gsd/ files — safe to drop the stash
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1844
|
+
if (stashRefForDrop) {
|
|
1845
|
+
try {
|
|
1846
|
+
execFileSync("git", ["stash", "drop", stashRefForDrop], {
|
|
1847
|
+
cwd: originalBasePath_,
|
|
1848
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1849
|
+
encoding: "utf-8",
|
|
1850
|
+
});
|
|
1851
|
+
}
|
|
1852
|
+
catch (err) { /* stash may already be consumed */
|
|
1853
|
+
logWarning("worktree", `git stash drop failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1854
|
+
}
|
|
1762
1855
|
}
|
|
1763
|
-
|
|
1764
|
-
logWarning("worktree",
|
|
1856
|
+
else {
|
|
1857
|
+
logWarning("worktree", "recorded stash entry could not be resolved; skipping automatic drop");
|
|
1765
1858
|
}
|
|
1766
1859
|
}
|
|
1767
|
-
else {
|
|
1860
|
+
else if (nonGsdUU.length > 0) {
|
|
1768
1861
|
// Non-.gsd conflicts remain — leave stash for manual resolution
|
|
1769
1862
|
logWarning("reconcile", "Stash pop conflict on non-.gsd files after merge", {
|
|
1770
1863
|
files: nonGsdUU.join(", "),
|
|
1771
1864
|
});
|
|
1772
1865
|
}
|
|
1866
|
+
else {
|
|
1867
|
+
logWarning("worktree", "git stash pop failed without resolvable conflict files; leaving stash for manual recovery");
|
|
1868
|
+
}
|
|
1773
1869
|
}
|
|
1774
1870
|
}
|
|
1775
1871
|
// 9a-iii. Restore sheltered queued milestone directories (#2505).
|
|
@@ -24,9 +24,9 @@ import { acquireSessionLock, getSessionLockStatus, releaseSessionLock, updateSes
|
|
|
24
24
|
import { resolveAutoSupervisorConfig, loadEffectiveGSDPreferences, getIsolationMode, } from "./preferences.js";
|
|
25
25
|
import { sendDesktopNotification } from "./notifications.js";
|
|
26
26
|
import { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, } from "./auto-budget.js";
|
|
27
|
-
import { markToolStart as _markToolStart, markToolEnd as _markToolEnd, getOldestInFlightToolAgeMs as _getOldestInFlightToolAgeMs, clearInFlightTools, isToolInvocationError, isQueuedUserMessageSkip, } from "./auto-tool-tracking.js";
|
|
27
|
+
import { markToolStart as _markToolStart, markToolEnd as _markToolEnd, getOldestInFlightToolAgeMs as _getOldestInFlightToolAgeMs, clearInFlightTools, isToolInvocationError, isQueuedUserMessageSkip, isDeterministicPolicyError, } from "./auto-tool-tracking.js";
|
|
28
28
|
import { closeoutUnit } from "./auto-unit-closeout.js";
|
|
29
|
-
import { selectAndApplyModel, resolveModelId } from "./auto-model-selection.js";
|
|
29
|
+
import { selectAndApplyModel, resolveModelId, clearToolBaseline } from "./auto-model-selection.js";
|
|
30
30
|
import { resetRoutingHistory, recordOutcome } from "./routing-history.js";
|
|
31
31
|
import { resetHookState, runPreDispatchHooks, restoreHookState, clearPersistedHookState, } from "./post-unit-hooks.js";
|
|
32
32
|
import { runGSDDoctor, rebuildState } from "./doctor.js";
|
|
@@ -82,7 +82,7 @@ import { WorktreeResolver, } from "./worktree-resolver.js";
|
|
|
82
82
|
import { reorderForCaching } from "./prompt-ordering.js";
|
|
83
83
|
// ─── Session State ─────────────────────────────────────────────────────────
|
|
84
84
|
import { AutoSession, } from "./auto/session.js";
|
|
85
|
-
export {
|
|
85
|
+
export { STUB_RECOVERY_THRESHOLD, NEW_SESSION_TIMEOUT_MS, } from "./auto/session.js";
|
|
86
86
|
// ── ENCAPSULATION INVARIANT ─────────────────────────────────────────────────
|
|
87
87
|
// ALL mutable auto-mode state lives in the AutoSession class (auto/session.ts).
|
|
88
88
|
// This file must NOT declare module-level `let` or `var` variables for state.
|
|
@@ -163,6 +163,13 @@ function normalizeSessionFilePath(raw) {
|
|
|
163
163
|
return null;
|
|
164
164
|
return candidate;
|
|
165
165
|
}
|
|
166
|
+
function synthesizePausedSessionRecovery(basePath, unitType, unitId, sessionFile) {
|
|
167
|
+
const activityDir = join(gsdRoot(basePath), "activity");
|
|
168
|
+
return synthesizeCrashRecovery(basePath, unitType, unitId, sessionFile, activityDir);
|
|
169
|
+
}
|
|
170
|
+
export function _synthesizePausedSessionRecoveryForTest(basePath, unitType, unitId, sessionFile) {
|
|
171
|
+
return synthesizePausedSessionRecovery(basePath, unitType, unitId, sessionFile);
|
|
172
|
+
}
|
|
166
173
|
export function startAutoDetached(ctx, pi, base, verboseMode, options) {
|
|
167
174
|
void startAuto(ctx, pi, base, verboseMode, options).catch((err) => {
|
|
168
175
|
const message = getErrorMessage(err);
|
|
@@ -320,13 +327,15 @@ export function markToolEnd(toolCallId) {
|
|
|
320
327
|
/**
|
|
321
328
|
* Record a tool invocation error on the current session (#2883).
|
|
322
329
|
* Called from tool_execution_end when a GSD tool fails with isError.
|
|
323
|
-
*
|
|
324
|
-
* (malformed/truncated JSON)
|
|
330
|
+
* Stores the error if it matches:
|
|
331
|
+
* - tool-invocation-error pattern (malformed/truncated JSON)
|
|
332
|
+
* - queued-user-message skip pattern
|
|
333
|
+
* - deterministic policy rejection (#4973, e.g. context_write_blocked)
|
|
325
334
|
*/
|
|
326
335
|
export function recordToolInvocationError(toolName, errorMsg) {
|
|
327
336
|
if (!s.active)
|
|
328
337
|
return;
|
|
329
|
-
if (isToolInvocationError(errorMsg) || isQueuedUserMessageSkip(errorMsg)) {
|
|
338
|
+
if (isToolInvocationError(errorMsg) || isQueuedUserMessageSkip(errorMsg) || isDeterministicPolicyError(errorMsg)) {
|
|
330
339
|
s.lastToolInvocationError = `${toolName}: ${errorMsg}`;
|
|
331
340
|
}
|
|
332
341
|
}
|
|
@@ -813,6 +822,12 @@ export async function stopAuto(ctx, pi, reason) {
|
|
|
813
822
|
initHealthWidget(ctx);
|
|
814
823
|
restoreProjectRootEnv();
|
|
815
824
|
restoreMilestoneLockEnv();
|
|
825
|
+
// Drop the active-tool baseline so a subsequent /gsd auto run on the
|
|
826
|
+
// same `pi` instance recaptures from the live tool set rather than
|
|
827
|
+
// restoring this session's snapshot and silently undoing any tool
|
|
828
|
+
// changes the user made between sessions (#4959 / CodeRabbit).
|
|
829
|
+
if (pi)
|
|
830
|
+
clearToolBaseline(pi);
|
|
816
831
|
// Reset all session state in one call
|
|
817
832
|
s.reset();
|
|
818
833
|
}
|
|
@@ -1060,6 +1075,15 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
1060
1075
|
debugLog("startAuto", { phase: "already-active", skipping: true });
|
|
1061
1076
|
return;
|
|
1062
1077
|
}
|
|
1078
|
+
// On a *fresh* start, drop any stale active-tool baseline left by a prior
|
|
1079
|
+
// auto session that didn't run stopAuto cleanly. Skip on resume: pauseAuto
|
|
1080
|
+
// leaves the last provider-trimmed active tools in place, so clearing here
|
|
1081
|
+
// would let the next selectAndApplyModel recapture that already-narrowed
|
|
1082
|
+
// set as the new baseline — exactly the cross-unit poisoning this PR is
|
|
1083
|
+
// fixing (#4959 / CodeRabbit Major). The pre-pause baseline survives in
|
|
1084
|
+
// the WeakMap keyed by `pi`.
|
|
1085
|
+
if (!s.paused)
|
|
1086
|
+
clearToolBaseline(pi);
|
|
1063
1087
|
const requestedStepMode = options?.step ?? false;
|
|
1064
1088
|
const interruptedAssessment = options?.interrupted ?? null;
|
|
1065
1089
|
if (options?.milestoneLock !== undefined) {
|
|
@@ -1217,18 +1241,6 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
1217
1241
|
ctx.ui.notify(`Cannot resume: ${resumeLock.reason}`, "error");
|
|
1218
1242
|
return;
|
|
1219
1243
|
}
|
|
1220
|
-
// Lock acquired — now safe to delete the pause file
|
|
1221
|
-
if (s.pausedSessionFile) {
|
|
1222
|
-
try {
|
|
1223
|
-
unlinkSync(s.pausedSessionFile);
|
|
1224
|
-
}
|
|
1225
|
-
catch (err) {
|
|
1226
|
-
if (err.code !== "ENOENT") {
|
|
1227
|
-
logWarning("session", `pause file cleanup failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
s.pausedSessionFile = null;
|
|
1231
|
-
}
|
|
1232
1244
|
s.paused = false;
|
|
1233
1245
|
s.active = true;
|
|
1234
1246
|
s.verbose = verboseMode;
|
|
@@ -1317,8 +1329,7 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
1317
1329
|
}
|
|
1318
1330
|
invalidateAllCaches();
|
|
1319
1331
|
if (s.pausedSessionFile) {
|
|
1320
|
-
const
|
|
1321
|
-
const recovery = synthesizeCrashRecovery(s.basePath, s.currentUnit?.type ?? s.pausedUnitType ?? "unknown", s.currentUnit?.id ?? s.pausedUnitId ?? "unknown", s.pausedSessionFile ?? undefined, activityDir);
|
|
1332
|
+
const recovery = synthesizePausedSessionRecovery(s.basePath, s.currentUnit?.type ?? s.pausedUnitType ?? "unknown", s.currentUnit?.id ?? s.pausedUnitId ?? "unknown", s.pausedSessionFile);
|
|
1322
1333
|
if (recovery && recovery.trace.toolCallCount > 0) {
|
|
1323
1334
|
s.pendingCrashRecovery = recovery.prompt;
|
|
1324
1335
|
ctx.ui.notify(`Recovered ${recovery.trace.toolCallCount} tool calls from paused session. Resuming with context.`, "info");
|
|
@@ -12,7 +12,15 @@ import { classifyError, createRetryState, resetRetryState, isTransient, } from "
|
|
|
12
12
|
import { blockModel, isModelBlocked } from "../blocked-models.js";
|
|
13
13
|
const retryState = createRetryState();
|
|
14
14
|
const MAX_NETWORK_RETRIES = 2;
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Cap on auto-resume attempts for sustained transient-provider errors.
|
|
17
|
+
*
|
|
18
|
+
* Exported so tests assert against the shared constant instead of
|
|
19
|
+
* regex-scraping the source literal (see #4837). Raising this value to
|
|
20
|
+
* handle longer provider overloads should update the single constant; the
|
|
21
|
+
* test in provider-errors.test.ts consumes it directly.
|
|
22
|
+
*/
|
|
23
|
+
export const MAX_TRANSIENT_AUTO_RESUMES = 8;
|
|
16
24
|
/**
|
|
17
25
|
* Reset the module-level retry state so a resumed auto-session starts fresh.
|
|
18
26
|
* Called by provider-error-resume.ts before startAuto() — without this, the
|
|
@@ -462,6 +462,9 @@ export function registerDbTools(pi) {
|
|
|
462
462
|
definitionOfDone: Type.Optional(Type.Array(Type.String(), { description: "Definition of done bullets" })),
|
|
463
463
|
requirementCoverage: Type.Optional(Type.String({ description: "Requirement coverage text" })),
|
|
464
464
|
boundaryMapMarkdown: Type.Optional(Type.String({ description: "Boundary map markdown block" })),
|
|
465
|
+
// Single-writer v3 audit trail (Stream 2): caller-provided actor identity + causation.
|
|
466
|
+
actorName: Type.Optional(Type.String({ description: "Caller-provided actor identity for the audit trail (e.g. 'executor-01', 'gsd-orchestrator')" })),
|
|
467
|
+
triggerReason: Type.Optional(Type.String({ description: "Caller-provided reason this action was triggered (e.g. 'plan-phase complete')" })),
|
|
465
468
|
}),
|
|
466
469
|
execute: planMilestoneExecute,
|
|
467
470
|
};
|
|
@@ -503,6 +506,9 @@ export function registerDbTools(pi) {
|
|
|
503
506
|
proofLevel: Type.Optional(Type.String({ description: "Slice proof level" })),
|
|
504
507
|
integrationClosure: Type.Optional(Type.String({ description: "Slice integration closure" })),
|
|
505
508
|
observabilityImpact: Type.Optional(Type.String({ description: "Slice observability impact" })),
|
|
509
|
+
// Single-writer v3 audit trail (Stream 2): caller-provided actor identity + causation.
|
|
510
|
+
actorName: Type.Optional(Type.String({ description: "Caller-provided actor identity for the audit trail (e.g. 'executor-01', 'gsd-orchestrator')" })),
|
|
511
|
+
triggerReason: Type.Optional(Type.String({ description: "Caller-provided reason this action was triggered (e.g. 'plan-phase complete')" })),
|
|
506
512
|
}),
|
|
507
513
|
execute: planSliceExecute,
|
|
508
514
|
};
|
|
@@ -569,6 +575,9 @@ export function registerDbTools(pi) {
|
|
|
569
575
|
inputs: Type.Array(Type.String(), { description: "Input files or references" }),
|
|
570
576
|
expectedOutput: Type.Array(Type.String(), { description: "Expected output files or artifacts" }),
|
|
571
577
|
observabilityImpact: Type.Optional(Type.String({ description: "Task observability impact" })),
|
|
578
|
+
// Single-writer v3 audit trail (Stream 2): caller-provided actor identity + causation.
|
|
579
|
+
actorName: Type.Optional(Type.String({ description: "Caller-provided actor identity for the audit trail (e.g. 'executor-01', 'gsd-orchestrator')" })),
|
|
580
|
+
triggerReason: Type.Optional(Type.String({ description: "Caller-provided reason this action was triggered (e.g. 'plan-phase complete')" })),
|
|
572
581
|
}),
|
|
573
582
|
execute: planTaskExecute,
|
|
574
583
|
};
|
|
@@ -628,6 +637,9 @@ export function registerDbTools(pi) {
|
|
|
628
637
|
}),
|
|
629
638
|
Type.String({ description: "Fallback: verification summary string" }),
|
|
630
639
|
]), { description: "Array of verification evidence entries" })),
|
|
640
|
+
// Single-writer v3 audit trail (Stream 2): caller-provided actor identity + causation.
|
|
641
|
+
actorName: Type.Optional(Type.String({ description: "Caller-provided actor identity for the audit trail (e.g. 'executor-01', 'gsd-orchestrator')" })),
|
|
642
|
+
triggerReason: Type.Optional(Type.String({ description: "Caller-provided reason this action was triggered (e.g. 'task verified after retry')" })),
|
|
631
643
|
}),
|
|
632
644
|
execute: taskCompleteExecute,
|
|
633
645
|
};
|
|
@@ -705,6 +717,9 @@ export function registerDbTools(pi) {
|
|
|
705
717
|
}),
|
|
706
718
|
Type.String({ description: "Fallback: slice ID string" }),
|
|
707
719
|
]), { description: "Upstream slice dependencies consumed" })),
|
|
720
|
+
// Single-writer v3 audit trail (Stream 2): caller-provided actor identity + causation.
|
|
721
|
+
actorName: Type.Optional(Type.String({ description: "Caller-provided actor identity for the audit trail (e.g. 'executor-01', 'gsd-orchestrator')" })),
|
|
722
|
+
triggerReason: Type.Optional(Type.String({ description: "Caller-provided reason this action was triggered (e.g. 'all tasks verified')" })),
|
|
708
723
|
}),
|
|
709
724
|
execute: sliceCompleteExecute,
|
|
710
725
|
};
|
|
@@ -826,6 +841,9 @@ export function registerDbTools(pi) {
|
|
|
826
841
|
lessonsLearned: Type.Optional(Type.Array(Type.String(), { description: "Lessons learned during the milestone" })),
|
|
827
842
|
followUps: Type.Optional(Type.String({ description: "Follow-up items for future milestones" })),
|
|
828
843
|
deviations: Type.Optional(Type.String({ description: "Deviations from the original plan" })),
|
|
844
|
+
// Single-writer v3 audit trail (Stream 2): caller-provided actor identity + causation.
|
|
845
|
+
actorName: Type.Optional(Type.String({ description: "Caller-provided actor identity for the audit trail (e.g. 'executor-01', 'gsd-orchestrator')" })),
|
|
846
|
+
triggerReason: Type.Optional(Type.String({ description: "Caller-provided reason this action was triggered (e.g. 'milestone validation passed')" })),
|
|
829
847
|
}),
|
|
830
848
|
execute: milestoneCompleteExecute,
|
|
831
849
|
};
|
|
@@ -897,6 +915,9 @@ export function registerDbTools(pi) {
|
|
|
897
915
|
expectedOutput: Type.Array(Type.String(), { description: "Expected output files or artifacts" }),
|
|
898
916
|
}), { description: "Tasks to upsert (update existing or insert new)" }),
|
|
899
917
|
removedTaskIds: Type.Array(Type.String(), { description: "Task IDs to remove from the slice" }),
|
|
918
|
+
// Single-writer v3 audit trail (Stream 2): caller-provided actor identity + causation.
|
|
919
|
+
actorName: Type.Optional(Type.String({ description: "Caller-provided actor identity for the audit trail (e.g. 'executor-01', 'gsd-orchestrator')" })),
|
|
920
|
+
triggerReason: Type.Optional(Type.String({ description: "Caller-provided reason this action was triggered (e.g. 'blocker discovered during execution')" })),
|
|
900
921
|
}),
|
|
901
922
|
execute: replanSliceExecute,
|
|
902
923
|
};
|
|
@@ -941,11 +962,199 @@ export function registerDbTools(pi) {
|
|
|
941
962
|
}), { description: "New slices to add" }),
|
|
942
963
|
removed: Type.Array(Type.String(), { description: "Slice IDs to remove" }),
|
|
943
964
|
}, { description: "Slice changes to apply" }),
|
|
965
|
+
// Single-writer v3 audit trail (Stream 2): caller-provided actor identity + causation.
|
|
966
|
+
actorName: Type.Optional(Type.String({ description: "Caller-provided actor identity for the audit trail (e.g. 'executor-01', 'gsd-orchestrator')" })),
|
|
967
|
+
triggerReason: Type.Optional(Type.String({ description: "Caller-provided reason this action was triggered (e.g. 'slice S01 completed, reassessing remaining roadmap')" })),
|
|
944
968
|
}),
|
|
945
969
|
execute: reassessRoadmapExecute,
|
|
946
970
|
};
|
|
947
971
|
pi.registerTool(reassessRoadmapTool);
|
|
948
972
|
registerAlias(pi, reassessRoadmapTool, "gsd_roadmap_reassess", "gsd_reassess_roadmap");
|
|
973
|
+
// ─── gsd_task_reopen (gsd_reopen_task alias) ───────────────────────────
|
|
974
|
+
// Single-writer v3, Stream 3: reversibility tools for closed units.
|
|
975
|
+
const reopenTaskExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
976
|
+
const dbAvailable = await ensureDbOpen();
|
|
977
|
+
if (!dbAvailable) {
|
|
978
|
+
return {
|
|
979
|
+
content: [{ type: "text", text: "Error: GSD database is not available. Cannot reopen task." }],
|
|
980
|
+
details: { operation: "reopen_task", error: "db_unavailable" },
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
try {
|
|
984
|
+
const { handleReopenTask } = await import("../tools/reopen-task.js");
|
|
985
|
+
const result = await handleReopenTask(params, process.cwd());
|
|
986
|
+
if ("error" in result) {
|
|
987
|
+
return {
|
|
988
|
+
content: [{ type: "text", text: `Error reopening task: ${result.error}` }],
|
|
989
|
+
details: { operation: "reopen_task", error: result.error },
|
|
990
|
+
};
|
|
991
|
+
}
|
|
992
|
+
return {
|
|
993
|
+
content: [{ type: "text", text: `Reopened task ${result.taskId} (${result.sliceId}/${result.milestoneId})` }],
|
|
994
|
+
details: {
|
|
995
|
+
operation: "reopen_task",
|
|
996
|
+
milestoneId: result.milestoneId,
|
|
997
|
+
sliceId: result.sliceId,
|
|
998
|
+
taskId: result.taskId,
|
|
999
|
+
},
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
catch (err) {
|
|
1003
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1004
|
+
logError("tool", `reopen_task tool failed: ${msg}`, { tool: "gsd_task_reopen", error: String(err) });
|
|
1005
|
+
return {
|
|
1006
|
+
content: [{ type: "text", text: `Error reopening task: ${msg}` }],
|
|
1007
|
+
details: { operation: "reopen_task", error: msg },
|
|
1008
|
+
};
|
|
1009
|
+
}
|
|
1010
|
+
};
|
|
1011
|
+
const reopenTaskTool = {
|
|
1012
|
+
name: "gsd_task_reopen",
|
|
1013
|
+
label: "Reopen Task",
|
|
1014
|
+
description: "Reset a completed task back to 'pending' so it can be re-done. Cleans up SUMMARY.md so the DB-filesystem reconciler does not auto-correct the task back to complete. " +
|
|
1015
|
+
"Both the parent slice and milestone must still be open — use gsd_slice_reopen first if the slice has been closed.",
|
|
1016
|
+
promptSnippet: "Reopen a completed GSD task (resets status to pending, removes SUMMARY.md)",
|
|
1017
|
+
promptGuidelines: [
|
|
1018
|
+
"Use gsd_task_reopen when a completed task needs to be re-done (e.g. verification missed a regression, requirements changed).",
|
|
1019
|
+
"Will fail if the parent slice or milestone is already closed — reopen those first.",
|
|
1020
|
+
"Will fail if the task is not currently 'complete' — there is nothing to reopen.",
|
|
1021
|
+
"Use the canonical name gsd_task_reopen; gsd_reopen_task is only an alias.",
|
|
1022
|
+
],
|
|
1023
|
+
parameters: Type.Object({
|
|
1024
|
+
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
1025
|
+
sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
|
|
1026
|
+
taskId: Type.String({ description: "Task ID (e.g. T01)" }),
|
|
1027
|
+
reason: Type.Optional(Type.String({ description: "Why the task is being reopened (recorded in the audit trail)" })),
|
|
1028
|
+
// Single-writer v3 audit trail (Stream 2): caller-provided actor identity + causation.
|
|
1029
|
+
actorName: Type.Optional(Type.String({ description: "Caller-provided actor identity for the audit trail (e.g. 'executor-01', 'gsd-orchestrator')" })),
|
|
1030
|
+
triggerReason: Type.Optional(Type.String({ description: "Caller-provided reason this action was triggered (e.g. 'regression discovered post-completion')" })),
|
|
1031
|
+
}),
|
|
1032
|
+
execute: reopenTaskExecute,
|
|
1033
|
+
};
|
|
1034
|
+
pi.registerTool(reopenTaskTool);
|
|
1035
|
+
registerAlias(pi, reopenTaskTool, "gsd_reopen_task", "gsd_task_reopen");
|
|
1036
|
+
// ─── gsd_slice_reopen (gsd_reopen_slice alias) ─────────────────────────
|
|
1037
|
+
const reopenSliceExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
1038
|
+
const dbAvailable = await ensureDbOpen();
|
|
1039
|
+
if (!dbAvailable) {
|
|
1040
|
+
return {
|
|
1041
|
+
content: [{ type: "text", text: "Error: GSD database is not available. Cannot reopen slice." }],
|
|
1042
|
+
details: { operation: "reopen_slice", error: "db_unavailable" },
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
try {
|
|
1046
|
+
const { handleReopenSlice } = await import("../tools/reopen-slice.js");
|
|
1047
|
+
const result = await handleReopenSlice(params, process.cwd());
|
|
1048
|
+
if ("error" in result) {
|
|
1049
|
+
return {
|
|
1050
|
+
content: [{ type: "text", text: `Error reopening slice: ${result.error}` }],
|
|
1051
|
+
details: { operation: "reopen_slice", error: result.error },
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
return {
|
|
1055
|
+
content: [{ type: "text", text: `Reopened slice ${result.sliceId} (${result.milestoneId}); reset ${result.tasksReset} task(s) to pending.` }],
|
|
1056
|
+
details: {
|
|
1057
|
+
operation: "reopen_slice",
|
|
1058
|
+
milestoneId: result.milestoneId,
|
|
1059
|
+
sliceId: result.sliceId,
|
|
1060
|
+
tasksReset: result.tasksReset,
|
|
1061
|
+
},
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
catch (err) {
|
|
1065
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1066
|
+
logError("tool", `reopen_slice tool failed: ${msg}`, { tool: "gsd_slice_reopen", error: String(err) });
|
|
1067
|
+
return {
|
|
1068
|
+
content: [{ type: "text", text: `Error reopening slice: ${msg}` }],
|
|
1069
|
+
details: { operation: "reopen_slice", error: msg },
|
|
1070
|
+
};
|
|
1071
|
+
}
|
|
1072
|
+
};
|
|
1073
|
+
const reopenSliceTool = {
|
|
1074
|
+
name: "gsd_slice_reopen",
|
|
1075
|
+
label: "Reopen Slice",
|
|
1076
|
+
description: "Reset a completed slice back to 'in_progress' and reset ALL of its tasks back to 'pending'. Cleans up SUMMARY.md / UAT.md and per-task summaries. " +
|
|
1077
|
+
"Reopening a slice means re-doing the work — partial resets create ambiguous state, so all tasks are reset.",
|
|
1078
|
+
promptSnippet: "Reopen a completed GSD slice (resets all tasks to pending, removes summaries)",
|
|
1079
|
+
promptGuidelines: [
|
|
1080
|
+
"Use gsd_slice_reopen when a completed slice needs to be re-done (e.g. integration issue surfaced, requirements changed).",
|
|
1081
|
+
"All tasks within the slice are reset to 'pending' — there is no partial-reopen.",
|
|
1082
|
+
"Will fail if the parent milestone is already closed — reopen the milestone first.",
|
|
1083
|
+
"Will fail if the slice is not currently 'complete' — there is nothing to reopen.",
|
|
1084
|
+
"Use the canonical name gsd_slice_reopen; gsd_reopen_slice is only an alias.",
|
|
1085
|
+
],
|
|
1086
|
+
parameters: Type.Object({
|
|
1087
|
+
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
1088
|
+
sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
|
|
1089
|
+
reason: Type.Optional(Type.String({ description: "Why the slice is being reopened (recorded in the audit trail)" })),
|
|
1090
|
+
// Single-writer v3 audit trail (Stream 2): caller-provided actor identity + causation.
|
|
1091
|
+
actorName: Type.Optional(Type.String({ description: "Caller-provided actor identity for the audit trail (e.g. 'executor-01', 'gsd-orchestrator')" })),
|
|
1092
|
+
triggerReason: Type.Optional(Type.String({ description: "Caller-provided reason this action was triggered (e.g. 'cross-slice regression discovered')" })),
|
|
1093
|
+
}),
|
|
1094
|
+
execute: reopenSliceExecute,
|
|
1095
|
+
};
|
|
1096
|
+
pi.registerTool(reopenSliceTool);
|
|
1097
|
+
registerAlias(pi, reopenSliceTool, "gsd_reopen_slice", "gsd_slice_reopen");
|
|
1098
|
+
// ─── gsd_milestone_reopen (gsd_reopen_milestone alias) ─────────────────
|
|
1099
|
+
const reopenMilestoneExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
1100
|
+
const dbAvailable = await ensureDbOpen();
|
|
1101
|
+
if (!dbAvailable) {
|
|
1102
|
+
return {
|
|
1103
|
+
content: [{ type: "text", text: "Error: GSD database is not available. Cannot reopen milestone." }],
|
|
1104
|
+
details: { operation: "reopen_milestone", error: "db_unavailable" },
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1107
|
+
try {
|
|
1108
|
+
const { handleReopenMilestone } = await import("../tools/reopen-milestone.js");
|
|
1109
|
+
const result = await handleReopenMilestone(params, process.cwd());
|
|
1110
|
+
if ("error" in result) {
|
|
1111
|
+
return {
|
|
1112
|
+
content: [{ type: "text", text: `Error reopening milestone: ${result.error}` }],
|
|
1113
|
+
details: { operation: "reopen_milestone", error: result.error },
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
1116
|
+
return {
|
|
1117
|
+
content: [{ type: "text", text: `Reopened milestone ${result.milestoneId}; reset ${result.slicesReset} slice(s) and ${result.tasksReset} task(s).` }],
|
|
1118
|
+
details: {
|
|
1119
|
+
operation: "reopen_milestone",
|
|
1120
|
+
milestoneId: result.milestoneId,
|
|
1121
|
+
slicesReset: result.slicesReset,
|
|
1122
|
+
tasksReset: result.tasksReset,
|
|
1123
|
+
},
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
catch (err) {
|
|
1127
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1128
|
+
logError("tool", `reopen_milestone tool failed: ${msg}`, { tool: "gsd_milestone_reopen", error: String(err) });
|
|
1129
|
+
return {
|
|
1130
|
+
content: [{ type: "text", text: `Error reopening milestone: ${msg}` }],
|
|
1131
|
+
details: { operation: "reopen_milestone", error: msg },
|
|
1132
|
+
};
|
|
1133
|
+
}
|
|
1134
|
+
};
|
|
1135
|
+
const reopenMilestoneTool = {
|
|
1136
|
+
name: "gsd_milestone_reopen",
|
|
1137
|
+
label: "Reopen Milestone",
|
|
1138
|
+
description: "Reset a closed milestone back to 'active', all of its slices to 'in_progress', and all tasks to 'pending'. " +
|
|
1139
|
+
"Cleans up MILESTONE-SUMMARY.md, slice summaries, and task summaries so the DB-filesystem reconciler does not auto-correct status back to complete.",
|
|
1140
|
+
promptSnippet: "Reopen a closed GSD milestone (resets slices and tasks, removes summaries)",
|
|
1141
|
+
promptGuidelines: [
|
|
1142
|
+
"Use gsd_milestone_reopen when a closed milestone needs to be re-done (e.g. validation failure surfaced after closure).",
|
|
1143
|
+
"All slices reset to 'in_progress' and all tasks reset to 'pending' — no partial reopen.",
|
|
1144
|
+
"Will fail if the milestone is not currently closed — there is nothing to reopen.",
|
|
1145
|
+
"Use the canonical name gsd_milestone_reopen; gsd_reopen_milestone is only an alias.",
|
|
1146
|
+
],
|
|
1147
|
+
parameters: Type.Object({
|
|
1148
|
+
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
1149
|
+
reason: Type.Optional(Type.String({ description: "Why the milestone is being reopened (recorded in the audit trail)" })),
|
|
1150
|
+
// Single-writer v3 audit trail (Stream 2): caller-provided actor identity + causation.
|
|
1151
|
+
actorName: Type.Optional(Type.String({ description: "Caller-provided actor identity for the audit trail (e.g. 'executor-01', 'gsd-orchestrator')" })),
|
|
1152
|
+
triggerReason: Type.Optional(Type.String({ description: "Caller-provided reason this action was triggered (e.g. 'post-closure validation failure')" })),
|
|
1153
|
+
}),
|
|
1154
|
+
execute: reopenMilestoneExecute,
|
|
1155
|
+
};
|
|
1156
|
+
pi.registerTool(reopenMilestoneTool);
|
|
1157
|
+
registerAlias(pi, reopenMilestoneTool, "gsd_reopen_milestone", "gsd_milestone_reopen");
|
|
949
1158
|
// ─── gsd_save_gate_result ──────────────────────────────────────────────
|
|
950
1159
|
const saveGateResultExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
951
1160
|
return executeSaveGateResult(params, process.cwd());
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { getAutoDashboardData, startAuto } from "../auto.js";
|
|
2
2
|
import { resetTransientRetryState } from "./agent-end-recovery.js";
|
|
3
|
-
import { resetSessionTimeoutState } from "../auto/phases.js";
|
|
4
3
|
const defaultDeps = {
|
|
5
4
|
getSnapshot: () => getAutoDashboardData(),
|
|
6
5
|
resetTransientRetryState,
|
|
7
|
-
resetSessionTimeoutState,
|
|
8
6
|
startAuto,
|
|
9
7
|
};
|
|
10
8
|
export async function resumeAutoAfterProviderDelay(pi, ctx, deps = defaultDeps) {
|
|
@@ -17,11 +15,10 @@ export async function resumeAutoAfterProviderDelay(pi, ctx, deps = defaultDeps)
|
|
|
17
15
|
ctx.ui.notify("Provider error recovery delay elapsed, but no paused auto-mode base path was available. Leaving auto-mode paused.", "warning");
|
|
18
16
|
return "missing-base";
|
|
19
17
|
}
|
|
20
|
-
// Reset retry
|
|
21
|
-
//
|
|
22
|
-
// auto-resume
|
|
18
|
+
// Reset provider-error retry state before restarting. Session-creation
|
|
19
|
+
// timeout state intentionally survives delayed resumes so the bounded
|
|
20
|
+
// auto-resume limit cannot be reset into an infinite pause/resume loop.
|
|
23
21
|
deps.resetTransientRetryState();
|
|
24
|
-
deps.resetSessionTimeoutState();
|
|
25
22
|
await deps.startAuto(ctx, pi, snapshot.basePath, false, { step: snapshot.stepMode });
|
|
26
23
|
return "resumed";
|
|
27
24
|
}
|