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
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
// GSD-2 — Milestone scope classifier (#4781 / ADR-003 companion).
|
|
2
|
+
//
|
|
3
|
+
// Pure heuristics over milestone planning fields. Produces a PipelineVariant
|
|
4
|
+
// that downstream dispatch logic can use to shape the auto-mode sequence.
|
|
5
|
+
// No LLM calls, no file I/O, sub-millisecond.
|
|
6
|
+
//
|
|
7
|
+
// Distinct from `complexity-classifier.ts`, which decides *model tier*
|
|
8
|
+
// (light/standard/heavy) for an individual unit. This module decides
|
|
9
|
+
// *pipeline topology* for an entire milestone at plan-milestone time.
|
|
10
|
+
//
|
|
11
|
+
// This file ships the classifier in isolation. Dispatch-side wiring
|
|
12
|
+
// lands in follow-up PRs so the classification contract can be reviewed
|
|
13
|
+
// and tested before any behavior change reaches users.
|
|
14
|
+
// ─── Keyword sets ─────────────────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* Override keywords that force `standard` (at minimum) regardless of
|
|
17
|
+
* apparent triviality. Presence of any of these signals work that is
|
|
18
|
+
* either security-sensitive, irreversible, or requires runtime verification
|
|
19
|
+
* a "trivial" pipeline would skip.
|
|
20
|
+
*
|
|
21
|
+
* Matched as case-insensitive word-boundary substrings. Conservative — err
|
|
22
|
+
* on the side of including a keyword; over-classifying to `standard` costs
|
|
23
|
+
* units, under-classifying could ship broken auth/security/migration work.
|
|
24
|
+
*/
|
|
25
|
+
const OVERRIDE_KEYWORDS = [
|
|
26
|
+
// Security-sensitive
|
|
27
|
+
"security", "auth", "authn", "authz", "authentication", "authorization",
|
|
28
|
+
"credential", "secret", "password", "token", "oauth", "encrypt", "decrypt",
|
|
29
|
+
"vulnerability", "exploit", "permission", "rbac", "acl",
|
|
30
|
+
// Data-migration / irreversible
|
|
31
|
+
"migration", "migrate", "schema change", "data migration",
|
|
32
|
+
"backfill", "drop column", "drop table",
|
|
33
|
+
// Compliance / regulatory
|
|
34
|
+
"compliance", "gdpr", "hipaa", "soc2", "pci",
|
|
35
|
+
// Infra / deploy — runtime verification needed
|
|
36
|
+
"deploy", "rollout", "canary", "production database",
|
|
37
|
+
];
|
|
38
|
+
/**
|
|
39
|
+
* Keywords that contribute to `complex` classification on their own.
|
|
40
|
+
* Different from OVERRIDE_KEYWORDS in that a single match bumps to
|
|
41
|
+
* complex, not just to standard.
|
|
42
|
+
*/
|
|
43
|
+
const COMPLEX_KEYWORDS = [
|
|
44
|
+
"multi-service", "distributed", "consensus", "saga", "eventual consistency",
|
|
45
|
+
"breaking change", "api contract change", "schema redesign",
|
|
46
|
+
"architect", "architecture", "refactor core",
|
|
47
|
+
];
|
|
48
|
+
/**
|
|
49
|
+
* Trivial-signal keywords: presence strongly suggests a simple, contained
|
|
50
|
+
* deliverable. Only effective when combined with low file count / no tests
|
|
51
|
+
* / no override keywords.
|
|
52
|
+
*/
|
|
53
|
+
const TRIVIAL_KEYWORDS = [
|
|
54
|
+
"single file", "one file", "static html", "static page",
|
|
55
|
+
"one-page", "landing page", "readme", "docs only", "typo", "rename",
|
|
56
|
+
"spelling", "comment", "changelog",
|
|
57
|
+
// Browser-only / no-build deliverable shapes (b23 forensic case).
|
|
58
|
+
"pure html", "browser-based", "no build step", "no build tooling",
|
|
59
|
+
"localstorage", "client-only", "no backend", "no server", "no backend.",
|
|
60
|
+
];
|
|
61
|
+
// ─── Heuristics ───────────────────────────────────────────────────────────
|
|
62
|
+
/**
|
|
63
|
+
* Estimate how many distinct files the milestone will touch, based on
|
|
64
|
+
* explicit mentions in the input text. Returns `null` when no hint is
|
|
65
|
+
* discoverable — callers should treat that as "unknown, no signal."
|
|
66
|
+
*/
|
|
67
|
+
function extractFileCountHint(text) {
|
|
68
|
+
// Explicit phrasing: "a single file", "two files", "3 files"
|
|
69
|
+
const singleFileMatch = /\b(a|one|single)\s+(file|page)\b/i.test(text);
|
|
70
|
+
if (singleFileMatch)
|
|
71
|
+
return 1;
|
|
72
|
+
const digitMatch = text.match(/\b(\d+)\s+files?\b/i);
|
|
73
|
+
if (digitMatch) {
|
|
74
|
+
const n = parseInt(digitMatch[1], 10);
|
|
75
|
+
if (!Number.isNaN(n))
|
|
76
|
+
return n;
|
|
77
|
+
}
|
|
78
|
+
const wordMatch = text.match(/\b(two|three|four|five|six|seven|eight|nine|ten)\s+files?\b/i);
|
|
79
|
+
if (wordMatch) {
|
|
80
|
+
const wordMap = {
|
|
81
|
+
two: 2, three: 3, four: 4, five: 5,
|
|
82
|
+
six: 6, seven: 7, eight: 8, nine: 9, ten: 10,
|
|
83
|
+
};
|
|
84
|
+
return wordMap[wordMatch[1].toLowerCase()] ?? null;
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
function escapeRegExp(value) {
|
|
89
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
90
|
+
}
|
|
91
|
+
function containsAnyKeyword(haystack, keywords) {
|
|
92
|
+
const lower = haystack.toLowerCase();
|
|
93
|
+
const hits = [];
|
|
94
|
+
for (const kw of keywords) {
|
|
95
|
+
// Word-boundary match to prevent substring collisions (e.g. "auth"
|
|
96
|
+
// must not match "author", "api" must not match "capital"). Phrases
|
|
97
|
+
// containing non-word characters (hyphens, slashes) still work because
|
|
98
|
+
// `\b` sits at the word-char / non-word-char transition, so
|
|
99
|
+
// `\bbrowser-based\b` matches "browser-based" bounded by whitespace
|
|
100
|
+
// or punctuation on either side.
|
|
101
|
+
const pattern = new RegExp(String.raw `\b${escapeRegExp(kw)}\b`, "i");
|
|
102
|
+
if (pattern.test(lower))
|
|
103
|
+
hits.push(kw);
|
|
104
|
+
}
|
|
105
|
+
return hits;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* True when `term` appears in the text without an immediately preceding
|
|
109
|
+
* negator (no / without / not / zero / skip) in the same clause. Used to
|
|
110
|
+
* keep phrases like "no backend" or "no tests" from flipping a trivial-
|
|
111
|
+
* class milestone to standard. Best-effort; imperfect English parsing,
|
|
112
|
+
* biased toward false negatives (if unsure, treats term as present —
|
|
113
|
+
* which routes to standard, the safe pipeline).
|
|
114
|
+
*/
|
|
115
|
+
function mentionsWithoutNegation(text, term) {
|
|
116
|
+
const lower = text.toLowerCase();
|
|
117
|
+
const termPattern = new RegExp(String.raw `\b${term}\b`, "gi");
|
|
118
|
+
const matches = Array.from(lower.matchAll(termPattern));
|
|
119
|
+
for (const m of matches) {
|
|
120
|
+
const start = m.index ?? 0;
|
|
121
|
+
const windowStart = Math.max(0, start - 30);
|
|
122
|
+
const window = lower.slice(windowStart, start);
|
|
123
|
+
// Negator anywhere in the 30-char lookback window counts as negation —
|
|
124
|
+
// covers "no backend", "without a server", "not using api", "zero
|
|
125
|
+
// dependencies on an api". If a sentence break intervenes between the
|
|
126
|
+
// negator and the term, treat as a different clause (positive mention).
|
|
127
|
+
const hasNegator = /(^|[^a-z0-9])(no|without|not|zero|skip(s|ping)?|drops?)\b/i.test(window);
|
|
128
|
+
const hasSentenceBreak = /[.;!?]/.test(window);
|
|
129
|
+
if (hasNegator && !hasSentenceBreak)
|
|
130
|
+
continue;
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
function mentionsTests(haystack) {
|
|
136
|
+
return mentionsWithoutNegation(haystack, "test")
|
|
137
|
+
|| mentionsWithoutNegation(haystack, "tests")
|
|
138
|
+
|| mentionsWithoutNegation(haystack, "testing")
|
|
139
|
+
|| mentionsWithoutNegation(haystack, "spec")
|
|
140
|
+
|| mentionsWithoutNegation(haystack, "unit test")
|
|
141
|
+
|| mentionsWithoutNegation(haystack, "integration test");
|
|
142
|
+
}
|
|
143
|
+
function mentionsBackend(haystack) {
|
|
144
|
+
return mentionsWithoutNegation(haystack, "api")
|
|
145
|
+
|| mentionsWithoutNegation(haystack, "backend")
|
|
146
|
+
|| mentionsWithoutNegation(haystack, "server")
|
|
147
|
+
|| mentionsWithoutNegation(haystack, "database")
|
|
148
|
+
|| mentionsWithoutNegation(haystack, "endpoint");
|
|
149
|
+
}
|
|
150
|
+
// ─── DB adapter ───────────────────────────────────────────────────────────
|
|
151
|
+
/**
|
|
152
|
+
* Shape adapter: convert a milestone DB row into the classifier input
|
|
153
|
+
* object. Keeps `milestone-scope-classifier.ts` free of DB types at the
|
|
154
|
+
* module boundary — callers can either use this helper or hand-build the
|
|
155
|
+
* input themselves (e.g. from plan-milestone tool params before insert).
|
|
156
|
+
*/
|
|
157
|
+
export function milestoneRowToScopeInput(row) {
|
|
158
|
+
return {
|
|
159
|
+
title: row.title,
|
|
160
|
+
vision: row.vision,
|
|
161
|
+
successCriteria: row.success_criteria,
|
|
162
|
+
keyRisks: row.key_risks,
|
|
163
|
+
definitionOfDone: row.definition_of_done,
|
|
164
|
+
requirementCoverage: row.requirement_coverage,
|
|
165
|
+
verificationContract: row.verification_contract,
|
|
166
|
+
verificationIntegration: row.verification_integration,
|
|
167
|
+
verificationOperational: row.verification_operational,
|
|
168
|
+
verificationUat: row.verification_uat,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Compute the pipeline variant for a milestone by reading its planning
|
|
173
|
+
* fields from the DB and running the classifier. Returns `null` when
|
|
174
|
+
* classification is unavailable (DB closed, milestone missing, unexpected
|
|
175
|
+
* error) — callers MUST treat null as "run the full pipeline" so a
|
|
176
|
+
* classification failure never silently downshifts dispatch.
|
|
177
|
+
*/
|
|
178
|
+
export async function getMilestonePipelineVariant(mid) {
|
|
179
|
+
try {
|
|
180
|
+
const { isDbAvailable, getMilestone } = await import("./gsd-db.js");
|
|
181
|
+
if (!isDbAvailable())
|
|
182
|
+
return null;
|
|
183
|
+
const row = getMilestone(mid);
|
|
184
|
+
if (!row)
|
|
185
|
+
return null;
|
|
186
|
+
return classifyMilestoneScope(milestoneRowToScopeInput(row)).variant;
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// ─── Public API ───────────────────────────────────────────────────────────
|
|
193
|
+
/**
|
|
194
|
+
* Classify a milestone's pipeline variant based on its planning inputs.
|
|
195
|
+
*
|
|
196
|
+
* Precedence (matches implementation order — complex-first so that
|
|
197
|
+
* security-sensitive architecture refactors correctly route to complex
|
|
198
|
+
* rather than standard; the override hit is still recorded in
|
|
199
|
+
* `signals.triggeredOverride` for telemetry):
|
|
200
|
+
* 1. Complex-signal keyword OR ≥ 8 file hint OR architecture/refactor-core
|
|
201
|
+
* language → `complex`.
|
|
202
|
+
* 2. Override keyword → `standard` (at minimum). Prevents trivial
|
|
203
|
+
* misclassification of security / auth / migration work.
|
|
204
|
+
* 3. Trivial-signal keyword AND ≤ 2 file hint AND no tests mentioned AND
|
|
205
|
+
* no backend mentioned → `trivial`.
|
|
206
|
+
* 4. Otherwise → `standard`.
|
|
207
|
+
*
|
|
208
|
+
* Ambiguity → `standard` (today's default). Safe to run the full pipeline.
|
|
209
|
+
*/
|
|
210
|
+
export function classifyMilestoneScope(input) {
|
|
211
|
+
const haystack = [
|
|
212
|
+
input.title ?? "",
|
|
213
|
+
input.vision ?? "",
|
|
214
|
+
(input.successCriteria ?? []).join("\n"),
|
|
215
|
+
(input.keyRisks ?? []).map(r => `${r.risk ?? ""} ${r.whyItMatters ?? ""}`).join("\n"),
|
|
216
|
+
(input.definitionOfDone ?? []).join("\n"),
|
|
217
|
+
input.requirementCoverage ?? "",
|
|
218
|
+
input.verificationContract ?? "",
|
|
219
|
+
input.verificationIntegration ?? "",
|
|
220
|
+
input.verificationOperational ?? "",
|
|
221
|
+
input.verificationUat ?? "",
|
|
222
|
+
].join("\n");
|
|
223
|
+
const overrideHits = containsAnyKeyword(haystack, OVERRIDE_KEYWORDS);
|
|
224
|
+
const complexHits = containsAnyKeyword(haystack, COMPLEX_KEYWORDS);
|
|
225
|
+
const trivialHits = containsAnyKeyword(haystack, TRIVIAL_KEYWORDS);
|
|
226
|
+
const fileCountHint = extractFileCountHint(haystack);
|
|
227
|
+
const hasTests = mentionsTests(haystack);
|
|
228
|
+
const hasBackend = mentionsBackend(haystack);
|
|
229
|
+
const reasons = [];
|
|
230
|
+
// Rule 2: complex-class signals. Evaluated before override because a
|
|
231
|
+
// complex + override input should land in complex, not standard.
|
|
232
|
+
if (complexHits.length > 0) {
|
|
233
|
+
reasons.push(`complex keywords: ${complexHits.slice(0, 3).join(", ")}`);
|
|
234
|
+
}
|
|
235
|
+
if (fileCountHint !== null && fileCountHint >= 8) {
|
|
236
|
+
reasons.push(`file count hint: ${fileCountHint}`);
|
|
237
|
+
}
|
|
238
|
+
const isComplex = complexHits.length > 0 || (fileCountHint !== null && fileCountHint >= 8);
|
|
239
|
+
if (isComplex) {
|
|
240
|
+
return {
|
|
241
|
+
variant: "complex",
|
|
242
|
+
reasons,
|
|
243
|
+
signals: {
|
|
244
|
+
triggeredOverride: overrideHits.length > 0,
|
|
245
|
+
complexCount: complexHits.length,
|
|
246
|
+
trivialCount: trivialHits.length,
|
|
247
|
+
fileCountHint,
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
// Rule 1: override keywords force standard.
|
|
252
|
+
if (overrideHits.length > 0) {
|
|
253
|
+
return {
|
|
254
|
+
variant: "standard",
|
|
255
|
+
reasons: [`override keywords: ${overrideHits.slice(0, 3).join(", ")}`],
|
|
256
|
+
signals: {
|
|
257
|
+
triggeredOverride: true,
|
|
258
|
+
complexCount: complexHits.length,
|
|
259
|
+
trivialCount: trivialHits.length,
|
|
260
|
+
fileCountHint,
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
// Rule 3: trivial signals — require ALL of: trivial-keyword, low file
|
|
265
|
+
// hint (or nothing suggesting high count), no test mention, no backend
|
|
266
|
+
// mention.
|
|
267
|
+
const fileCountOk = fileCountHint === null || fileCountHint <= 2;
|
|
268
|
+
const trivial = trivialHits.length > 0 &&
|
|
269
|
+
fileCountOk &&
|
|
270
|
+
!hasTests &&
|
|
271
|
+
!hasBackend;
|
|
272
|
+
if (trivial) {
|
|
273
|
+
reasons.push(`trivial keywords: ${trivialHits.slice(0, 3).join(", ")}`);
|
|
274
|
+
if (fileCountHint !== null)
|
|
275
|
+
reasons.push(`file count hint: ${fileCountHint}`);
|
|
276
|
+
reasons.push("no tests mentioned", "no backend mentioned");
|
|
277
|
+
return {
|
|
278
|
+
variant: "trivial",
|
|
279
|
+
reasons,
|
|
280
|
+
signals: {
|
|
281
|
+
triggeredOverride: false,
|
|
282
|
+
complexCount: complexHits.length,
|
|
283
|
+
trivialCount: trivialHits.length,
|
|
284
|
+
fileCountHint,
|
|
285
|
+
},
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
// Rule 4: fallback.
|
|
289
|
+
return {
|
|
290
|
+
variant: "standard",
|
|
291
|
+
reasons: reasons.length > 0 ? reasons : ["no strong signals — default"],
|
|
292
|
+
signals: {
|
|
293
|
+
triggeredOverride: overrideHits.length > 0,
|
|
294
|
+
complexCount: complexHits.length,
|
|
295
|
+
trivialCount: trivialHits.length,
|
|
296
|
+
fileCountHint,
|
|
297
|
+
},
|
|
298
|
+
};
|
|
299
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared milestone SUMMARY classifier.
|
|
3
|
+
*
|
|
4
|
+
* SUMMARY presence alone is not enough to prove milestone completion: recovery
|
|
5
|
+
* and blocker paths also write SUMMARY files. Keep this leaf module free of
|
|
6
|
+
* state/auto imports so state derivation, dispatch guards, and recovery can
|
|
7
|
+
* share one definition without cycles.
|
|
8
|
+
*/
|
|
9
|
+
import { splitFrontmatter, parseFrontmatterMap } from "../shared/frontmatter.js";
|
|
10
|
+
import { isClosedStatus } from "./status-guards.js";
|
|
11
|
+
export function classifyMilestoneSummaryContent(content) {
|
|
12
|
+
const [fmLines] = splitFrontmatter(content);
|
|
13
|
+
const fm = fmLines ? parseFrontmatterMap(fmLines) : null;
|
|
14
|
+
const rawStatus = typeof fm?.status === "string" ? fm.status.trim().toLowerCase() : "";
|
|
15
|
+
if (rawStatus) {
|
|
16
|
+
if (isClosedStatus(rawStatus))
|
|
17
|
+
return "success";
|
|
18
|
+
if (["active", "pending", "blocked", "failed", "failure", "incomplete"].includes(rawStatus)) {
|
|
19
|
+
return "failure";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const failureSignal = /(?:^|\n)\s*#\s*BLOCKER\b/i.test(content)
|
|
23
|
+
|| /auto-mode recovery failed/i.test(content)
|
|
24
|
+
|| /verification\s+failed/i.test(content)
|
|
25
|
+
|| /(?:^|\n)\s*(?:status|verdict|outcome|result)\s*[:=-]\s*not complete\b/i.test(content);
|
|
26
|
+
if (failureSignal)
|
|
27
|
+
return "failure";
|
|
28
|
+
return "unknown";
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Legacy-compatible terminal check for state derivation.
|
|
32
|
+
* Unknown summaries remain terminal to preserve old handwritten SUMMARY files;
|
|
33
|
+
* explicit failure summaries do not.
|
|
34
|
+
*/
|
|
35
|
+
export function isTerminalMilestoneSummaryContent(content) {
|
|
36
|
+
return classifyMilestoneSummaryContent(content) !== "failure";
|
|
37
|
+
}
|
|
@@ -43,6 +43,9 @@ export const BUNDLED_COST_TABLE = [
|
|
|
43
43
|
{ id: "gpt-5.3-codex-spark", inputPer1k: 0.0003, outputPer1k: 0.0012, updatedAt: "2026-03-29" },
|
|
44
44
|
{ id: "gpt-5.4", inputPer1k: 0.005, outputPer1k: 0.02, updatedAt: "2026-03-29" },
|
|
45
45
|
{ id: "gpt-5.4-mini", inputPer1k: 0.00075, outputPer1k: 0.0045, updatedAt: "2026-04-18" },
|
|
46
|
+
// GPT-5.5 API list price, also used for live Codex OAuth routing.
|
|
47
|
+
// Source: https://openai.com/api/pricing/
|
|
48
|
+
{ id: "gpt-5.5", inputPer1k: 0.005, outputPer1k: 0.03, updatedAt: "2026-04-23" },
|
|
46
49
|
// Google
|
|
47
50
|
{ id: "gemini-2.0-flash", inputPer1k: 0.0001, outputPer1k: 0.0004, updatedAt: "2025-03-15" },
|
|
48
51
|
{ id: "gemini-flash-2.0", inputPer1k: 0.0001, outputPer1k: 0.0004, updatedAt: "2025-03-15" },
|
|
@@ -43,6 +43,7 @@ export const MODEL_CAPABILITY_TIER = {
|
|
|
43
43
|
"gpt-5.2-codex": "heavy",
|
|
44
44
|
"gpt-5.3-codex": "heavy",
|
|
45
45
|
"gpt-5.4": "heavy",
|
|
46
|
+
"gpt-5.5": "heavy",
|
|
46
47
|
"o1": "heavy",
|
|
47
48
|
"o3": "heavy",
|
|
48
49
|
"o4-mini": "heavy",
|
|
@@ -76,6 +77,7 @@ const MODEL_COST_PER_1K_INPUT = {
|
|
|
76
77
|
"gpt-5.3-codex": 0.005,
|
|
77
78
|
"gpt-5.3-codex-spark": 0.0003,
|
|
78
79
|
"gpt-5.4": 0.005,
|
|
80
|
+
"gpt-5.5": 0.005,
|
|
79
81
|
"o4-mini": 0.005,
|
|
80
82
|
"o4-mini-deep-research": 0.005,
|
|
81
83
|
"gemini-2.0-flash": 0.0001,
|
|
@@ -116,6 +118,10 @@ export const MODEL_CAPABILITY_PROFILES = {
|
|
|
116
118
|
"gpt-5.3-codex": { coding: 94, debugging: 91, research: 74, reasoning: 89, speed: 50, longContext: 80, instruction: 89 },
|
|
117
119
|
"gpt-5.3-codex-spark": { coding: 68, debugging: 58, research: 42, reasoning: 52, speed: 90, longContext: 50, instruction: 74 },
|
|
118
120
|
"gpt-5.4": { coding: 95, debugging: 92, research: 88, reasoning: 94, speed: 42, longContext: 88, instruction: 92 },
|
|
121
|
+
// GPT-5.5 scores are relative to the existing gpt-5.4 profile and backed by
|
|
122
|
+
// OpenAI's 2026-04-23 published eval deltas across coding, tool use, and long context.
|
|
123
|
+
// Source: https://openai.com/index/introducing-gpt-5-5/
|
|
124
|
+
"gpt-5.5": { coding: 96, debugging: 93, research: 89, reasoning: 95, speed: 42, longContext: 90, instruction: 93 },
|
|
119
125
|
// ── OpenAI o-series (reasoning-first) ──────────────────────────────────────
|
|
120
126
|
"o1": { coding: 78, debugging: 82, research: 78, reasoning: 90, speed: 20, longContext: 65, instruction: 82 },
|
|
121
127
|
"o3": { coding: 80, debugging: 85, research: 80, reasoning: 92, speed: 25, longContext: 70, instruction: 85 },
|
|
@@ -740,15 +740,44 @@ export function nativeResetPaths(basePath, paths) {
|
|
|
740
740
|
gitExec(basePath, ["reset", "HEAD", "--", p], true);
|
|
741
741
|
}
|
|
742
742
|
}
|
|
743
|
+
/**
|
|
744
|
+
* Read `commit.gpgsign` from the repo config. Returns true only if the value
|
|
745
|
+
* is the literal string "true". Any other state (unset, false, error) → false.
|
|
746
|
+
*
|
|
747
|
+
* Used by nativeCommit to route signing-required commits through the git CLI,
|
|
748
|
+
* because the libgit2 native path does not invoke configured signers.
|
|
749
|
+
* (Issue #4980 CRIT-2)
|
|
750
|
+
*/
|
|
751
|
+
function shouldSignCommits(basePath) {
|
|
752
|
+
try {
|
|
753
|
+
const result = execFileSync("git", ["config", "--get", "commit.gpgsign"], {
|
|
754
|
+
cwd: basePath,
|
|
755
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
756
|
+
encoding: "utf-8",
|
|
757
|
+
env: GIT_NO_PROMPT_ENV,
|
|
758
|
+
}).trim();
|
|
759
|
+
return result === "true";
|
|
760
|
+
}
|
|
761
|
+
catch {
|
|
762
|
+
return false;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
743
765
|
/**
|
|
744
766
|
* Create a commit from the current index.
|
|
745
767
|
* Returns the commit SHA on success, or null if nothing to commit.
|
|
746
768
|
* Native: libgit2 commit create.
|
|
747
|
-
* Fallback: `git commit
|
|
769
|
+
* Fallback: `git commit -F -` (runs hooks; honors commit.gpgsign).
|
|
770
|
+
*
|
|
771
|
+
* The fallback intentionally does NOT use --no-verify — user pre-commit /
|
|
772
|
+
* commit-msg / prepare-commit-msg hooks must fire on every GSD-automated
|
|
773
|
+
* commit. (Issue #4980 CRIT-1)
|
|
748
774
|
*/
|
|
749
775
|
export function nativeCommit(basePath, message, options) {
|
|
750
776
|
const native = loadNative();
|
|
751
|
-
|
|
777
|
+
// libgit2's commit-create does not invoke configured GPG/SSH signers. When
|
|
778
|
+
// commit.gpgsign=true, route through the git CLI fallback so signing
|
|
779
|
+
// happens. (Issue #4980 CRIT-2)
|
|
780
|
+
if (native && !shouldSignCommits(basePath)) {
|
|
752
781
|
try {
|
|
753
782
|
return native.gitCommit(basePath, message, options?.allowEmpty);
|
|
754
783
|
}
|
|
@@ -759,9 +788,10 @@ export function nativeCommit(basePath, message, options) {
|
|
|
759
788
|
throw e;
|
|
760
789
|
}
|
|
761
790
|
}
|
|
762
|
-
// Fallback: use git
|
|
791
|
+
// Fallback / signed-commit path: use git CLI with stdin pipe for safe
|
|
792
|
+
// multi-line messages. Hooks run; commit.gpgsign honored.
|
|
763
793
|
try {
|
|
764
|
-
const args = ["commit", "
|
|
794
|
+
const args = ["commit", "-F", "-"];
|
|
765
795
|
if (options?.allowEmpty)
|
|
766
796
|
args.push("--allow-empty");
|
|
767
797
|
const result = execFileSync("git", args, {
|
|
@@ -1031,6 +1031,29 @@ export function validatePreferences(preferences) {
|
|
|
1031
1031
|
if (g.merge_to_main !== undefined) {
|
|
1032
1032
|
warnings.push("git.merge_to_main is deprecated — milestone-level merge is now always used. Remove this setting.");
|
|
1033
1033
|
}
|
|
1034
|
+
// #4765 — collapse cadence + milestone resquash
|
|
1035
|
+
if (g.collapse_cadence !== undefined) {
|
|
1036
|
+
const validCadence = new Set(["milestone", "slice"]);
|
|
1037
|
+
if (typeof g.collapse_cadence === "string" && validCadence.has(g.collapse_cadence)) {
|
|
1038
|
+
git.collapse_cadence = g.collapse_cadence;
|
|
1039
|
+
}
|
|
1040
|
+
else {
|
|
1041
|
+
errors.push("git.collapse_cadence must be one of: milestone, slice");
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
if (g.milestone_resquash !== undefined) {
|
|
1045
|
+
if (typeof g.milestone_resquash === "boolean") {
|
|
1046
|
+
git.milestone_resquash = g.milestone_resquash;
|
|
1047
|
+
const cadence = git.collapse_cadence
|
|
1048
|
+
?? (typeof g.collapse_cadence === "string" ? g.collapse_cadence : undefined);
|
|
1049
|
+
if (cadence !== "slice") {
|
|
1050
|
+
warnings.push('git.milestone_resquash is ignored unless git.collapse_cadence is "slice"');
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
else {
|
|
1054
|
+
errors.push("git.milestone_resquash must be a boolean");
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1034
1057
|
if (Object.keys(git).length > 0) {
|
|
1035
1058
|
validated.git = git;
|
|
1036
1059
|
}
|
|
@@ -24,6 +24,10 @@ const SEMI_STATIC_LABELS = new Set([
|
|
|
24
24
|
"prior-summaries",
|
|
25
25
|
"project-context",
|
|
26
26
|
"overrides",
|
|
27
|
+
// KNOWLEDGE is milestone-scoped (stable within a session), so it belongs
|
|
28
|
+
// in the cacheable prefix. See issue #4719.
|
|
29
|
+
"knowledge",
|
|
30
|
+
"project-knowledge",
|
|
27
31
|
]);
|
|
28
32
|
/** Labels that change per-task */
|
|
29
33
|
const DYNAMIC_LABELS = new Set([
|
|
@@ -10,14 +10,18 @@ Your working directory is `{{workingDirectory}}`. All file reads, writes, and sh
|
|
|
10
10
|
|
|
11
11
|
All slices are done. You are closing out the milestone — verifying that the assembled work actually delivers the promised outcome, writing the milestone summary, and updating project state. The milestone summary is the final record. After you finish, the system merges the worktree back to the integration branch. If there are queued milestones, the next one starts its own research → plan → execute cycle from a clean slate — the milestone summary is how it learns what was already built.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Preloaded context below — the roadmap, compact slice-summary excerpts, requirements, decisions, and project context. **Slice summaries are excerpts, not full files.** They include frontmatter fields, section heads (deviations, known limitations, follow-ups), and short narrative only. When drafting LEARNINGS, the Decision Re-evaluation table, or cross-slice narrative, Read the full slice SUMMARY.md files listed under "On-demand Slice Summaries" — do that selectively as needed, not preemptively.
|
|
14
|
+
|
|
15
|
+
Start with what the excerpts give you. Read full files when the section heads signal richer context you need.
|
|
16
|
+
|
|
17
|
+
**On-demand Read ordering:** Complete all slice SUMMARY Reads you need for cross-slice synthesis, the Decision Re-evaluation table, and LEARNINGS **before** calling `gsd_complete_milestone` (step 10). Once that tool runs, the milestone is marked complete in the DB — running out of tool budget between step 10 and the LEARNINGS write (step 12) leaves the milestone committed without its LEARNINGS artifact.
|
|
14
18
|
|
|
15
19
|
{{inlinedContext}}
|
|
16
20
|
|
|
17
21
|
Then:
|
|
18
22
|
1. Use the **Milestone Summary** output template from the inlined context above
|
|
19
23
|
2. {{skillActivation}}
|
|
20
|
-
3. **Verify code changes exist.**
|
|
24
|
+
3. **Verify code changes exist.** Compare the milestone against its integration branch (usually `main`, `master`, or the recorded integration branch), using the merge-base as the older revision and `HEAD` as the newer revision. If that branch diff lists non-`.gsd/` files, code-change verification passes. If `HEAD` is already the same commit as the integration branch/merge-base (a retry-on-main self-diff), do **not** treat the empty branch diff as proof of missing code. Instead, inspect milestone-scoped commit evidence such as recent commits with `GSD-Unit: {{milestoneId}}` or production `GSD-Task: Sxx/Tyy` trailers whose diff also touches `.gsd/milestones/{{milestoneId}}/`, then check those commits for non-`.gsd/` files. Only record a **verification failure** when neither the branch diff nor milestone-scoped commit evidence shows implementation files.
|
|
21
25
|
4. Verify each **success criterion** from the milestone definition in `{{roadmapPath}}`. For each criterion, confirm it was met with specific evidence from slice summaries, test results, or observable behavior. Record any criterion that was NOT met as a **verification failure**.
|
|
22
26
|
5. Verify the milestone's **definition of done** — all slices are `[x]`, all slice summaries exist, and any cross-slice integration points work correctly. Record any unmet items as a **verification failure**.
|
|
23
27
|
6. If the roadmap includes a **Horizontal Checklist**, verify each item was addressed during the milestone. Note unchecked items in the milestone summary.
|
|
@@ -164,9 +164,18 @@ Preserve the specification's exact terminology, emphasis, and specific framing.
|
|
|
164
164
|
|
|
165
165
|
### Ready-phrase pre-condition (NON-BYPASSABLE)
|
|
166
166
|
|
|
167
|
-
Before emitting the ready phrase, verify in the CURRENT turn that you have
|
|
167
|
+
Before emitting the ready phrase, verify in the CURRENT turn that you have:
|
|
168
168
|
|
|
169
|
-
|
|
169
|
+
- [ ] Written `.gsd/PROJECT.md` (step 2)
|
|
170
|
+
- [ ] Written `.gsd/REQUIREMENTS.md` (step 3)
|
|
171
|
+
- [ ] Written `{{contextPath}}` (step 4)
|
|
172
|
+
- [ ] Called `gsd_plan_milestone` (step 5)
|
|
173
|
+
|
|
174
|
+
If ANY box is unchecked, **STOP**. Do NOT emit the ready phrase. Emit the missing tool calls in this same turn. The system detects missing artifacts and will reject premature ready signals — you will be asked again and retries are capped.
|
|
175
|
+
|
|
176
|
+
Do not announce the ready phrase as something you are "about to" do. Do not narrate "now writing the files" as a substitute for actually writing them. The ready phrase is a post-write signal, not an intent signal.
|
|
177
|
+
|
|
178
|
+
After completing steps 1–7 above, say exactly: "Milestone {{milestoneId}} ready." — nothing else. Auto-mode will start automatically.
|
|
170
179
|
|
|
171
180
|
### Multi-Milestone
|
|
172
181
|
|
|
@@ -240,9 +249,19 @@ For single-milestone projects, do NOT write this file.
|
|
|
240
249
|
|
|
241
250
|
### Ready-phrase pre-condition (NON-BYPASSABLE)
|
|
242
251
|
|
|
243
|
-
Before emitting the ready phrase, verify in the CURRENT turn that you have
|
|
252
|
+
Before emitting the ready phrase, verify in the CURRENT turn that you have:
|
|
253
|
+
|
|
254
|
+
- [ ] Written `.gsd/PROJECT.md`
|
|
255
|
+
- [ ] Written `.gsd/REQUIREMENTS.md`
|
|
256
|
+
- [ ] Written the primary milestone `CONTEXT.md`
|
|
257
|
+
- [ ] Called `gsd_plan_milestone` for the primary milestone
|
|
258
|
+
- [ ] Written `.gsd/DISCUSSION-MANIFEST.json` with `gates_completed === total`
|
|
259
|
+
|
|
260
|
+
If ANY box is unchecked, **STOP**. Do NOT emit the ready phrase. Emit the missing tool calls in this same turn. The system detects missing artifacts and will reject premature ready signals — you will be asked again and retries are capped.
|
|
261
|
+
|
|
262
|
+
Do not announce the ready phrase as something you are "about to" do. Do not narrate "now writing the files" as a substitute for actually writing them. The ready phrase is a post-write signal, not an intent signal.
|
|
244
263
|
|
|
245
|
-
After
|
|
264
|
+
After completing every step above, say exactly: "Milestone {{milestoneId}} ready." — nothing else. Auto-mode will start automatically.
|
|
246
265
|
|
|
247
266
|
## Critical Rules
|
|
248
267
|
|
|
@@ -7,9 +7,10 @@ Rules:
|
|
|
7
7
|
2. Read before edit.
|
|
8
8
|
3. Prefer fixing authoritative artifacts over masking warnings.
|
|
9
9
|
4. For missing summaries or UAT files, generate the real artifact from existing slice/task context when possible — do not leave placeholders if you can reconstruct the real content.
|
|
10
|
-
5.
|
|
11
|
-
6.
|
|
12
|
-
7.
|
|
10
|
+
5. For a missing milestone `CONTEXT.md` when the milestone is already past `pre-planning` (phase is `executing`, `summarizing`, `validating-milestone`, or `completing-milestone`): the artifact was skipped during bootstrap and must be reconstructed before execution can resume. Read `PROJECT.md`, `REQUIREMENTS.md`, the milestone's `ROADMAP.md`, and any slice-level context on disk, then write `.gsd/milestones/<milestone-id>/<milestone-id>-CONTEXT.md` with the real context for the scoped milestone. Do not leave a stub — the plan gate will reject it on the next cycle.
|
|
11
|
+
6. After each repair cluster, verify the relevant invariant directly from disk.
|
|
12
|
+
7. When done, rerun `/gsd doctor {{doctorCommandSuffix}}` mentally by ensuring the remaining issue set for this scope is reduced or cleared.
|
|
13
|
+
8. Do NOT query `.gsd/gsd.db` directly via `sqlite3` or `node -e require('better-sqlite3')` — use `gsd_milestone_status` to inspect DB state. Direct access bypasses the WAL connection owned by the engine and can corrupt in-flight writes.
|
|
13
14
|
|
|
14
15
|
## Doctor Summary
|
|
15
16
|
|
|
@@ -27,4 +28,4 @@ Then:
|
|
|
27
28
|
- Repair the unresolved issues in scope
|
|
28
29
|
- Keep changes minimal and targeted
|
|
29
30
|
- If unresolved issues remain outside scope, leave them untouched and mention them briefly
|
|
30
|
-
- End with: "GSD doctor heal complete."
|
|
31
|
+
- End with: "GSD doctor heal complete."
|
|
@@ -20,9 +20,22 @@ Pay particular attention to **Forward Intelligence** sections — they contain h
|
|
|
20
20
|
|
|
21
21
|
You have full tool access. Before decomposing, explore the relevant code to ground your plan in reality.
|
|
22
22
|
|
|
23
|
-
### Verify Roadmap Assumptions
|
|
23
|
+
### Verify Roadmap Assumptions (JIT Reassessment — ADR-003 §4)
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Before planning this slice, verify that the roadmap's assumptions still hold given prior slice summaries. Check inlined dependency summaries (below) for discovered constraints, changed approaches, or flagged fragility.
|
|
26
|
+
|
|
27
|
+
**If the remaining roadmap needs adjustment, modify it before proceeding:**
|
|
28
|
+
|
|
29
|
+
- If a downstream slice's title/demo/dependencies are now wrong, call `gsd_reassess_roadmap` with the corrected `sliceChanges.modified` entry.
|
|
30
|
+
- If new work surfaced that deserves its own slice, add it via `sliceChanges.added`.
|
|
31
|
+
- If a downstream slice is now redundant or out of scope, remove it via `sliceChanges.removed`.
|
|
32
|
+
- **Bias strongly toward "roadmap is fine."** Most slice completions produce no structural change. Only adjust when there is concrete evidence a downstream slice is wrong — not speculative concern. Over-reassessment is costlier than a later mid-slice replan.
|
|
33
|
+
|
|
34
|
+
Completed slices are immutable: never modify or remove a slice whose status is complete.
|
|
35
|
+
|
|
36
|
+
Then proceed with planning this slice against the (possibly updated) roadmap.
|
|
37
|
+
|
|
38
|
+
The roadmap description may be stale — verify it against the current codebase state.
|
|
26
39
|
|
|
27
40
|
### Explore Slice Scope
|
|
28
41
|
|
|
@@ -58,6 +58,17 @@ export function rollbackToCheckpoint(basePath, unitId, sha) {
|
|
|
58
58
|
logWarning("safety", "rollback: detached HEAD state, cannot rollback");
|
|
59
59
|
return false;
|
|
60
60
|
}
|
|
61
|
+
// Preserve any staged or untracked user work before the hard reset.
|
|
62
|
+
// The user may have a partial fix staged that they wanted to inspect;
|
|
63
|
+
// reset --hard wipes both staged and unstaged changes (reflog only
|
|
64
|
+
// covers committed state). Push a labeled stash first so recovery
|
|
65
|
+
// is possible. (Issue #4980 HIGH-4)
|
|
66
|
+
try {
|
|
67
|
+
execFileSync("git", ["stash", "push", "--include-untracked", "-m", `gsd: pre-rollback-stash ${unitId} ${new Date().toISOString()}`], { cwd: basePath, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" });
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
/* nothing to stash, or stash refused — proceed with reset */
|
|
71
|
+
}
|
|
61
72
|
// Reset branch pointer and working tree to checkpoint SHA in one step.
|
|
62
73
|
// Using `git reset --hard <sha>` works on the currently checked-out branch
|
|
63
74
|
// (unlike `git branch -f` which is rejected for checked-out branches).
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Service Tier — gating, status formatting, icon resolution, and
|
|
3
3
|
* the /gsd fast command handler.
|
|
4
4
|
*
|
|
5
|
-
* Service tiers (priority/flex) are an OpenAI feature that only
|
|
6
|
-
* to gpt-5.4 variants. This module centralizes the model-gating logic
|
|
5
|
+
* Service tiers (priority/flex) are an OpenAI feature that currently only
|
|
6
|
+
* applies to gpt-5.4 variants in GSD. This module centralizes the model-gating logic
|
|
7
7
|
* so that icons, preferences, and the before_provider_request hook all
|
|
8
8
|
* use a single source of truth.
|
|
9
9
|
*/
|
|
@@ -21,6 +21,9 @@ const SERVICE_TIER_SCOPE_NOTE = "Only affects gpt-5.4 models, regardless of prov
|
|
|
21
21
|
* (set via CAPABILITY_PATCHES in packages/pi-ai/src/models.ts). When callers
|
|
22
22
|
* have access to the full Model object, prefer reading capabilities directly.
|
|
23
23
|
*
|
|
24
|
+
* GPT-5.5 is intentionally excluded until we verify its provider payload
|
|
25
|
+
* contract instead of assuming `service_tier` support.
|
|
26
|
+
*
|
|
24
27
|
* See: https://github.com/gsd-build/gsd-2/issues/2546
|
|
25
28
|
*/
|
|
26
29
|
const SERVICE_TIER_MODEL_PREFIXES = ["gpt-5.4"];
|