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
package/README.md
CHANGED
|
@@ -27,34 +27,70 @@ One command. Walk away. Come back to a built project with clean git history.
|
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
30
|
-
## What's New in v2.
|
|
30
|
+
## What's New in v2.78
|
|
31
31
|
|
|
32
|
-
###
|
|
32
|
+
### Worktree Lifecycle & Forensics
|
|
33
33
|
|
|
34
|
-
- **
|
|
35
|
-
- **
|
|
36
|
-
-
|
|
34
|
+
- **Slice-cadence worktree collapse (#4765)** — new `git.collapse_cadence: "milestone" | "slice"` preference. With `slice`, each validated slice squash-merges to main immediately, shrinking the orphan window from milestone-size to slice-size. Pair with `git.milestone_resquash: true` to collapse per-slice commits into one milestone commit at completion.
|
|
35
|
+
- **Worktree telemetry (#4764)** — new journal events (`worktree-created`, `worktree-merged`, `worktree-orphaned`, `auto-exit`, `canonical-root-redirect`, `slice-merged`, `milestone-resquash`) and a `summarizeWorktreeTelemetry` aggregator that reports orphan breakdowns, merge durations, conflict counts, exit reasons, and unmerged-exit metrics.
|
|
36
|
+
- **`/gsd forensics` worktree section** — surfaces the telemetry above with two new anomalies: `worktree-orphan` and `worktree-unmerged-exit`.
|
|
37
|
+
- **Worktree-aware canonical milestone root (#4761)** — `resolveCanonicalMilestoneRoot` routes validators and cross-session readers through the live worktree, so milestone validation no longer silently reads stale project-root state.
|
|
38
|
+
- **Bootstrap orphan audit (#4762)** — in-progress milestones with commits ahead of main no longer get skipped; the audit emits a warning with commit count and worktree location so interrupted auto-runs are visible.
|
|
37
39
|
|
|
38
|
-
###
|
|
40
|
+
### Auto Pipeline & Component System
|
|
39
41
|
|
|
40
|
-
- **
|
|
41
|
-
- **
|
|
42
|
-
- **
|
|
42
|
+
- **Unified component system** — skills, agents, pipelines, and marketplace are now one component model wired through runtime, dispatch, and telemetry, replacing per-surface plumbing.
|
|
43
|
+
- **UnitContextManifest v2 (#4924, #4934)** — auto dispatch runs through a typed manifest with declarative tools-policy and typed computed artifacts. CI guards the schema so drift fails fast.
|
|
44
|
+
- **Composer migration phase 3 (#4782)** — `complete-slice`, `research-milestone`, `run-uat`, and `reassess-roadmap` now build context through the manifest composer for a consistent shape across units.
|
|
45
|
+
- **Milestone scope classifier + pipeline variants (#4781)** — auto picks a pipeline variant from milestone shape, so research-heavy and execution-heavy milestones no longer share a one-size dispatch path.
|
|
46
|
+
- **Per-unit-type skill manifest resolver (#4779)** — skills wire into specific unit types instead of being globally on, with manifests expanded across the remaining types.
|
|
47
|
+
- **Single-writer-v3 control plane** — closes outstanding gaps in the durable-state writer model so concurrent writers can't desync workflow state.
|
|
48
|
+
- **Opt-in `reassess-roadmap` (#4778)** — gated behind the `skip_clean_reassess` preference per ADR-003 §4; auto no longer triggers reassessment unprompted.
|
|
43
49
|
|
|
44
|
-
###
|
|
50
|
+
### Extensions Framework
|
|
45
51
|
|
|
46
|
-
- **
|
|
47
|
-
- **
|
|
48
|
-
- **
|
|
52
|
+
- **Extension lifecycle commands** — `gsd extensions install / update / uninstall / list / info / validate` for npm, git, and local sources, with dependency warnings and user-metadata tracking.
|
|
53
|
+
- **Topological extension load order** — Kahn's-algorithm sort with surfaced `ExtensionLoadWarning`s, so dependent extensions resolve deterministically and misconfigurations are visible instead of silent.
|
|
54
|
+
- **cmux ↔ gsd decoupling** — static cross-imports replaced with a shared `cmux-events` contract and dynamic imports, isolating extension boundaries.
|
|
55
|
+
- **Extracted `@gsd-extensions/google-search` workspace** — first reference extension carved out of core; legacy in-tree source replaced with a deprecation stub.
|
|
56
|
+
|
|
57
|
+
### Models, Agent, and UX
|
|
58
|
+
|
|
59
|
+
- **GPT-5.5 Codex support** — added across `gsd` and `pi-ai`, including `xhigh` thinking level for custom GPT-5.5 models.
|
|
60
|
+
- **Auth mode in `/model`** — providers display alongside auth mode for clearer routing.
|
|
61
|
+
- **Permission granularity picker** — Claude Code "Always Allow" prompts let you scope the grant instead of approving the broad case.
|
|
62
|
+
- **Headless auto default → `bypassPermissions` (#4657)** — Claude Code CLI headless auto-mode runs without permission prompts by default.
|
|
63
|
+
- **`skillFilter` for system prompts** — `pi-coding-agent` filters which skills are surfaced in `buildSystemPrompt`, with consumer exceptions guarded.
|
|
64
|
+
- **Visual postinstall (#4641)** — install shows a spinner/banner UX so first-run state is legible.
|
|
65
|
+
- **PR-risk verification** — risk prompt emits a copy-pasteable code block to make follow-up commands one step.
|
|
49
66
|
|
|
50
67
|
### Reliability & Safety
|
|
51
68
|
|
|
52
|
-
- **
|
|
53
|
-
- **
|
|
54
|
-
- **
|
|
69
|
+
- **Major git-safety pass** — clarified TOCTOU ancestry guard, atomic sync-lock acquire with PID-verified stale override, `.git/index.lock` force-removal gated by 5-min age, `GIT_DIR`/`GIT_WORK_TREE`/`GIT_INDEX_FILE` stripped from env overlays, rebase/cherry-pick/revert state detected and aborted in recovery, working tree stashed before `reset --hard` in self-heal/rollback, worktree create guarded against unborn branches, and user hooks + `commit.gpgsign` honored on auto-commits.
|
|
70
|
+
- **Atomic `.gsd/` state writes** — file-locks now actually lock and throw on contention; appends are lock-wrapped to prevent interleaved writes.
|
|
71
|
+
- **Compaction correctness (#4665)** — fixed chunker/truncation mismatch and silent chunk-drops that produced degenerate or empty summaries.
|
|
72
|
+
- **Write-gate (#4950)** — fail-closed depth confirmation, EXDEV-safe snapshot rename, opt-out persistence default, off-by-one max-attempts fix, exception capture in `gate.execute`, and audit/DB rows for unknown gate ids.
|
|
73
|
+
- **Auto state machine** — deterministic policy errors classified non-retriable (#4973), depth-verification bypass for non-interactive sessions, baseline restored between units (#4961), `restoreToolBaseline` gated by `isAutoMode` (#4966).
|
|
74
|
+
- **Slice + crash recovery** — slice orchestrator state persists across crashes; ancestry-guarded force-reset, detached-HEAD refusal, and stash-by-ref recovery.
|
|
75
|
+
- **Empty-turn recovery** — Claude Code CLI tool-block shape canonicalized so empty-turn recovery matches real provider output.
|
|
55
76
|
|
|
56
77
|
See the full [Changelog](./CHANGELOG.md) for details on every release.
|
|
57
78
|
|
|
79
|
+
<details>
|
|
80
|
+
<summary>v2.77 highlights</summary>
|
|
81
|
+
|
|
82
|
+
- **Context Mode** — dispatch builds task-ready context automatically (artifacts, prior session, milestone/slice signals, execution metadata); enabled by default for new projects
|
|
83
|
+
- **Sandboxed execution tools** — `gsd_exec_search`, `gsd_resume`, and sandboxed tool-output paths for context-mode flows
|
|
84
|
+
- **Memory architecture (ADR-013)** — `memories` table is now authoritative; `structured_fields` adds typed metadata; dual-write migration landed with decisions backfill
|
|
85
|
+
- **Skill coverage** — 9 gap-closing skills landed plus 6 planning/design skills surfaced
|
|
86
|
+
- **Hook stack** — Layer 0 shell hooks and additional Layer 2 lifecycle events
|
|
87
|
+
- **TUI polish** — dedicated chat-frame style for skill invocations; active-row overflow fixes
|
|
88
|
+
- **Worktree + dispatch resilience** — crash-recovery dispatch hardened, safer path derivation, improved worktree context fallback
|
|
89
|
+
- **DB/schema guardrails** — migration/index ordering and schema version stamping tightened
|
|
90
|
+
- **Preflight hardening** — milestone completion enforces stricter clean-root checks with auto-stash
|
|
91
|
+
|
|
92
|
+
</details>
|
|
93
|
+
|
|
58
94
|
<details>
|
|
59
95
|
<summary>v2.75 highlights</summary>
|
|
60
96
|
|
|
@@ -288,7 +324,7 @@ Auto mode is a state machine driven by files on disk. It reads `.gsd/STATE.md`,
|
|
|
288
324
|
|
|
289
325
|
5. **Provider error recovery** — Transient provider errors (rate limits, 500/503 server errors, overloaded) auto-resume after a delay. Permanent errors (auth, billing) pause for manual review. The model fallback chain retries transient network errors before switching models.
|
|
290
326
|
|
|
291
|
-
6. **Stuck detection** — A sliding-window detector identifies repeated dispatch patterns (including multi-unit cycles).
|
|
327
|
+
6. **Stuck and artifact detection** — A sliding-window detector identifies repeated dispatch patterns (including multi-unit cycles). Missing expected artifacts use a separate bounded path: GSD retries artifact verification up to 3 times with failure context, then pauses auto mode with the missing artifact error instead of looping indefinitely.
|
|
292
328
|
|
|
293
329
|
7. **Timeout supervision** — Soft timeout warns the LLM to wrap up. Idle watchdog detects stalls. Hard timeout pauses auto mode. Recovery steering nudges the LLM to finish durable output before giving up.
|
|
294
330
|
|
package/dist/claude-cli-check.js
CHANGED
|
@@ -20,33 +20,71 @@ export const CLAUDE_COMMAND = process.platform === 'win32' ? 'claude.cmd' : 'cla
|
|
|
20
20
|
* expose a bare `claude` shim. Try all three so no valid install is missed.
|
|
21
21
|
*/
|
|
22
22
|
const CLAUDE_COMMAND_CANDIDATES = process.platform === 'win32' ? [CLAUDE_COMMAND, 'claude.exe', 'claude'] : [CLAUDE_COMMAND];
|
|
23
|
+
// Codes treated as "this candidate didn't run — try the next one" rather than
|
|
24
|
+
// fatal failures. ETIMEDOUT/EAGAIN cover slow-spawn cases on Windows where
|
|
25
|
+
// cmd.exe wrapping plus the Claude CLI startup path together exceed the
|
|
26
|
+
// per-attempt timeout (Issue #4997 regression on Windows + Node 25).
|
|
27
|
+
const SOFT_FAIL_CODES = new Set(['ENOENT', 'EINVAL', 'ETIMEDOUT', 'EAGAIN']);
|
|
28
|
+
const VERSION_TIMEOUT_MS = 5_000;
|
|
29
|
+
// Auth probe needs more headroom on Windows because the spawn goes through
|
|
30
|
+
// cmd.exe → claude.cmd → node → Claude CLI.
|
|
31
|
+
const AUTH_TIMEOUT_MS = 15_000;
|
|
23
32
|
/**
|
|
24
33
|
* Try to run `args` against each candidate binary.
|
|
25
34
|
* Returns the output buffer on first success, throws the last error if all fail.
|
|
26
35
|
*/
|
|
27
|
-
function execClaudeCheck(args) {
|
|
36
|
+
function execClaudeCheck(args, timeoutMs) {
|
|
28
37
|
let lastError;
|
|
29
38
|
for (const command of CLAUDE_COMMAND_CANDIDATES) {
|
|
30
39
|
try {
|
|
31
|
-
return execFileSync(command, args, {
|
|
40
|
+
return execFileSync(command, args, {
|
|
41
|
+
timeout: timeoutMs,
|
|
42
|
+
stdio: 'pipe',
|
|
43
|
+
shell: process.platform === 'win32',
|
|
44
|
+
});
|
|
32
45
|
}
|
|
33
46
|
catch (error) {
|
|
34
47
|
lastError = error;
|
|
35
48
|
const code = error?.code;
|
|
36
|
-
|
|
37
|
-
if (code === 'ENOENT' || code === 'EINVAL')
|
|
49
|
+
if (code && SOFT_FAIL_CODES.has(code))
|
|
38
50
|
continue;
|
|
39
51
|
throw error;
|
|
40
52
|
}
|
|
41
53
|
}
|
|
42
54
|
throw lastError ?? new Error(`Claude CLI not found (tried: ${CLAUDE_COMMAND_CANDIDATES.join(', ')})`);
|
|
43
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Decide auth state from `claude auth status` output.
|
|
58
|
+
*
|
|
59
|
+
* Newer Claude CLI builds emit JSON with a `loggedIn` boolean. Older builds
|
|
60
|
+
* emit free-form text. Prefer the structured signal; fall back to a text
|
|
61
|
+
* heuristic. The text heuristic only covers English phrasing.
|
|
62
|
+
*/
|
|
63
|
+
function parseAuthStatus(output) {
|
|
64
|
+
const trimmed = output.trim();
|
|
65
|
+
if (trimmed.startsWith('{')) {
|
|
66
|
+
try {
|
|
67
|
+
const parsed = JSON.parse(trimmed);
|
|
68
|
+
if (typeof parsed.loggedIn === 'boolean') {
|
|
69
|
+
return parsed.loggedIn;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// Fall through to text heuristic.
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const lower = trimmed.toLowerCase();
|
|
77
|
+
if (/not logged in|no credentials|unauthenticated|not authenticated/.test(lower)) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
44
82
|
/**
|
|
45
83
|
* Check if the `claude` binary is installed (regardless of auth state).
|
|
46
84
|
*/
|
|
47
85
|
export function isClaudeBinaryInstalled() {
|
|
48
86
|
try {
|
|
49
|
-
execClaudeCheck(['--version']);
|
|
87
|
+
execClaudeCheck(['--version'], VERSION_TIMEOUT_MS);
|
|
50
88
|
return true;
|
|
51
89
|
}
|
|
52
90
|
catch {
|
|
@@ -58,16 +96,14 @@ export function isClaudeBinaryInstalled() {
|
|
|
58
96
|
*/
|
|
59
97
|
export function isClaudeCliReady() {
|
|
60
98
|
try {
|
|
61
|
-
execClaudeCheck(['--version']);
|
|
99
|
+
execClaudeCheck(['--version'], VERSION_TIMEOUT_MS);
|
|
62
100
|
}
|
|
63
101
|
catch {
|
|
64
102
|
return false;
|
|
65
103
|
}
|
|
66
104
|
try {
|
|
67
|
-
const output = execClaudeCheck(['auth', 'status'])
|
|
68
|
-
|
|
69
|
-
.toLowerCase();
|
|
70
|
-
return !(/not logged in|no credentials|unauthenticated|not authenticated/i.test(output));
|
|
105
|
+
const output = execClaudeCheck(['auth', 'status', '--json'], AUTH_TIMEOUT_MS).toString();
|
|
106
|
+
return parseAuthStatus(output);
|
|
71
107
|
}
|
|
72
108
|
catch {
|
|
73
109
|
return false;
|
package/dist/headless.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* 10 — blocked (command reported a blocker)
|
|
12
12
|
* 11 — cancelled (SIGINT/SIGTERM received)
|
|
13
13
|
*/
|
|
14
|
-
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
14
|
+
import { existsSync, mkdirSync, writeFileSync, writeSync } from 'node:fs';
|
|
15
15
|
import { join } from 'node:path';
|
|
16
16
|
import { resolve } from 'node:path';
|
|
17
17
|
import { RpcClient, SessionManager } from '@gsd/pi-coding-agent';
|
|
@@ -250,6 +250,30 @@ async function runHeadlessOnce(options, restartCount) {
|
|
|
250
250
|
const result = await handleQuery(process.cwd());
|
|
251
251
|
return { exitCode: result.exitCode, interrupted: false };
|
|
252
252
|
}
|
|
253
|
+
// Doctor: read-only health check, no RPC child needed (#4904 live-regression).
|
|
254
|
+
// The interactive `/gsd doctor` command lives in the GSD extension; this CLI
|
|
255
|
+
// path lets non-interactive callers (CI, recovery scripts, the live-regression
|
|
256
|
+
// suite) get the same diagnostic without a TTY.
|
|
257
|
+
if (options.command === 'doctor') {
|
|
258
|
+
const wantsJson = options.json || options.commandArgs.includes('--json');
|
|
259
|
+
const { runGSDDoctor } = await import('./resources/extensions/gsd/doctor.js');
|
|
260
|
+
const { formatDoctorReport, formatDoctorReportJson } = await import('./resources/extensions/gsd/doctor-format.js');
|
|
261
|
+
let exitCode = 1;
|
|
262
|
+
try {
|
|
263
|
+
const report = await runGSDDoctor(process.cwd());
|
|
264
|
+
const out = wantsJson ? formatDoctorReportJson(report) : formatDoctorReport(report);
|
|
265
|
+
process.stdout.write(`${out}\n`);
|
|
266
|
+
exitCode = report.ok ? 0 : 1;
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
270
|
+
process.stderr.write(`[headless] doctor failed: ${msg}\n`);
|
|
271
|
+
exitCode = 1;
|
|
272
|
+
}
|
|
273
|
+
// Bypass the auto-restart loop in runHeadless — doctor is a one-shot
|
|
274
|
+
// diagnostic; exit 1 means "issues detected", not "crashed".
|
|
275
|
+
process.exit(exitCode);
|
|
276
|
+
}
|
|
253
277
|
// Resolve CLI path for the child process
|
|
254
278
|
const cliPath = process.env.GSD_BIN_PATH || process.argv[1];
|
|
255
279
|
if (!cliPath) {
|
|
@@ -616,7 +640,15 @@ async function runHeadlessOnce(options, restartCount) {
|
|
|
616
640
|
});
|
|
617
641
|
// Signal handling
|
|
618
642
|
const signalHandler = () => {
|
|
619
|
-
|
|
643
|
+
// Use writeSync on fd 2 to guarantee the Interrupted marker reaches
|
|
644
|
+
// consumers before process.exit() truncates pending async writes.
|
|
645
|
+
try {
|
|
646
|
+
writeSync(2, '\n[headless] Interrupted, stopping child process...\n');
|
|
647
|
+
}
|
|
648
|
+
catch {
|
|
649
|
+
// Fallback to async write if fd 2 is somehow unavailable.
|
|
650
|
+
process.stderr.write('\n[headless] Interrupted, stopping child process...\n');
|
|
651
|
+
}
|
|
620
652
|
interrupted = true;
|
|
621
653
|
exitCode = EXIT_CANCELLED;
|
|
622
654
|
// Kill child process — don't await, just fire and exit.
|
|
@@ -635,8 +667,21 @@ async function runHeadlessOnce(options, restartCount) {
|
|
|
635
667
|
}
|
|
636
668
|
process.exit(exitCode);
|
|
637
669
|
};
|
|
638
|
-
|
|
639
|
-
process.
|
|
670
|
+
// Use prependListener so our handler runs before pi-coding-agent's
|
|
671
|
+
// LSP-client module-load SIGINT handler, which calls process.exit(0)
|
|
672
|
+
// and would otherwise short-circuit our exit-code-11 contract.
|
|
673
|
+
process.prependListener('SIGINT', signalHandler);
|
|
674
|
+
process.prependListener('SIGTERM', signalHandler);
|
|
675
|
+
// Emit a deterministic readiness marker so test harnesses can wait for
|
|
676
|
+
// the SIGINT handler to be live before sending a signal. writeSync on
|
|
677
|
+
// fd 2 avoids any pipe-buffering race between the marker and subsequent
|
|
678
|
+
// signal delivery.
|
|
679
|
+
try {
|
|
680
|
+
writeSync(2, '[headless] signal-handlers-ready\n');
|
|
681
|
+
}
|
|
682
|
+
catch {
|
|
683
|
+
process.stderr.write('[headless] signal-handlers-ready\n');
|
|
684
|
+
}
|
|
640
685
|
// Start the RPC session
|
|
641
686
|
try {
|
|
642
687
|
await client.start();
|
|
@@ -2,7 +2,47 @@ import { DefaultResourceLoader } from '@gsd/pi-coding-agent';
|
|
|
2
2
|
export { discoverExtensionEntryPaths } from './extension-discovery.js';
|
|
3
3
|
export declare function getExtensionKey(entryPath: string, extensionsDir: string): string;
|
|
4
4
|
export declare function readManagedResourceVersion(agentDir: string): string | null;
|
|
5
|
+
/**
|
|
6
|
+
* Computes a content fingerprint of a resources directory (defaults to the
|
|
7
|
+
* bundled resourcesDir).
|
|
8
|
+
*
|
|
9
|
+
* Walks all files under `rootDir` and hashes `${relativePath}:${sha256(contents)}`
|
|
10
|
+
* for each one. Using the file *contents* — not size — is what distinguishes
|
|
11
|
+
* this from the earlier implementation and closes #4787: a same-size edit
|
|
12
|
+
* (e.g. swapping one word for another word of the same byte length) produces
|
|
13
|
+
* a different file hash, bumps the aggregate fingerprint, and therefore
|
|
14
|
+
* triggers a full resync in `initResources`. The old path+size approach
|
|
15
|
+
* silently cached stale prompts across upgrades.
|
|
16
|
+
*
|
|
17
|
+
* Cost is ~1-2ms for a typical resources tree (~100 small .md files) —
|
|
18
|
+
* still negligible at startup. Files are streamed via `readFileSync` but
|
|
19
|
+
* bundled prompts are tiny so this is fine.
|
|
20
|
+
*
|
|
21
|
+
* Exported for unit tests and for callers that want to check a different
|
|
22
|
+
* directory (e.g. pre-install verification).
|
|
23
|
+
*/
|
|
24
|
+
export declare function computeResourceFingerprint(rootDir?: string): string;
|
|
5
25
|
export declare function getNewerManagedResourceVersion(agentDir: string, currentVersion: string): string | null;
|
|
26
|
+
/**
|
|
27
|
+
* Syncs a single bundled resource directory into the agent directory.
|
|
28
|
+
*
|
|
29
|
+
* 1. Makes the destination writable (handles Nix store read-only copies).
|
|
30
|
+
* 2. Removes destination subdirs that exist in source to clear stale files,
|
|
31
|
+
* while preserving user-created directories.
|
|
32
|
+
* 3. Copies source into destination.
|
|
33
|
+
* 4. Makes the result writable for the next upgrade cycle.
|
|
34
|
+
*/
|
|
35
|
+
export declare function syncResourceDir(srcDir: string, destDir: string): void;
|
|
36
|
+
/** Check if any @gsd* scopes exist in internal but not in hoisted node_modules */
|
|
37
|
+
export declare function hasMissingWorkspaceScopes(hoisted: string, internal: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Create a real node_modules directory containing symlinks from both the
|
|
40
|
+
* hoisted root (external deps) and internal root (@gsd/* workspace packages).
|
|
41
|
+
* Used for pnpm global installs where @gsd/* isn't hoisted.
|
|
42
|
+
*/
|
|
43
|
+
export declare function reconcileMergedNodeModules(agentNodeModules: string, hoisted: string, internal: string): void;
|
|
44
|
+
/** Build a cache fingerprint from packageRoot + sorted entry names of both directories */
|
|
45
|
+
export declare function mergedFingerprint(hoisted: string, internal: string): string;
|
|
6
46
|
/**
|
|
7
47
|
* Syncs all bundled resources to agentDir (~/.gsd/agent/) on every launch.
|
|
8
48
|
*
|
package/dist/resource-loader.js
CHANGED
|
@@ -101,17 +101,27 @@ function readManagedResourceManifest(agentDir) {
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
/**
|
|
104
|
-
* Computes a
|
|
104
|
+
* Computes a content fingerprint of a resources directory (defaults to the
|
|
105
|
+
* bundled resourcesDir).
|
|
105
106
|
*
|
|
106
|
-
* Walks all files under
|
|
107
|
-
*
|
|
108
|
-
*
|
|
107
|
+
* Walks all files under `rootDir` and hashes `${relativePath}:${sha256(contents)}`
|
|
108
|
+
* for each one. Using the file *contents* — not size — is what distinguishes
|
|
109
|
+
* this from the earlier implementation and closes #4787: a same-size edit
|
|
110
|
+
* (e.g. swapping one word for another word of the same byte length) produces
|
|
111
|
+
* a different file hash, bumps the aggregate fingerprint, and therefore
|
|
112
|
+
* triggers a full resync in `initResources`. The old path+size approach
|
|
113
|
+
* silently cached stale prompts across upgrades.
|
|
109
114
|
*
|
|
110
|
-
* ~
|
|
115
|
+
* Cost is ~1-2ms for a typical resources tree (~100 small .md files) —
|
|
116
|
+
* still negligible at startup. Files are streamed via `readFileSync` but
|
|
117
|
+
* bundled prompts are tiny so this is fine.
|
|
118
|
+
*
|
|
119
|
+
* Exported for unit tests and for callers that want to check a different
|
|
120
|
+
* directory (e.g. pre-install verification).
|
|
111
121
|
*/
|
|
112
|
-
function computeResourceFingerprint() {
|
|
122
|
+
export function computeResourceFingerprint(rootDir = resourcesDir) {
|
|
113
123
|
const entries = [];
|
|
114
|
-
collectFileEntries(
|
|
124
|
+
collectFileEntries(rootDir, rootDir, entries);
|
|
115
125
|
entries.sort();
|
|
116
126
|
return createHash('sha256').update(entries.join('\n')).digest('hex').slice(0, 16);
|
|
117
127
|
}
|
|
@@ -125,8 +135,17 @@ function collectFileEntries(dir, root, out) {
|
|
|
125
135
|
}
|
|
126
136
|
else {
|
|
127
137
|
const rel = relative(root, fullPath);
|
|
128
|
-
|
|
129
|
-
|
|
138
|
+
// Hash the file contents — see function doc for #4787 rationale.
|
|
139
|
+
let contentHash;
|
|
140
|
+
try {
|
|
141
|
+
contentHash = createHash('sha256').update(readFileSync(fullPath)).digest('hex');
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// Unreadable file — fall back to a stable marker so the entry still
|
|
145
|
+
// contributes to the aggregate hash and future reads will re-hash.
|
|
146
|
+
contentHash = 'unreadable';
|
|
147
|
+
}
|
|
148
|
+
out.push(`${rel}:${contentHash}`);
|
|
130
149
|
}
|
|
131
150
|
}
|
|
132
151
|
}
|
|
@@ -188,7 +207,7 @@ function makeTreeWritable(dirPath) {
|
|
|
188
207
|
* 3. Copies source into destination.
|
|
189
208
|
* 4. Makes the result writable for the next upgrade cycle.
|
|
190
209
|
*/
|
|
191
|
-
function syncResourceDir(srcDir, destDir) {
|
|
210
|
+
export function syncResourceDir(srcDir, destDir) {
|
|
192
211
|
makeTreeWritable(destDir);
|
|
193
212
|
if (existsSync(srcDir)) {
|
|
194
213
|
pruneStaleSiblingFiles(srcDir, destDir);
|
|
@@ -282,7 +301,7 @@ function ensureNodeModulesSymlink(agentDir) {
|
|
|
282
301
|
reconcileMergedNodeModules(agentNodeModules, hoistedNodeModules, internalNodeModules);
|
|
283
302
|
}
|
|
284
303
|
/** Check if any @gsd* scopes exist in internal but not in hoisted node_modules */
|
|
285
|
-
function hasMissingWorkspaceScopes(hoisted, internal) {
|
|
304
|
+
export function hasMissingWorkspaceScopes(hoisted, internal) {
|
|
286
305
|
if (!existsSync(internal))
|
|
287
306
|
return false;
|
|
288
307
|
try {
|
|
@@ -326,7 +345,7 @@ function reconcileSymlink(link, target) {
|
|
|
326
345
|
* hoisted root (external deps) and internal root (@gsd/* workspace packages).
|
|
327
346
|
* Used for pnpm global installs where @gsd/* isn't hoisted.
|
|
328
347
|
*/
|
|
329
|
-
function reconcileMergedNodeModules(agentNodeModules, hoisted, internal) {
|
|
348
|
+
export function reconcileMergedNodeModules(agentNodeModules, hoisted, internal) {
|
|
330
349
|
// Fast path: if already merged for this packageRoot + same directory contents, skip.
|
|
331
350
|
// The fingerprint includes entry names from both roots so `pnpm add/remove` triggers rebuild.
|
|
332
351
|
const marker = join(agentNodeModules, '.gsd-merged');
|
|
@@ -400,7 +419,7 @@ function reconcileMergedNodeModules(agentNodeModules, hoisted, internal) {
|
|
|
400
419
|
}
|
|
401
420
|
}
|
|
402
421
|
/** Build a cache fingerprint from packageRoot + sorted entry names of both directories */
|
|
403
|
-
function mergedFingerprint(hoisted, internal) {
|
|
422
|
+
export function mergedFingerprint(hoisted, internal) {
|
|
404
423
|
try {
|
|
405
424
|
const h = readdirSync(hoisted).sort().join(',');
|
|
406
425
|
const i = readdirSync(internal).sort().join(',');
|
|
@@ -21,6 +21,15 @@ async function getSharp() {
|
|
|
21
21
|
}
|
|
22
22
|
return _sharp;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Test-only seam: override the cached sharp module. Pass `null` to simulate
|
|
26
|
+
* an environment where the sharp native dep is unavailable; pass `undefined`
|
|
27
|
+
* to clear the cache and let the next getSharp() call re-import. See
|
|
28
|
+
* tests/capture-sharp-optional.test.cjs.
|
|
29
|
+
*/
|
|
30
|
+
export function __setSharpForTesting(value) {
|
|
31
|
+
_sharp = value;
|
|
32
|
+
}
|
|
24
33
|
import { formatCompactStateSummary } from "./utils.js";
|
|
25
34
|
// Anthropic vision: 1568px is the recommended optimal width. Height is capped
|
|
26
35
|
// generously at 8000px so tall full-page screenshots remain readable rather
|
|
@@ -12,76 +12,25 @@
|
|
|
12
12
|
import { describe, it, before, after } from "node:test";
|
|
13
13
|
import assert from "node:assert/strict";
|
|
14
14
|
import { chromium } from "playwright";
|
|
15
|
-
import {
|
|
16
|
-
import { resolve, dirname } from "node:path";
|
|
15
|
+
import { dirname } from "node:path";
|
|
17
16
|
import { fileURLToPath } from "node:url";
|
|
18
17
|
|
|
19
18
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
|
-
const ROOT = resolve(__dirname, "..");
|
|
21
19
|
|
|
22
20
|
// ---------------------------------------------------------------------------
|
|
23
|
-
// Source
|
|
21
|
+
// Source loading — import the IIFE builders directly via jiti.
|
|
22
|
+
// The test-only named exports in tools/intent.ts and tools/forms.ts exist
|
|
23
|
+
// exactly so this test can call the real, in-tree builders. No brace
|
|
24
|
+
// walking, no regex stripping — a refactor of the signatures just updates
|
|
25
|
+
// the import surface, not the test.
|
|
24
26
|
// ---------------------------------------------------------------------------
|
|
25
27
|
|
|
26
|
-
// 1. EVALUATE_HELPERS_SOURCE — exported constant, extract via jiti
|
|
27
28
|
import { createRequire } from "node:module";
|
|
28
29
|
const require = createRequire(import.meta.url);
|
|
29
30
|
const jiti = require("jiti")(__dirname, { interopDefault: true, debug: false });
|
|
30
31
|
const { EVALUATE_HELPERS_SOURCE } = jiti("../evaluate-helpers.ts");
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
// Extract the function from source, wrap it, and eval to get the builder.
|
|
34
|
-
const intentSource = readFileSync(resolve(ROOT, "tools/intent.ts"), "utf-8");
|
|
35
|
-
|
|
36
|
-
function extractBuildIntentScoringScript() {
|
|
37
|
-
// Match the function body: starts with "function buildIntentScoringScript"
|
|
38
|
-
// and returns a template literal string. We extract up to the matching closing brace.
|
|
39
|
-
const startMarker = "function buildIntentScoringScript(intent: string, scope?: string): string {";
|
|
40
|
-
const startIdx = intentSource.indexOf(startMarker);
|
|
41
|
-
if (startIdx === -1) throw new Error("Could not find buildIntentScoringScript in intent.ts");
|
|
42
|
-
|
|
43
|
-
// Walk from start, counting braces to find the end
|
|
44
|
-
let depth = 0;
|
|
45
|
-
let foundFirst = false;
|
|
46
|
-
let endIdx = startIdx;
|
|
47
|
-
for (let i = startIdx; i < intentSource.length; i++) {
|
|
48
|
-
if (intentSource[i] === "{") { depth++; foundFirst = true; }
|
|
49
|
-
if (intentSource[i] === "}") depth--;
|
|
50
|
-
if (foundFirst && depth === 0) { endIdx = i + 1; break; }
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
let fnBody = intentSource.slice(startIdx, endIdx);
|
|
54
|
-
// Strip TypeScript type annotations
|
|
55
|
-
fnBody = fnBody.replace(/\(intent:\s*string,\s*scope\?:\s*string\):\s*string/, "(intent, scope)");
|
|
56
|
-
return new Function("return " + fnBody)();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const buildIntentScoringScript = extractBuildIntentScoringScript();
|
|
60
|
-
|
|
61
|
-
// 3. Form analysis — module-private buildFormAnalysisScript.
|
|
62
|
-
const formsSource = readFileSync(resolve(ROOT, "tools/forms.ts"), "utf-8");
|
|
63
|
-
|
|
64
|
-
function extractBuildFormAnalysisScript() {
|
|
65
|
-
const startMarker = "function buildFormAnalysisScript(selector?: string): string {";
|
|
66
|
-
const startIdx = formsSource.indexOf(startMarker);
|
|
67
|
-
if (startIdx === -1) throw new Error("Could not find buildFormAnalysisScript in forms.ts");
|
|
68
|
-
|
|
69
|
-
let depth = 0;
|
|
70
|
-
let foundFirst = false;
|
|
71
|
-
let endIdx = startIdx;
|
|
72
|
-
for (let i = startIdx; i < formsSource.length; i++) {
|
|
73
|
-
if (formsSource[i] === "{") { depth++; foundFirst = true; }
|
|
74
|
-
if (formsSource[i] === "}") depth--;
|
|
75
|
-
if (foundFirst && depth === 0) { endIdx = i + 1; break; }
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
let fnBody = formsSource.slice(startIdx, endIdx);
|
|
79
|
-
// Strip TypeScript type annotation
|
|
80
|
-
fnBody = fnBody.replace(/\(selector\?:\s*string\):\s*string/, "(selector)");
|
|
81
|
-
return new Function("return " + fnBody)();
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const buildFormAnalysisScript = extractBuildFormAnalysisScript();
|
|
32
|
+
const { buildIntentScoringScript } = jiti("../tools/intent.ts");
|
|
33
|
+
const { buildFormAnalysisScript } = jiti("../tools/forms.ts");
|
|
85
34
|
|
|
86
35
|
// ---------------------------------------------------------------------------
|
|
87
36
|
// Browser lifecycle
|
|
@@ -387,32 +387,44 @@ describe("formatArtifactTimestamp", () => {
|
|
|
387
387
|
// ---------------------------------------------------------------------------
|
|
388
388
|
|
|
389
389
|
describe("EVALUATE_HELPERS_SOURCE", () => {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
390
|
+
// Behaviour test: executing the source in a Node vm sandbox must
|
|
391
|
+
// populate a `window.__pi` namespace with every expected helper.
|
|
392
|
+
// No source grep — we actually run the code and verify the resulting
|
|
393
|
+
// object shape.
|
|
394
|
+
it("executing the source assigns all expected helpers to window.__pi", () => {
|
|
395
|
+
const vm = require("node:vm");
|
|
396
|
+
const expectedFunctions = [
|
|
397
|
+
"cssPath",
|
|
398
|
+
"simpleHash",
|
|
399
|
+
"isVisible",
|
|
400
|
+
"isEnabled",
|
|
401
|
+
"inferRole",
|
|
402
|
+
"accessibleName",
|
|
403
|
+
"isInteractiveEl",
|
|
404
|
+
"domPath",
|
|
405
|
+
"selectorHints",
|
|
406
|
+
];
|
|
395
407
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
`
|
|
408
|
+
// Playwright evaluates the source in a page context where `window`
|
|
409
|
+
// exists, so the helpers attach to `window.__pi`. Provide a minimal
|
|
410
|
+
// window stub in a vm context so we avoid polluting the test globals.
|
|
411
|
+
const sandbox = { window: {} };
|
|
412
|
+
const script = new vm.Script(EVALUATE_HELPERS_SOURCE);
|
|
413
|
+
script.runInNewContext(sandbox, { timeout: 1000 });
|
|
414
|
+
|
|
415
|
+
assert.ok(
|
|
416
|
+
sandbox.window.__pi && typeof sandbox.window.__pi === "object",
|
|
417
|
+
"executing EVALUATE_HELPERS_SOURCE must assign window.__pi",
|
|
418
|
+
);
|
|
419
|
+
|
|
420
|
+
for (const fnName of expectedFunctions) {
|
|
421
|
+
assert.equal(
|
|
422
|
+
typeof sandbox.window.__pi[fnName],
|
|
423
|
+
"function",
|
|
424
|
+
`window.__pi.${fnName} must be a function after executing the source`,
|
|
413
425
|
);
|
|
414
|
-
}
|
|
415
|
-
}
|
|
426
|
+
}
|
|
427
|
+
});
|
|
416
428
|
});
|
|
417
429
|
|
|
418
430
|
// ---------------------------------------------------------------------------
|