gsd-pi 2.77.0-dev.1d17f366c → 2.77.0-dev.2daa994b6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/headless.js +25 -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/gsd/auto/phases.js +5 -18
- package/dist/resources/extensions/gsd/auto/session.js +6 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +37 -8
- package/dist/resources/extensions/gsd/auto-post-unit.js +79 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +372 -104
- package/dist/resources/extensions/gsd/auto-start.js +75 -24
- package/dist/resources/extensions/gsd/auto.js +34 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +9 -1
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +7 -1
- 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/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/forensics.js +106 -0
- package/dist/resources/extensions/gsd/gsd-db.js +1 -1
- package/dist/resources/extensions/gsd/guided-flow.js +2 -4
- 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/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 +5 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/dist/resources/extensions/gsd/service-tier.js +5 -2
- 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/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 +334 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +51 -0
- 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 +17 -17
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
- 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 +1 -3
- 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/workflow-tools.test.ts +80 -39
- 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/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 +29 -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/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 +39 -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/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/__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/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/image.test.js +6 -5
- package/packages/pi-tui/dist/components/image.test.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/image.test.ts +10 -5
- 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/tests/stream-adapter.test.ts +80 -72
- 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/phases.ts +6 -17
- package/src/resources/extensions/gsd/auto/session.ts +7 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +40 -8
- package/src/resources/extensions/gsd/auto-post-unit.ts +81 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +385 -93
- package/src/resources/extensions/gsd/auto-start.ts +97 -4
- package/src/resources/extensions/gsd/auto.ts +37 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +9 -1
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +7 -1
- 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/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/forensics.ts +118 -1
- package/src/resources/extensions/gsd/git-service.ts +16 -0
- package/src/resources/extensions/gsd/gsd-db.ts +1 -1
- package/src/resources/extensions/gsd/guided-flow.ts +2 -4
- 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/model-cost-table.ts +3 -0
- package/src/resources/extensions/gsd/model-router.ts +6 -0
- 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 +5 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/src/resources/extensions/gsd/service-tier.ts +5 -2
- 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/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +25 -292
- 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-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 +8 -4
- 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/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/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/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/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/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 +1 -1
- 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/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/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/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 +22 -16
- 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/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/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/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/smart-entry-draft.test.ts +2 -1
- 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-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/unit-context-composer.test.ts +355 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +203 -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 -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/zombie-gsd-state.test.ts +80 -96
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +8 -2
- package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +492 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +53 -0
- 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/{vidAVJkURvTJ0_V2-64ro → gYYky7yfxW8txb9vU2TrJ}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{vidAVJkURvTJ0_V2-64ro → gYYky7yfxW8txb9vU2TrJ}/_ssgManifest.js +0 -0
|
@@ -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
|
});
|
|
@@ -105,9 +105,41 @@ describe("templates", () => {
|
|
|
105
105
|
assert.ok(comment.includes("duration:"));
|
|
106
106
|
});
|
|
107
107
|
|
|
108
|
-
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 '{{' / '}}'.
|
|
109
118
|
const comment = formatSummaryComment({});
|
|
110
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
|
+
);
|
|
111
143
|
});
|
|
112
144
|
});
|
|
113
145
|
|
|
@@ -26,12 +26,12 @@ import {
|
|
|
26
26
|
import { detectStuck } from "./detect-stuck.js";
|
|
27
27
|
import { runUnit } from "./run-unit.js";
|
|
28
28
|
import { debugLog } from "../debug-logger.js";
|
|
29
|
-
import { PROJECT_FILES } from "../detection.js";
|
|
29
|
+
import { PROJECT_FILES, hasProjectFileInAncestor } from "../detection.js";
|
|
30
30
|
import { MergeConflictError } from "../git-service.js";
|
|
31
31
|
import { setCurrentPhase, clearCurrentPhase } from "../../shared/gsd-phase-state.js";
|
|
32
32
|
import { pauseAutoForProviderError } from "../provider-error-pause.js";
|
|
33
33
|
import { resumeAutoAfterProviderDelay } from "../bootstrap/provider-error-resume.js";
|
|
34
|
-
import { join, basename
|
|
34
|
+
import { join, basename } from "node:path";
|
|
35
35
|
import { existsSync, cpSync, readdirSync } from "node:fs";
|
|
36
36
|
import {
|
|
37
37
|
logWarning,
|
|
@@ -1378,21 +1378,10 @@ export async function runUnitPhase(
|
|
|
1378
1378
|
// Monorepo support (#2347): if no project files in the worktree directory,
|
|
1379
1379
|
// walk parent directories up to the filesystem root. In monorepos,
|
|
1380
1380
|
// package.json / Cargo.toml etc. live in a parent directory.
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
while (checkDir !== root) {
|
|
1386
|
-
// Stop at git repository boundary — ancestors above the repo root
|
|
1387
|
-
// (e.g. ~ or /usr/local) may contain unrelated project files.
|
|
1388
|
-
if (deps.existsSync(join(checkDir, ".git"))) break;
|
|
1389
|
-
if (PROJECT_FILES.some((f) => deps.existsSync(join(checkDir, f)))) {
|
|
1390
|
-
hasProjectFileInParent = true;
|
|
1391
|
-
break;
|
|
1392
|
-
}
|
|
1393
|
-
checkDir = dirname(checkDir);
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1381
|
+
const hasProjectFileInParent =
|
|
1382
|
+
!hasProjectFile && !hasSrcDir && !hasXcodeBundle
|
|
1383
|
+
? hasProjectFileInAncestor(s.basePath, deps.existsSync)
|
|
1384
|
+
: false;
|
|
1396
1385
|
if (!hasProjectFile && !hasSrcDir && !hasXcodeBundle && !hasProjectFileInParent) {
|
|
1397
1386
|
// Greenfield projects won't have project files yet — the first task creates them.
|
|
1398
1387
|
// Log a warning but allow execution to proceed. The .git check above is sufficient
|
|
@@ -178,6 +178,12 @@ export class AutoSession {
|
|
|
178
178
|
* stopAuto does not attempt the same merge a second time (#2645). */
|
|
179
179
|
milestoneMergedInPhases = false;
|
|
180
180
|
|
|
181
|
+
// #4765 — slice-cadence collapse: main-branch SHAs at the moment each
|
|
182
|
+
// milestone's first slice merge began. Used by resquashMilestoneOnMain at
|
|
183
|
+
// milestone completion to collapse N slice commits into one. Cleared when
|
|
184
|
+
// the milestone finishes (or resquash runs).
|
|
185
|
+
milestoneStartShas: Map<string, string> = new Map();
|
|
186
|
+
|
|
181
187
|
// ── Dispatch circuit breakers ──────────────────────────────────────
|
|
182
188
|
rewriteAttemptCount = 0;
|
|
183
189
|
/** Tracks consecutive bootstrap attempts that found phase === "complete".
|
|
@@ -299,6 +305,7 @@ export class AutoSession {
|
|
|
299
305
|
this.lastGitActionStatus = null;
|
|
300
306
|
this.isolationDegraded = false;
|
|
301
307
|
this.milestoneMergedInPhases = false;
|
|
308
|
+
this.milestoneStartShas = new Map();
|
|
302
309
|
this.checkpointSha = null;
|
|
303
310
|
|
|
304
311
|
// Signal handler
|
|
@@ -59,6 +59,7 @@ import {
|
|
|
59
59
|
import { resolveModelWithFallbacksForUnit } from "./preferences-models.js";
|
|
60
60
|
import { resolveUokFlags } from "./uok/flags.js";
|
|
61
61
|
import { selectReactiveDispatchBatch } from "./uok/execution-graph.js";
|
|
62
|
+
import { getMilestonePipelineVariant } from "./milestone-scope-classifier.js";
|
|
62
63
|
import { EXECUTION_ENTRY_PHASES, hasFinalizedMilestoneContext } from "./uok/plan-v2.js";
|
|
63
64
|
|
|
64
65
|
// ─── Types ────────────────────────────────────────────────────────────────
|
|
@@ -90,6 +91,18 @@ export interface DispatchContext {
|
|
|
90
91
|
modelRegistry?: MinimalModelRegistry;
|
|
91
92
|
}
|
|
92
93
|
|
|
94
|
+
type ReassessmentChecker = typeof checkNeedsReassessment;
|
|
95
|
+
|
|
96
|
+
let reassessmentChecker: ReassessmentChecker = checkNeedsReassessment;
|
|
97
|
+
|
|
98
|
+
export function setReassessmentCheckerForTest(checker: ReassessmentChecker): () => void {
|
|
99
|
+
const previous = reassessmentChecker;
|
|
100
|
+
reassessmentChecker = checker;
|
|
101
|
+
return () => {
|
|
102
|
+
reassessmentChecker = previous;
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
93
106
|
export interface DispatchRule {
|
|
94
107
|
/** Human-readable name for debugging and test identification */
|
|
95
108
|
name: string;
|
|
@@ -371,11 +384,15 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
371
384
|
name: "reassess-roadmap (post-completion)",
|
|
372
385
|
match: async ({ state, mid, midTitle, basePath, prefs }) => {
|
|
373
386
|
if (prefs?.phases?.skip_reassess) return null;
|
|
374
|
-
// Default reassess_after_slice to
|
|
375
|
-
// is
|
|
376
|
-
|
|
387
|
+
// Default reassess_after_slice to false per ADR-003 §4 — most reassess
|
|
388
|
+
// units conclude "roadmap is fine" and burn a session for no change.
|
|
389
|
+
// The plan-slice prompt now carries a reassessment preamble so the
|
|
390
|
+
// next slice's planner does JIT roadmap verification at zero extra
|
|
391
|
+
// cost. Opt-in via explicit `reassess_after_slice: true` (e.g.
|
|
392
|
+
// burn-max profile) when you want the dedicated reassess session.
|
|
393
|
+
const reassessEnabled = prefs?.phases?.reassess_after_slice ?? false;
|
|
377
394
|
if (!reassessEnabled) return null;
|
|
378
|
-
const needsReassess = await
|
|
395
|
+
const needsReassess = await reassessmentChecker(basePath, mid, state);
|
|
379
396
|
if (!needsReassess) return null;
|
|
380
397
|
return {
|
|
381
398
|
action: "dispatch",
|
|
@@ -482,6 +499,11 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
482
499
|
match: async ({ state, mid, midTitle, basePath, prefs }) => {
|
|
483
500
|
if (state.phase !== "planning") return null;
|
|
484
501
|
if (prefs?.phases?.skip_research || prefs?.phases?.skip_slice_research) return null;
|
|
502
|
+
// #4781 phase 2: trivial-scope milestones skip dedicated slice research.
|
|
503
|
+
// plan-slice absorbs the lightweight discovery a trivial deliverable
|
|
504
|
+
// needs. Null result (DB unavailable / unknown) falls through to today's
|
|
505
|
+
// behavior.
|
|
506
|
+
if (await getMilestonePipelineVariant(mid) === "trivial") return null;
|
|
485
507
|
|
|
486
508
|
// Load roadmap to find all slices
|
|
487
509
|
const roadmapFile = resolveMilestoneFile(basePath, mid, "ROADMAP");
|
|
@@ -538,6 +560,8 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
538
560
|
// Phase skip: skip research when preference or profile says so
|
|
539
561
|
if (prefs?.phases?.skip_research || prefs?.phases?.skip_slice_research)
|
|
540
562
|
return null;
|
|
563
|
+
// #4781 phase 2: trivial-scope milestones skip dedicated slice research.
|
|
564
|
+
if (await getMilestonePipelineVariant(mid) === "trivial") return null;
|
|
541
565
|
if (!state.activeSlice) return missingSliceStop(mid, state.phase);
|
|
542
566
|
const sid = state.activeSlice!.id;
|
|
543
567
|
const sTitle = state.activeSlice!.title;
|
|
@@ -890,8 +914,13 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
890
914
|
};
|
|
891
915
|
}
|
|
892
916
|
|
|
893
|
-
//
|
|
894
|
-
|
|
917
|
+
// #4781 phase 2: trivial-scope milestones skip the dedicated validate
|
|
918
|
+
// unit — complete-milestone's own verification steps (3/4/5 in the
|
|
919
|
+
// closer prompt) are sufficient proof for contained deliverables.
|
|
920
|
+
const trivialVariant = await getMilestonePipelineVariant(mid) === "trivial";
|
|
921
|
+
|
|
922
|
+
// Skip preference OR trivial scope: write a minimal pass-through VALIDATION file.
|
|
923
|
+
if (prefs?.phases?.skip_milestone_validation || trivialVariant) {
|
|
895
924
|
const mDir = resolveMilestonePath(basePath, mid);
|
|
896
925
|
if (mDir) {
|
|
897
926
|
if (!existsSync(mDir)) mkdirSync(mDir, { recursive: true });
|
|
@@ -899,15 +928,18 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
899
928
|
mDir,
|
|
900
929
|
buildMilestoneFileName(mid, "VALIDATION"),
|
|
901
930
|
);
|
|
931
|
+
const skipSource = trivialVariant
|
|
932
|
+
? "trivial-scope pipeline variant (#4781)"
|
|
933
|
+
: "`skip_milestone_validation` preference";
|
|
902
934
|
const content = [
|
|
903
935
|
"---",
|
|
904
936
|
"verdict: pass",
|
|
905
937
|
"remediation_round: 0",
|
|
906
938
|
"---",
|
|
907
939
|
"",
|
|
908
|
-
"# Milestone Validation (skipped
|
|
940
|
+
"# Milestone Validation (skipped)",
|
|
909
941
|
"",
|
|
910
|
-
|
|
942
|
+
`Milestone validation was skipped via ${skipSource}.`,
|
|
911
943
|
].join("\n");
|
|
912
944
|
writeFileSync(validationPath, content, "utf-8");
|
|
913
945
|
}
|
|
@@ -618,6 +618,87 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
618
618
|
clearReactiveState(s.basePath, mid, sid);
|
|
619
619
|
}
|
|
620
620
|
});
|
|
621
|
+
|
|
622
|
+
// #4765 — slice-cadence collapse. When `git.collapse_cadence: "slice"`
|
|
623
|
+
// is set, squash-merge the slice's commits from the milestone branch
|
|
624
|
+
// onto main right here, so orphan risk shrinks from milestone-size to
|
|
625
|
+
// slice-size. Only runs in worktree isolation mode — the feature needs
|
|
626
|
+
// a milestone branch to squash from.
|
|
627
|
+
let sliceMergeStopped = false;
|
|
628
|
+
await runSafely("postUnit", "slice-cadence-merge", async () => {
|
|
629
|
+
const prefsResult = loadEffectiveGSDPreferences(s.basePath);
|
|
630
|
+
const prefs = prefsResult?.preferences;
|
|
631
|
+
const { getCollapseCadence, mergeSliceToMain } = await import("./slice-cadence.js");
|
|
632
|
+
if (getCollapseCadence(prefs) !== "slice") return;
|
|
633
|
+
if (prefs?.git?.isolation !== "worktree") return;
|
|
634
|
+
if (s.isolationDegraded) return;
|
|
635
|
+
|
|
636
|
+
const projectRoot = s.originalBasePath || s.basePath;
|
|
637
|
+
const { milestone: mid, slice: sid } = parseUnitId(unit.id);
|
|
638
|
+
if (!mid || !sid) return;
|
|
639
|
+
|
|
640
|
+
// Record the milestone start SHA before the first slice merge, so
|
|
641
|
+
// resquashMilestoneOnMain has a target at milestone completion.
|
|
642
|
+
// Resolve main branch dynamically — hard-coding "main" breaks repos
|
|
643
|
+
// that use "master" or a custom default branch.
|
|
644
|
+
if (!s.milestoneStartShas.has(mid)) {
|
|
645
|
+
try {
|
|
646
|
+
const { nativeDetectMainBranch } = await import("./native-git-bridge.js");
|
|
647
|
+
const mainBranch = nativeDetectMainBranch(projectRoot);
|
|
648
|
+
const { execFileSync } = await import("node:child_process");
|
|
649
|
+
const sha = execFileSync("git", ["rev-parse", mainBranch], {
|
|
650
|
+
cwd: projectRoot, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8",
|
|
651
|
+
}).trim();
|
|
652
|
+
if (sha) s.milestoneStartShas.set(mid, sha);
|
|
653
|
+
} catch (err) {
|
|
654
|
+
logWarning("engine", `slice-cadence: failed to record milestone start SHA: ${err instanceof Error ? err.message : String(err)}`);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
try {
|
|
659
|
+
const result = mergeSliceToMain(projectRoot, mid, sid);
|
|
660
|
+
if (result.skipped) {
|
|
661
|
+
logWarning("engine", `slice-cadence: merge skipped for ${sid} — ${result.skippedReason}`);
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
ctx.ui.notify(
|
|
665
|
+
`slice-cadence: ${sid} merged to main (${result.durationMs}ms).`,
|
|
666
|
+
"info",
|
|
667
|
+
);
|
|
668
|
+
} catch (err) {
|
|
669
|
+
const { MergeConflictError } = await import("./git-service.js");
|
|
670
|
+
if (err instanceof MergeConflictError) {
|
|
671
|
+
ctx.ui.notify(
|
|
672
|
+
`slice-cadence merge conflict in ${sid}: ${err.conflictedFiles.join(", ")}. ` +
|
|
673
|
+
`Resolve manually on main and run \`/gsd auto\` to resume.`,
|
|
674
|
+
"error",
|
|
675
|
+
);
|
|
676
|
+
// Stop auto AND signal the outer postUnit flow to exit early.
|
|
677
|
+
// Without the flag, subsequent hooks (triage, rogue detection,
|
|
678
|
+
// DB writes) would keep running against a conflicted main
|
|
679
|
+
// checkout after the loop was already told to stop.
|
|
680
|
+
const { stopAuto } = await import("./auto.js");
|
|
681
|
+
await stopAuto(ctx, undefined, `slice-merge-conflict on ${sid}`);
|
|
682
|
+
sliceMergeStopped = true;
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
logError("engine", `slice-cadence merge failed for ${sid}`, {
|
|
686
|
+
error: err instanceof Error ? err.message : String(err),
|
|
687
|
+
});
|
|
688
|
+
// Non-conflict failures (dirty main, rev-walk error, etc.) can
|
|
689
|
+
// leave the checkout in an unexpected state. Stop auto-mode so
|
|
690
|
+
// the next slice doesn't dispatch on top of it.
|
|
691
|
+
const { stopAuto } = await import("./auto.js");
|
|
692
|
+
await stopAuto(ctx, undefined, `slice-merge-error on ${sid}`);
|
|
693
|
+
sliceMergeStopped = true;
|
|
694
|
+
}
|
|
695
|
+
});
|
|
696
|
+
// Exit early after stopAuto so the rest of post-unit processing
|
|
697
|
+
// (triage, rogue detection, hook dispatch, DB writes) doesn't run
|
|
698
|
+
// against a conflicted main checkout. Return "dispatched" to match
|
|
699
|
+
// the convention used by other stop/pauseAuto paths in this function
|
|
700
|
+
// (see signal handling earlier: stop/pause also return "dispatched").
|
|
701
|
+
if (sliceMergeStopped) return "dispatched";
|
|
621
702
|
}
|
|
622
703
|
|
|
623
704
|
// Post-triage: execute actionable resolutions
|