gsd-pi 2.77.0-dev.eaa4973bc → 2.78.0-dev.aeeb2ca00
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 +53 -17
- package/dist/claude-cli-check.js +46 -10
- 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 +72 -16
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +481 -17
- package/dist/resources/extensions/github-sync/templates.js +103 -0
- package/dist/resources/extensions/google-search/index.js +3 -2
- package/dist/resources/extensions/gsd/auto/loop.js +124 -2
- package/dist/resources/extensions/gsd/auto/phases.js +57 -39
- package/dist/resources/extensions/gsd/auto/session.js +6 -2
- package/dist/resources/extensions/gsd/auto-dispatch.js +142 -29
- package/dist/resources/extensions/gsd/auto-model-selection.js +124 -4
- package/dist/resources/extensions/gsd/auto-post-unit.js +150 -64
- package/dist/resources/extensions/gsd/auto-prompts.js +372 -104
- package/dist/resources/extensions/gsd/auto-recovery.js +197 -48
- package/dist/resources/extensions/gsd/auto-start.js +107 -29
- 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 +76 -21
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +19 -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/context-store.js +23 -7
- package/dist/resources/extensions/gsd/detection.js +49 -1
- package/dist/resources/extensions/gsd/dispatch-guard.js +2 -17
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/forensics.js +106 -0
- 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 +39 -13
- 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/milestone-summary-classifier.js +37 -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/preferences-validation.js +23 -0
- package/dist/resources/extensions/gsd/prompt-cache-optimizer.js +4 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
- package/dist/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
- 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-cadence.js +238 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +278 -8
- package/dist/resources/extensions/gsd/state-transition-matrix.js +118 -0
- package/dist/resources/extensions/gsd/state.js +69 -58
- package/dist/resources/extensions/gsd/sync-lock.js +98 -42
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +7 -2
- 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/dispatch-envelope.js +33 -0
- package/dist/resources/extensions/gsd/uok/execution-graph.js +10 -0
- package/dist/resources/extensions/gsd/uok/gate-runner.js +53 -5
- package/dist/resources/extensions/gsd/uok/gitops.js +2 -1
- package/dist/resources/extensions/gsd/uok/loop-adapter.js +37 -10
- package/dist/resources/extensions/gsd/uok/parity-report.js +58 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +10 -4
- package/dist/resources/extensions/gsd/uok/writer.js +82 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +6 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +85 -8
- package/dist/resources/extensions/gsd/worktree-resolver.js +86 -7
- package/dist/resources/extensions/gsd/worktree-telemetry.js +198 -0
- 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 +11 -11
- 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 +11 -11
- 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/package.json +2 -2
- 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/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +15 -6
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- 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 +85 -0
- package/packages/mcp-server/src/workflow-tools.ts +19 -6
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +2 -2
- 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/package.json +1 -1
- 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/package.json +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/__tests__/tool-execution.test.js +36 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.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/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +30 -12
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.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/package.json +1 -1
- 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/__tests__/tool-execution.test.ts +49 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +48 -9
- 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 +37 -11
- 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/package.json +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 +42 -11
- 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/package.json +1 -1
- package/packages/rpc-client/src/rpc-client.test.ts +109 -52
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +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 +75 -16
- 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/templates.ts +151 -0
- package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
- package/src/resources/extensions/github-sync/tests/templates.test.ts +92 -1
- package/src/resources/extensions/google-search/index.ts +3 -2
- package/src/resources/extensions/gsd/auto/loop.ts +142 -2
- package/src/resources/extensions/gsd/auto/phases.ts +62 -38
- package/src/resources/extensions/gsd/auto/session.ts +7 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +156 -29
- package/src/resources/extensions/gsd/auto-model-selection.ts +131 -4
- package/src/resources/extensions/gsd/auto-post-unit.ts +163 -73
- package/src/resources/extensions/gsd/auto-prompts.ts +385 -93
- package/src/resources/extensions/gsd/auto-recovery.ts +230 -51
- package/src/resources/extensions/gsd/auto-start.ts +127 -9
- 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 +90 -23
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +20 -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/context-store.ts +25 -8
- package/src/resources/extensions/gsd/detection.ts +58 -1
- package/src/resources/extensions/gsd/dispatch-guard.ts +2 -20
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/forensics.ts +118 -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 +149 -2
- package/src/resources/extensions/gsd/gsd-db.ts +6 -3
- package/src/resources/extensions/gsd/guided-flow.ts +57 -14
- package/src/resources/extensions/gsd/journal.ts +11 -1
- 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/milestone-summary-classifier.ts +42 -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/preferences-validation.ts +21 -0
- package/src/resources/extensions/gsd/prompt-cache-optimizer.ts +4 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
- package/src/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
- 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-cadence.ts +299 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +309 -8
- package/src/resources/extensions/gsd/state-transition-matrix.ts +152 -0
- package/src/resources/extensions/gsd/state.ts +76 -66
- 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/artifacts-table-preserved-on-cache-invalidate.test.ts +2 -1
- 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 +133 -292
- 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-remediate-slice-status.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -194
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
- package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
- package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +108 -0
- 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-slice-verification-gate.test.ts +2 -1
- 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/context-store.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +50 -1
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +159 -0
- package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +1 -0
- 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 -4
- package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +173 -0
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +8 -104
- 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/google-search-stub.test.ts +14 -4
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +117 -0
- 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 -56
- 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/interactive-routing-bypass.test.ts +9 -3
- package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +93 -1
- 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 -55
- package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
- package/src/resources/extensions/gsd/tests/milestone-summary-classifier.test.ts +30 -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 -48
- package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +59 -2
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -130
- 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/preferences-worktree-sync.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/prompt-cache-optimizer.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +15 -4
- 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/queue-draft-detection.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +4 -5
- 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/restore-tools-after-discuss.test.ts +6 -3
- 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/sidecar-queue.test.ts +3 -2
- 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-cadence.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +164 -1
- package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +7 -6
- 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/sync-worktree-skip-current.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/test-helpers.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/test-helpers.ts +153 -0
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -1
- 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-contracts.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +16 -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/uok-loop-adapter-writer.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/uok-parity-report.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +19 -2
- package/src/resources/extensions/gsd/tests/uok-writer.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -80
- 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/worktree-telemetry.test.ts +210 -0
- 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/tools/validate-milestone.ts +8 -2
- 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/contracts.ts +65 -0
- package/src/resources/extensions/gsd/uok/dispatch-envelope.ts +56 -0
- package/src/resources/extensions/gsd/uok/execution-graph.ts +22 -0
- package/src/resources/extensions/gsd/uok/gate-runner.ts +65 -5
- package/src/resources/extensions/gsd/uok/gitops.ts +6 -1
- package/src/resources/extensions/gsd/uok/loop-adapter.ts +45 -10
- package/src/resources/extensions/gsd/uok/parity-report.ts +84 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +13 -5
- package/src/resources/extensions/gsd/uok/writer.ts +113 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +6 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +108 -7
- package/src/resources/extensions/gsd/worktree-resolver.ts +96 -9
- package/src/resources/extensions/gsd/worktree-telemetry.ts +322 -0
- 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 -143
- 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 -74
- package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
- 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 -125
- package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -42
- /package/dist/web/standalone/.next/static/{5wbu35_C2_MQ3Jj1lEVDx → cAJH99yNS1UPbeSEiNRrV}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{5wbu35_C2_MQ3Jj1lEVDx → cAJH99yNS1UPbeSEiNRrV}/_ssgManifest.js +0 -0
|
@@ -181,3 +181,154 @@ export function formatSummaryComment(data: SummaryData): string {
|
|
|
181
181
|
|
|
182
182
|
return lines.join("\n");
|
|
183
183
|
}
|
|
184
|
+
|
|
185
|
+
// ─── Swarm Delivery Routines ───────────────────────────────────────────────
|
|
186
|
+
|
|
187
|
+
export type SwarmLaneId = "workflow" | "state" | "writer" | "uok" | "github";
|
|
188
|
+
|
|
189
|
+
export interface SwarmLaneData {
|
|
190
|
+
id: SwarmLaneId;
|
|
191
|
+
branch: string;
|
|
192
|
+
owner?: string;
|
|
193
|
+
latestCommit?: string;
|
|
194
|
+
summary?: string;
|
|
195
|
+
changedContracts?: string[];
|
|
196
|
+
testEvidence?: string[];
|
|
197
|
+
blockers?: string[];
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export interface SwarmLanePRData {
|
|
201
|
+
lane: SwarmLaneData;
|
|
202
|
+
impactArea: string;
|
|
203
|
+
transitionRisks: string[];
|
|
204
|
+
rollbackPlan: string[];
|
|
205
|
+
linkedIssue?: number;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface SwarmReleaseChecklistData {
|
|
209
|
+
integrationBranch: string;
|
|
210
|
+
lanes: SwarmLaneData[];
|
|
211
|
+
parityReport?: string;
|
|
212
|
+
rollbackDrill?: string;
|
|
213
|
+
requiredChecks?: string[];
|
|
214
|
+
openRisks?: string[];
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export const SWARM_LANE_LABELS: Record<SwarmLaneId, string> = {
|
|
218
|
+
workflow: "lane/workflow",
|
|
219
|
+
state: "lane/state",
|
|
220
|
+
writer: "lane/writer",
|
|
221
|
+
uok: "lane/uok",
|
|
222
|
+
github: "lane/github",
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
function checkedList(items: string[] | undefined, emptyLabel: string): string[] {
|
|
226
|
+
if (!items?.length) return [`- [ ] ${emptyLabel}`];
|
|
227
|
+
return items.map((item) => `- [ ] ${item}`);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export function formatSwarmLanePRBody(data: SwarmLanePRData): string {
|
|
231
|
+
const lines: string[] = [];
|
|
232
|
+
const laneLabel = SWARM_LANE_LABELS[data.lane.id];
|
|
233
|
+
|
|
234
|
+
lines.push("## Swarm lane");
|
|
235
|
+
lines.push("");
|
|
236
|
+
lines.push(`**Lane:** \`${laneLabel}\``);
|
|
237
|
+
lines.push(`**Branch:** \`${data.lane.branch}\``);
|
|
238
|
+
if (data.lane.owner) lines.push(`**Owner:** ${data.lane.owner}`);
|
|
239
|
+
if (data.lane.latestCommit) lines.push(`**Latest commit:** \`${data.lane.latestCommit}\``);
|
|
240
|
+
lines.push("");
|
|
241
|
+
|
|
242
|
+
lines.push("## Impact area");
|
|
243
|
+
lines.push("");
|
|
244
|
+
lines.push(data.impactArea);
|
|
245
|
+
lines.push("");
|
|
246
|
+
|
|
247
|
+
lines.push("## Changed contracts");
|
|
248
|
+
lines.push(...checkedList(data.lane.changedContracts, "No shared contracts changed"));
|
|
249
|
+
lines.push("");
|
|
250
|
+
|
|
251
|
+
lines.push("## Transition risks");
|
|
252
|
+
lines.push(...checkedList(data.transitionRisks, "No transition risks identified"));
|
|
253
|
+
lines.push("");
|
|
254
|
+
|
|
255
|
+
lines.push("## Rollback plan");
|
|
256
|
+
lines.push(...checkedList(data.rollbackPlan, "Revert this lane PR"));
|
|
257
|
+
lines.push("");
|
|
258
|
+
|
|
259
|
+
lines.push("## Test evidence");
|
|
260
|
+
lines.push(...checkedList(data.lane.testEvidence, "Test evidence pending"));
|
|
261
|
+
lines.push("");
|
|
262
|
+
|
|
263
|
+
if (data.lane.blockers?.length) {
|
|
264
|
+
lines.push("## Blockers");
|
|
265
|
+
for (const blocker of data.lane.blockers) lines.push(`- ${blocker}`);
|
|
266
|
+
lines.push("");
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (data.linkedIssue) {
|
|
270
|
+
lines.push(`Closes #${data.linkedIssue}`);
|
|
271
|
+
lines.push("");
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
lines.push("---");
|
|
275
|
+
lines.push("*Auto-generated by GSD GitHub Sync swarm routines*");
|
|
276
|
+
|
|
277
|
+
return lines.join("\n");
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export function formatSwarmReleaseChecklistBody(data: SwarmReleaseChecklistData): string {
|
|
281
|
+
const lines: string[] = [];
|
|
282
|
+
|
|
283
|
+
lines.push(`# UOK Swarm Release Checklist`);
|
|
284
|
+
lines.push("");
|
|
285
|
+
lines.push(`**Integration branch:** \`${data.integrationBranch}\``);
|
|
286
|
+
lines.push("");
|
|
287
|
+
|
|
288
|
+
lines.push("## Lane summary");
|
|
289
|
+
lines.push("");
|
|
290
|
+
lines.push("| Lane | Branch | Owner | Commit | Status |");
|
|
291
|
+
lines.push("|------|--------|-------|--------|--------|");
|
|
292
|
+
for (const lane of data.lanes) {
|
|
293
|
+
const owner = lane.owner ?? "";
|
|
294
|
+
const commit = lane.latestCommit ? `\`${lane.latestCommit}\`` : "";
|
|
295
|
+
const status = lane.blockers?.length ? "blocked" : "ready";
|
|
296
|
+
lines.push(`| \`${SWARM_LANE_LABELS[lane.id]}\` | \`${lane.branch}\` | ${owner} | ${commit} | ${status} |`);
|
|
297
|
+
}
|
|
298
|
+
lines.push("");
|
|
299
|
+
|
|
300
|
+
lines.push("## Required evidence");
|
|
301
|
+
lines.push("- [ ] Changed contracts summarized");
|
|
302
|
+
lines.push("- [ ] Transition matrix diff attached or linked");
|
|
303
|
+
lines.push("- [ ] Writer sequence proof attached or linked");
|
|
304
|
+
lines.push("- [ ] UOK parity report attached or linked");
|
|
305
|
+
lines.push("- [ ] Rollback drill evidence attached or linked");
|
|
306
|
+
lines.push("");
|
|
307
|
+
|
|
308
|
+
if (data.requiredChecks?.length) {
|
|
309
|
+
lines.push("## Required checks");
|
|
310
|
+
for (const check of data.requiredChecks) lines.push(`- [ ] ${check}`);
|
|
311
|
+
lines.push("");
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
lines.push("## Parity report");
|
|
315
|
+
lines.push(data.parityReport ?? "Pending.");
|
|
316
|
+
lines.push("");
|
|
317
|
+
|
|
318
|
+
lines.push("## Rollback drill");
|
|
319
|
+
lines.push(data.rollbackDrill ?? "Pending.");
|
|
320
|
+
lines.push("");
|
|
321
|
+
|
|
322
|
+
lines.push("## Open risks");
|
|
323
|
+
if (data.openRisks?.length) {
|
|
324
|
+
for (const risk of data.openRisks) lines.push(`- ${risk}`);
|
|
325
|
+
} else {
|
|
326
|
+
lines.push("None.");
|
|
327
|
+
}
|
|
328
|
+
lines.push("");
|
|
329
|
+
|
|
330
|
+
lines.push("---");
|
|
331
|
+
lines.push("*Auto-generated by GSD GitHub Sync swarm routines*");
|
|
332
|
+
|
|
333
|
+
return lines.join("\n");
|
|
334
|
+
}
|
|
@@ -1,20 +1,89 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { describe, it, beforeEach, afterEach } from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
3
|
import { ghIsAvailable, _resetGhCache } from "../cli.ts";
|
|
4
4
|
|
|
5
|
-
describe("cli", () => {
|
|
5
|
+
describe("github-sync/cli.ghIsAvailable", () => {
|
|
6
|
+
let originalPath: string | undefined;
|
|
7
|
+
|
|
6
8
|
beforeEach(() => {
|
|
7
9
|
_resetGhCache();
|
|
10
|
+
originalPath = process.env.PATH;
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
if (originalPath !== undefined) {
|
|
15
|
+
process.env.PATH = originalPath;
|
|
16
|
+
} else {
|
|
17
|
+
delete process.env.PATH;
|
|
18
|
+
}
|
|
19
|
+
_resetGhCache();
|
|
8
20
|
});
|
|
9
21
|
|
|
10
|
-
it("
|
|
11
|
-
|
|
12
|
-
|
|
22
|
+
it("returns true when gh is on PATH, false otherwise", () => {
|
|
23
|
+
// Force gh to be unavailable by setting PATH to an empty-ish string
|
|
24
|
+
// that contains no gh. This is more robust than asserting a raw
|
|
25
|
+
// `typeof === 'boolean'` (which the previous test did — a tautology,
|
|
26
|
+
// since the function's TypeScript signature already guarantees it).
|
|
27
|
+
process.env.PATH = "/nonexistent-path-for-test";
|
|
28
|
+
assert.equal(
|
|
29
|
+
ghIsAvailable(),
|
|
30
|
+
false,
|
|
31
|
+
"with gh not on PATH, ghIsAvailable must return false",
|
|
32
|
+
);
|
|
13
33
|
});
|
|
14
34
|
|
|
15
|
-
it("
|
|
35
|
+
it("caches the availability result — PATH changes after first call are ignored", () => {
|
|
36
|
+
// With the original PATH, gh may or may not be present (depends on
|
|
37
|
+
// the dev machine / CI runner). Either way, capture the first
|
|
38
|
+
// result, then mutate PATH so a fresh subprocess spawn would yield
|
|
39
|
+
// a different result. If the function is genuinely caching, the
|
|
40
|
+
// second call returns the same value despite the PATH change.
|
|
41
|
+
|
|
42
|
+
// Prime the cache with whatever the current PATH says.
|
|
16
43
|
const first = ghIsAvailable();
|
|
44
|
+
|
|
45
|
+
// Change PATH so the `gh` binary is no longer findable — any
|
|
46
|
+
// subsequent subprocess spawn would yield false.
|
|
47
|
+
process.env.PATH = "/nonexistent-path-for-test";
|
|
48
|
+
|
|
17
49
|
const second = ghIsAvailable();
|
|
18
|
-
|
|
50
|
+
|
|
51
|
+
assert.equal(
|
|
52
|
+
second,
|
|
53
|
+
first,
|
|
54
|
+
"cached result must not change when PATH changes after the first call. " +
|
|
55
|
+
"Without caching, mutating PATH away from gh would flip the result.",
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("re-evaluates after _resetGhCache — cache is the thing being tested", () => {
|
|
60
|
+
// This locks in that `_resetGhCache` actually clears the cache:
|
|
61
|
+
// with it absent, the second assertion wouldn't observe the PATH change.
|
|
62
|
+
process.env.PATH = "/nonexistent-path-for-test";
|
|
63
|
+
const beforeReset = ghIsAvailable(); // false — gh not on PATH
|
|
64
|
+
assert.equal(beforeReset, false);
|
|
65
|
+
|
|
66
|
+
_resetGhCache();
|
|
67
|
+
// Restore PATH so that if a real gh is available, the cached
|
|
68
|
+
// "false" from before-reset must not persist.
|
|
69
|
+
if (originalPath !== undefined) {
|
|
70
|
+
process.env.PATH = originalPath;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// After reset, another call re-probes. We don't know whether the
|
|
74
|
+
// real machine has gh, but we know the re-probe happened because
|
|
75
|
+
// before-reset with an empty PATH was false AND if the machine
|
|
76
|
+
// has gh, the post-reset result would be true (i.e. different).
|
|
77
|
+
const afterReset = ghIsAvailable();
|
|
78
|
+
// Invariant: either the dev machine has gh (afterReset=true, differs
|
|
79
|
+
// from beforeReset) or it doesn't (afterReset=false, unchanged).
|
|
80
|
+
// Both are fine — what matters is that _resetGhCache cleared the
|
|
81
|
+
// memoized value so the re-probe ran. That's observable by the
|
|
82
|
+
// fact that with gh present, afterReset=true even though the
|
|
83
|
+
// cached pre-reset value was false.
|
|
84
|
+
assert.ok(
|
|
85
|
+
typeof afterReset === "boolean",
|
|
86
|
+
"re-probe must return a boolean",
|
|
87
|
+
);
|
|
19
88
|
});
|
|
20
89
|
});
|
|
@@ -5,6 +5,9 @@ import {
|
|
|
5
5
|
formatSlicePRBody,
|
|
6
6
|
formatTaskIssueBody,
|
|
7
7
|
formatSummaryComment,
|
|
8
|
+
formatSwarmLanePRBody,
|
|
9
|
+
formatSwarmReleaseChecklistBody,
|
|
10
|
+
SWARM_LANE_LABELS,
|
|
8
11
|
} from "../templates.ts";
|
|
9
12
|
|
|
10
13
|
describe("templates", () => {
|
|
@@ -102,9 +105,97 @@ describe("templates", () => {
|
|
|
102
105
|
assert.ok(comment.includes("duration:"));
|
|
103
106
|
});
|
|
104
107
|
|
|
105
|
-
it("handles empty data gracefully", () => {
|
|
108
|
+
it("handles empty data gracefully — no debug-artifact output", () => {
|
|
109
|
+
// Previous version only asserted `typeof === 'string'`, which the
|
|
110
|
+
// function signature already guarantees (tautology).
|
|
111
|
+
//
|
|
112
|
+
// The real invariant is: empty input must produce a string that
|
|
113
|
+
// is safe to post (or skip) without leaking a debug-stringified
|
|
114
|
+
// object. An empty string IS allowed here — callers are expected
|
|
115
|
+
// to gate on truthiness before posting ("skip if empty"). What
|
|
116
|
+
// must NOT happen is leaking 'undefined', '[object Object]',
|
|
117
|
+
// 'null', or a template-placeholder tell like '{{' / '}}'.
|
|
106
118
|
const comment = formatSummaryComment({});
|
|
107
119
|
assert.equal(typeof comment, "string");
|
|
120
|
+
assert.doesNotMatch(
|
|
121
|
+
comment,
|
|
122
|
+
/^undefined$|^\[object Object\]$|^null$/,
|
|
123
|
+
"empty-data comment must not be a debug-style stringified artifact",
|
|
124
|
+
);
|
|
125
|
+
assert.doesNotMatch(
|
|
126
|
+
comment,
|
|
127
|
+
/\{\{\s*\w+\s*\}\}/,
|
|
128
|
+
"empty-data comment must not leak unsubstituted {{placeholders}}",
|
|
129
|
+
);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("empty input produces empty comment — callers gate on truthiness", () => {
|
|
133
|
+
// Sister to the previous test: this locks in the current behaviour
|
|
134
|
+
// that empty input returns empty string, so a regression that
|
|
135
|
+
// unexpectedly starts emitting a non-empty default (which would
|
|
136
|
+
// then post spam comments for every bare-data milestone) fails.
|
|
137
|
+
const comment = formatSummaryComment({});
|
|
138
|
+
assert.equal(
|
|
139
|
+
comment,
|
|
140
|
+
"",
|
|
141
|
+
"empty data must return exactly '' so callers can `if (comment)` gate",
|
|
142
|
+
);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
describe("swarm delivery routines", () => {
|
|
147
|
+
it("formats lane PR bodies with impact, risks, rollback, and evidence", () => {
|
|
148
|
+
const body = formatSwarmLanePRBody({
|
|
149
|
+
lane: {
|
|
150
|
+
id: "writer",
|
|
151
|
+
branch: "lane/single-writer",
|
|
152
|
+
owner: "@owner",
|
|
153
|
+
latestCommit: "abc1234",
|
|
154
|
+
changedContracts: ["WriterToken"],
|
|
155
|
+
testEvidence: ["npm run typecheck:extensions"],
|
|
156
|
+
},
|
|
157
|
+
impactArea: "Single-writer UOK metadata.",
|
|
158
|
+
transitionRisks: ["Writer token lifecycle regression"],
|
|
159
|
+
rollbackPlan: ["Disable writer sequence enrichment"],
|
|
160
|
+
linkedIssue: 123,
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
assert.ok(body.includes("`lane/writer`"));
|
|
164
|
+
assert.ok(body.includes("Single-writer UOK metadata."));
|
|
165
|
+
assert.ok(body.includes("- [ ] Writer token lifecycle regression"));
|
|
166
|
+
assert.ok(body.includes("- [ ] Disable writer sequence enrichment"));
|
|
167
|
+
assert.ok(body.includes("- [ ] npm run typecheck:extensions"));
|
|
168
|
+
assert.ok(body.includes("Closes #123"));
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("formats release checklist bodies from lane state", () => {
|
|
172
|
+
const body = formatSwarmReleaseChecklistBody({
|
|
173
|
+
integrationBranch: "integration/uok-swarm",
|
|
174
|
+
lanes: [
|
|
175
|
+
{ id: "workflow", branch: "lane/workflow-engine", owner: "@a", latestCommit: "1111111" },
|
|
176
|
+
{ id: "state", branch: "lane/state-machine", blockers: ["matrix gap"] },
|
|
177
|
+
],
|
|
178
|
+
parityReport: "No critical mismatches.",
|
|
179
|
+
rollbackDrill: "Passed fallback drill.",
|
|
180
|
+
requiredChecks: ["unit", "integration"],
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
assert.ok(body.includes("`integration/uok-swarm`"));
|
|
184
|
+
assert.ok(body.includes("| `lane/workflow` | `lane/workflow-engine` | @a | `1111111` | ready |"));
|
|
185
|
+
assert.ok(body.includes("| `lane/state` | `lane/state-machine` | | | blocked |"));
|
|
186
|
+
assert.ok(body.includes("- [ ] UOK parity report attached or linked"));
|
|
187
|
+
assert.ok(body.includes("- [ ] unit"));
|
|
188
|
+
assert.ok(body.includes("Passed fallback drill."));
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it("declares expected swarm lane labels for generated GitHub routines", () => {
|
|
192
|
+
assert.deepEqual(Object.values(SWARM_LANE_LABELS), [
|
|
193
|
+
"lane/workflow",
|
|
194
|
+
"lane/state",
|
|
195
|
+
"lane/writer",
|
|
196
|
+
"lane/uok",
|
|
197
|
+
"lane/github",
|
|
198
|
+
]);
|
|
108
199
|
});
|
|
109
200
|
});
|
|
110
201
|
});
|
|
@@ -4,8 +4,9 @@ import type { ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
|
4
4
|
export default function (pi: ExtensionAPI) {
|
|
5
5
|
pi.on("session_start", async (_event, ctx) => {
|
|
6
6
|
ctx.ui.notify(
|
|
7
|
-
"google_search
|
|
8
|
-
"
|
|
7
|
+
"google_search is being extracted to @gsd-extensions/google-search " +
|
|
8
|
+
"(not yet published to npm). This stub will be replaced once the " +
|
|
9
|
+
"package is available. No action needed for now.",
|
|
9
10
|
"warning",
|
|
10
11
|
);
|
|
11
12
|
});
|
|
@@ -29,14 +29,16 @@ import {
|
|
|
29
29
|
} from "./phases.js";
|
|
30
30
|
import { debugLog } from "../debug-logger.js";
|
|
31
31
|
import { isInfrastructureError, isTransientCooldownError, getCooldownRetryAfterMs, COOLDOWN_FALLBACK_WAIT_MS, MAX_COOLDOWN_RETRIES } from "./infra-errors.js";
|
|
32
|
+
import { ModelPolicyDispatchBlockedError } from "../auto-model-selection.js";
|
|
32
33
|
import { resolveEngine } from "../engine-resolver.js";
|
|
33
34
|
import { logWarning } from "../workflow-logger.js";
|
|
34
35
|
import { gsdRoot } from "../paths.js";
|
|
36
|
+
import { atomicWriteSync } from "../atomic-write.js";
|
|
35
37
|
import { resolveUokFlags } from "../uok/flags.js";
|
|
36
38
|
import { scheduleSidecarQueue } from "../uok/execution-graph.js";
|
|
37
39
|
import { ExecutionGraphScheduler } from "../uok/execution-graph.js";
|
|
38
40
|
import type { UokGraphNode } from "../uok/contracts.js";
|
|
39
|
-
import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
41
|
+
import { readFileSync, writeFileSync, mkdirSync, unlinkSync } from "node:fs";
|
|
40
42
|
import { join } from "node:path";
|
|
41
43
|
|
|
42
44
|
// ── Stuck detection persistence (#3704) ──────────────────────────────────
|
|
@@ -82,12 +84,69 @@ function saveStuckState(basePath: string, state: LoopState): void {
|
|
|
82
84
|
}
|
|
83
85
|
}
|
|
84
86
|
|
|
87
|
+
// ── Custom workflow verification retry persistence ───────────────────────
|
|
88
|
+
// Custom workflows can request verification retries after a step runs. The
|
|
89
|
+
// retry budget must survive an auto-mode restart or a failing verifier can
|
|
90
|
+
// consume a fresh retry budget every session.
|
|
91
|
+
function customVerifyRetryStateDir(s: Pick<AutoSession, "activeRunDir" | "basePath">): string {
|
|
92
|
+
return s.activeRunDir ? join(s.activeRunDir, "runtime") : join(gsdRoot(s.basePath), "runtime");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function customVerifyRetryStatePath(s: Pick<AutoSession, "activeRunDir" | "basePath">): string {
|
|
96
|
+
return join(customVerifyRetryStateDir(s), "custom-verify-retries.json");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function hydrateCustomVerifyRetryCounts(s: AutoSession): Map<string, number> {
|
|
100
|
+
if (s.verificationRetryCount.size > 0) {
|
|
101
|
+
return s.verificationRetryCount;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
const raw = JSON.parse(readFileSync(customVerifyRetryStatePath(s), "utf-8"));
|
|
106
|
+
const counts = raw && typeof raw === "object" && raw.counts && typeof raw.counts === "object"
|
|
107
|
+
? raw.counts as Record<string, unknown>
|
|
108
|
+
: {};
|
|
109
|
+
for (const [key, value] of Object.entries(counts)) {
|
|
110
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
|
|
111
|
+
s.verificationRetryCount.set(key, Math.floor(value));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
} catch (err) {
|
|
115
|
+
debugLog("autoLoop", { phase: "load-custom-verify-retries-failed", error: err instanceof Error ? err.message : String(err) });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return s.verificationRetryCount;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function saveCustomVerifyRetryCounts(s: AutoSession): void {
|
|
122
|
+
const retryCounts = s.verificationRetryCount;
|
|
123
|
+
const filePath = customVerifyRetryStatePath(s);
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
if (!retryCounts || retryCounts.size === 0) {
|
|
127
|
+
unlinkSync(filePath);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
mkdirSync(customVerifyRetryStateDir(s), { recursive: true });
|
|
131
|
+
atomicWriteSync(filePath, JSON.stringify({
|
|
132
|
+
counts: Object.fromEntries(retryCounts),
|
|
133
|
+
updatedAt: new Date().toISOString(),
|
|
134
|
+
}) + "\n");
|
|
135
|
+
} catch (err) {
|
|
136
|
+
const code = err && typeof err === "object" && "code" in err ? (err as { code?: string }).code : undefined;
|
|
137
|
+
if (code !== "ENOENT") {
|
|
138
|
+
debugLog("autoLoop", { phase: "save-custom-verify-retries-failed", error: err instanceof Error ? err.message : String(err) });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
85
143
|
// ── Memory pressure monitoring (#3331) ──────────────────────────────────
|
|
86
144
|
// Check heap usage every N iterations and trigger graceful shutdown before
|
|
87
145
|
// the OS OOM killer sends SIGKILL. The threshold is 90% of the V8 heap
|
|
88
146
|
// limit (--max-old-space-size or default ~1.5-4GB depending on platform).
|
|
89
147
|
const MEMORY_CHECK_INTERVAL = 5; // check every 5 iterations
|
|
90
148
|
const MEMORY_PRESSURE_THRESHOLD = 0.85; // 85% of heap limit
|
|
149
|
+
const MAX_CUSTOM_ENGINE_VERIFY_RETRIES = 3;
|
|
91
150
|
|
|
92
151
|
type DispatchContract = "legacy-direct" | "uok-scheduler";
|
|
93
152
|
|
|
@@ -437,16 +496,51 @@ export async function autoLoop(
|
|
|
437
496
|
break;
|
|
438
497
|
}
|
|
439
498
|
if (verifyResult === "retry") {
|
|
440
|
-
|
|
499
|
+
const recoveryKey = `${iterData.unitType}/${iterData.unitId}`;
|
|
500
|
+
const retryCounts = hydrateCustomVerifyRetryCounts(s);
|
|
501
|
+
const attempts = (retryCounts.get(recoveryKey) ?? 0) + 1;
|
|
502
|
+
retryCounts.set(recoveryKey, attempts);
|
|
503
|
+
saveCustomVerifyRetryCounts(s);
|
|
504
|
+
debugLog("autoLoop", { phase: "custom-engine-verify-retry", iteration, unitId: iterData.unitId, attempts });
|
|
441
505
|
deps.uokObserver?.onPhaseResult("custom-engine", "retry", {
|
|
442
506
|
unitType: iterData.unitType,
|
|
443
507
|
unitId: iterData.unitId,
|
|
508
|
+
attempts,
|
|
444
509
|
});
|
|
510
|
+
if (attempts > MAX_CUSTOM_ENGINE_VERIFY_RETRIES) {
|
|
511
|
+
const recovery = await policy.recover(iterData.unitType, iterData.unitId, { basePath: s.basePath });
|
|
512
|
+
if (recovery.outcome === "pause") {
|
|
513
|
+
await deps.pauseAuto(ctx, pi);
|
|
514
|
+
finishTurn("paused", "manual-attention", recovery.reason ?? "custom-engine-verify-retry-exhausted");
|
|
515
|
+
break;
|
|
516
|
+
}
|
|
517
|
+
if (recovery.outcome === "skip") {
|
|
518
|
+
await deps.stopAuto(
|
|
519
|
+
ctx,
|
|
520
|
+
pi,
|
|
521
|
+
recovery.reason ??
|
|
522
|
+
`Custom workflow verification for ${iterData.unitId} requested skip after retry exhaustion, but the custom engine cannot reconcile skipped steps.`,
|
|
523
|
+
);
|
|
524
|
+
finishTurn("stopped", "manual-attention", "custom-engine-verify-retry-exhausted");
|
|
525
|
+
break;
|
|
526
|
+
}
|
|
527
|
+
const exhaustedReason =
|
|
528
|
+
`Custom workflow verification for ${iterData.unitId} requested retry ${attempts} times without passing.`;
|
|
529
|
+
await deps.stopAuto(
|
|
530
|
+
ctx,
|
|
531
|
+
pi,
|
|
532
|
+
recovery.outcome === "stop" && recovery.reason ? recovery.reason : exhaustedReason,
|
|
533
|
+
);
|
|
534
|
+
finishTurn("stopped", "manual-attention", "custom-engine-verify-retry-exhausted");
|
|
535
|
+
break;
|
|
536
|
+
}
|
|
445
537
|
finishTurn("retry");
|
|
446
538
|
continue;
|
|
447
539
|
}
|
|
448
540
|
|
|
449
541
|
// Verification passed — mark step complete
|
|
542
|
+
s.verificationRetryCount?.delete(`${iterData.unitType}/${iterData.unitId}`);
|
|
543
|
+
saveCustomVerifyRetryCounts(s);
|
|
450
544
|
debugLog("autoLoop", { phase: "custom-engine-reconcile", iteration, unitId: iterData.unitId });
|
|
451
545
|
const reconcileResult = await engine.reconcile(engineState, {
|
|
452
546
|
unitType: iterData.unitType,
|
|
@@ -610,6 +704,52 @@ export async function autoLoop(
|
|
|
610
704
|
// runFinalize leave the journal incomplete, making diagnosis harder.
|
|
611
705
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId, seq: nextSeq(), eventType: "iteration-end", data: { iteration, error: msg } });
|
|
612
706
|
|
|
707
|
+
// ── Pre-send model-policy block: not a retryable error (#4959 / #4850) ──
|
|
708
|
+
// The model-policy gate runs before the prompt is sent. When every
|
|
709
|
+
// candidate model is denied (cross-provider disabled + flat-rate
|
|
710
|
+
// baseline + tool-policy denial), retrying the same unit produces the
|
|
711
|
+
// same denial — burning the consecutive-error budget toward a 3-strike
|
|
712
|
+
// hard stop and corrupting auto-mode state. Pause for user attention
|
|
713
|
+
// instead, with the per-model deny reasons surfaced from the typed
|
|
714
|
+
// error.
|
|
715
|
+
if (loopErr instanceof ModelPolicyDispatchBlockedError) {
|
|
716
|
+
debugLog("autoLoop", {
|
|
717
|
+
phase: "model-policy-blocked",
|
|
718
|
+
iteration,
|
|
719
|
+
unitType: loopErr.unitType,
|
|
720
|
+
unitId: loopErr.unitId,
|
|
721
|
+
reasons: loopErr.reasons,
|
|
722
|
+
});
|
|
723
|
+
ctx.ui.notify(
|
|
724
|
+
`Auto-mode paused: model-policy denied dispatch for ${loopErr.unitType}/${loopErr.unitId}. ${msg}`,
|
|
725
|
+
"error",
|
|
726
|
+
);
|
|
727
|
+
deps.emitJournalEvent({
|
|
728
|
+
ts: new Date().toISOString(),
|
|
729
|
+
flowId,
|
|
730
|
+
seq: nextSeq(),
|
|
731
|
+
eventType: "unit-end",
|
|
732
|
+
data: {
|
|
733
|
+
unitType: loopErr.unitType,
|
|
734
|
+
unitId: loopErr.unitId,
|
|
735
|
+
status: "blocked",
|
|
736
|
+
reason: "model-policy-dispatch-blocked",
|
|
737
|
+
reasons: loopErr.reasons,
|
|
738
|
+
},
|
|
739
|
+
});
|
|
740
|
+
// Carry the blocked unit identity into the turn-result observer:
|
|
741
|
+
// the throw originated inside dispatch, so observedUnitType/Id were
|
|
742
|
+
// not assigned by the success path at lines 453/631/647 — but the
|
|
743
|
+
// typed error already names the unit (#4959 / CodeRabbit).
|
|
744
|
+
observedUnitType = loopErr.unitType;
|
|
745
|
+
observedUnitId = loopErr.unitId;
|
|
746
|
+
await deps.pauseAuto(ctx, pi);
|
|
747
|
+
finishTurn("paused", "manual-attention", msg);
|
|
748
|
+
// Do NOT increment consecutiveErrors — the failure is configuration,
|
|
749
|
+
// not a transient runtime fault.
|
|
750
|
+
break;
|
|
751
|
+
}
|
|
752
|
+
|
|
613
753
|
// ── Infrastructure errors: immediate stop, no retry ──
|
|
614
754
|
// These are unrecoverable (disk full, OOM, etc.). Retrying just burns
|
|
615
755
|
// LLM budget on guaranteed failures.
|