gsd-pi 2.77.0-dev.1d17f366c → 2.77.0-dev.2daa994b6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/headless.js +25 -4
- package/dist/resource-loader.d.ts +40 -0
- package/dist/resource-loader.js +32 -13
- package/dist/resources/extensions/browser-tools/capture.js +9 -0
- package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
- package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
- package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
- package/dist/resources/extensions/browser-tools/tools/forms.js +5 -1
- package/dist/resources/extensions/browser-tools/tools/intent.js +5 -1
- package/dist/resources/extensions/gsd/auto/phases.js +5 -18
- package/dist/resources/extensions/gsd/auto/session.js +6 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +37 -8
- package/dist/resources/extensions/gsd/auto-post-unit.js +79 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +372 -104
- package/dist/resources/extensions/gsd/auto-start.js +75 -24
- package/dist/resources/extensions/gsd/auto.js +34 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +9 -1
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +7 -1
- package/dist/resources/extensions/gsd/component-loader.js +447 -0
- package/dist/resources/extensions/gsd/component-types.js +69 -0
- package/dist/resources/extensions/gsd/context-store.js +23 -7
- package/dist/resources/extensions/gsd/detection.js +49 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/forensics.js +106 -0
- package/dist/resources/extensions/gsd/gsd-db.js +1 -1
- package/dist/resources/extensions/gsd/guided-flow.js +2 -4
- package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
- package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
- package/dist/resources/extensions/gsd/model-router.js +6 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +23 -0
- package/dist/resources/extensions/gsd/prompt-cache-optimizer.js +4 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +5 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/dist/resources/extensions/gsd/service-tier.js +5 -2
- package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
- package/dist/resources/extensions/gsd/slice-cadence.js +238 -0
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +7 -2
- package/dist/resources/extensions/gsd/unit-context-composer.js +147 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +334 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +51 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +86 -7
- package/dist/resources/extensions/gsd/worktree-telemetry.js +198 -0
- package/dist/resources/extensions/mcp-client/index.js +3 -1
- package/dist/resources/extensions/ollama/index.js +5 -1
- package/dist/resources/extensions/remote-questions/manager.js +11 -5
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/package.json +1 -3
- package/packages/mcp-server/src/mcp-server.test.ts +25 -3
- package/packages/mcp-server/src/readers/graph.test.ts +87 -15
- package/packages/mcp-server/src/workflow-tools.test.ts +80 -39
- package/packages/native/package.json +1 -1
- package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
- package/packages/native/src/__tests__/module-compat.test.mjs +59 -27
- package/packages/native/src/__tests__/ps.test.mjs +14 -8
- package/packages/native/src/__tests__/stream-process.test.mjs +23 -2
- package/packages/native/src/__tests__/truncate.test.mjs +17 -2
- package/packages/pi-agent-core/src/agent-loop.test.ts +5 -15
- package/packages/pi-agent-core/src/agent.test.ts +96 -102
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
- package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai.js +17 -0
- package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.test.js +43 -70
- package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
- package/packages/pi-ai/dist/models.test.js +29 -11
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- package/packages/pi-ai/scripts/generate-models.ts +44 -0
- package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
- package/packages/pi-ai/src/models/generated/openai.ts +17 -0
- package/packages/pi-ai/src/models.generated.test.ts +46 -73
- package/packages/pi-ai/src/models.test.ts +39 -11
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js +75 -12
- package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +61 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +30 -4
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +17 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +76 -18
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +2 -6
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +5 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts +18 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.js +18 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +20 -0
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -2
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -0
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +36 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +20 -13
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +30 -12
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
- package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +58 -0
- package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +35 -4
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +20 -0
- package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +5 -1
- package/packages/pi-coding-agent/src/core/retry-handler.ts +2 -8
- package/packages/pi-coding-agent/src/core/retryable-error-regex.ts +18 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +35 -1
- package/packages/pi-coding-agent/src/index.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +49 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +48 -9
- package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js +18 -8
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +128 -17
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +36 -12
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
- package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
- package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
- package/packages/pi-tui/dist/components/image.test.js +6 -5
- package/packages/pi-tui/dist/components/image.test.js.map +1 -1
- package/packages/pi-tui/src/__tests__/autocomplete.test.ts +24 -8
- package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
- package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +41 -12
- package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
- package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
- package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
- package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
- package/packages/pi-tui/src/components/image.test.ts +10 -5
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/dist/rpc-client.test.js +101 -51
- package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
- package/packages/rpc-client/src/rpc-client.test.ts +109 -52
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/scripts/install.js +15 -1
- package/src/resources/extensions/browser-tools/capture.ts +12 -0
- package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
- package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
- package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
- package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
- package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +80 -72
- package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
- package/src/resources/extensions/github-sync/tests/templates.test.ts +33 -1
- package/src/resources/extensions/gsd/auto/phases.ts +6 -17
- package/src/resources/extensions/gsd/auto/session.ts +7 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +40 -8
- package/src/resources/extensions/gsd/auto-post-unit.ts +81 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +385 -93
- package/src/resources/extensions/gsd/auto-start.ts +97 -4
- package/src/resources/extensions/gsd/auto.ts +37 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +9 -1
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +7 -1
- package/src/resources/extensions/gsd/component-loader.ts +598 -0
- package/src/resources/extensions/gsd/component-types.ts +362 -0
- package/src/resources/extensions/gsd/context-store.ts +25 -8
- package/src/resources/extensions/gsd/detection.ts +58 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/forensics.ts +118 -1
- package/src/resources/extensions/gsd/git-service.ts +16 -0
- package/src/resources/extensions/gsd/gsd-db.ts +1 -1
- package/src/resources/extensions/gsd/guided-flow.ts +2 -4
- package/src/resources/extensions/gsd/journal.ts +11 -1
- package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
- package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
- package/src/resources/extensions/gsd/model-router.ts +6 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +21 -0
- package/src/resources/extensions/gsd/prompt-cache-optimizer.ts +4 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +5 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/src/resources/extensions/gsd/service-tier.ts +5 -2
- package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
- package/src/resources/extensions/gsd/slice-cadence.ts +299 -0
- package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +25 -292
- package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -194
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
- package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
- package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
- package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
- package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/context-store.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +8 -104
- package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
- package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -56
- package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
- package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +9 -3
- package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +93 -1
- package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +8 -37
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -55
- package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
- package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +6 -48
- package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +59 -2
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -130
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/prompt-cache-optimizer.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +15 -4
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +22 -16
- package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +4 -5
- package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
- package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
- package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
- package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +7 -6
- package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/test-helpers.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/test-helpers.ts +153 -0
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +203 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -80
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -54
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +342 -277
- package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +37 -29
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
- package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
- package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +210 -0
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +8 -2
- package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +492 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +53 -0
- package/src/resources/extensions/gsd/worktree-resolver.ts +96 -9
- package/src/resources/extensions/gsd/worktree-telemetry.ts +322 -0
- package/src/resources/extensions/mcp-client/index.ts +3 -1
- package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +70 -36
- package/src/resources/extensions/ollama/index.ts +5 -1
- package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +123 -15
- package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +206 -19
- package/src/resources/extensions/remote-questions/manager.ts +36 -4
- package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +200 -190
- package/src/resources/extensions/shared/tests/interview-preview.test.ts +11 -3
- package/src/resources/extensions/voice/tests/linux-ready.test.ts +129 -113
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +0 -2
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +0 -1
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +0 -289
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +0 -1
- package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +0 -363
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -143
- package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +0 -157
- package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +0 -107
- package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +0 -48
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -159
- package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
- package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +0 -74
- package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +0 -38
- package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +0 -73
- package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -125
- package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -42
- /package/dist/web/standalone/.next/static/{vidAVJkURvTJ0_V2-64ro → gYYky7yfxW8txb9vU2TrJ}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{vidAVJkURvTJ0_V2-64ro → gYYky7yfxW8txb9vU2TrJ}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified Component Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Shared metadata for installable/discoverable skills and agents.
|
|
5
|
+
*
|
|
6
|
+
* Replaces the separate type systems in:
|
|
7
|
+
* - packages/pi-coding-agent/src/core/skills.ts (SkillFrontmatter, Skill)
|
|
8
|
+
* - src/resources/extensions/subagent/agents.ts (AgentConfig)
|
|
9
|
+
*
|
|
10
|
+
* Legacy skill and agent formats are supported via backward-compatible loading.
|
|
11
|
+
*/
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Validation
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/** Max name length per spec */
|
|
16
|
+
export const MAX_NAME_LENGTH = 64;
|
|
17
|
+
/** Max description length per spec */
|
|
18
|
+
export const MAX_DESCRIPTION_LENGTH = 1024;
|
|
19
|
+
/** Valid name pattern: lowercase a-z, 0-9, hyphens, no leading/trailing/consecutive hyphens */
|
|
20
|
+
export const NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
21
|
+
/**
|
|
22
|
+
* Validate a component name.
|
|
23
|
+
* @returns Array of error messages (empty if valid).
|
|
24
|
+
*/
|
|
25
|
+
export function validateComponentName(name) {
|
|
26
|
+
const errors = [];
|
|
27
|
+
if (!name || name.trim() === '') {
|
|
28
|
+
errors.push('name is required');
|
|
29
|
+
return errors;
|
|
30
|
+
}
|
|
31
|
+
if (name.length > MAX_NAME_LENGTH) {
|
|
32
|
+
errors.push(`name exceeds ${MAX_NAME_LENGTH} characters (${name.length})`);
|
|
33
|
+
}
|
|
34
|
+
if (name.includes('--')) {
|
|
35
|
+
errors.push('name must not contain consecutive hyphens');
|
|
36
|
+
}
|
|
37
|
+
if (!NAME_PATTERN.test(name)) {
|
|
38
|
+
if (/[A-Z]/.test(name)) {
|
|
39
|
+
errors.push('name must be lowercase');
|
|
40
|
+
}
|
|
41
|
+
else if (name.startsWith('-') || name.endsWith('-')) {
|
|
42
|
+
errors.push('name must not start or end with a hyphen');
|
|
43
|
+
}
|
|
44
|
+
else if (!name.includes('--')) {
|
|
45
|
+
errors.push('name must contain only lowercase a-z, 0-9, and hyphens');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return errors;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Validate a component description.
|
|
52
|
+
* @returns Array of error messages (empty if valid).
|
|
53
|
+
*/
|
|
54
|
+
export function validateComponentDescription(description) {
|
|
55
|
+
const errors = [];
|
|
56
|
+
if (!description || description.trim() === '') {
|
|
57
|
+
errors.push('description is required');
|
|
58
|
+
}
|
|
59
|
+
else if (description.length > MAX_DESCRIPTION_LENGTH) {
|
|
60
|
+
errors.push(`description exceeds ${MAX_DESCRIPTION_LENGTH} characters (${description.length})`);
|
|
61
|
+
}
|
|
62
|
+
return errors;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Compute the canonical ID for a component.
|
|
66
|
+
*/
|
|
67
|
+
export function computeComponentId(name, namespace) {
|
|
68
|
+
return namespace ? `${namespace}:${name}` : name;
|
|
69
|
+
}
|
|
@@ -180,7 +180,13 @@ export function queryProject() {
|
|
|
180
180
|
// ─── Knowledge Query ───────────────────────────────────────────────────────
|
|
181
181
|
/**
|
|
182
182
|
* Filter KNOWLEDGE.md sections by keyword matching.
|
|
183
|
-
*
|
|
183
|
+
*
|
|
184
|
+
* Structure-adaptive (issue #4719): files that organise entries as H3 items
|
|
185
|
+
* under one or more H2 topics are filtered at H3 granularity. Files with only
|
|
186
|
+
* H2 topic headers (no H3) fall back to H2-level filtering for backwards
|
|
187
|
+
* compatibility.
|
|
188
|
+
*
|
|
189
|
+
* Matches keywords case-insensitively against:
|
|
184
190
|
* 1. Section header text
|
|
185
191
|
* 2. First paragraph of section content (up to first blank line or next heading)
|
|
186
192
|
*
|
|
@@ -189,28 +195,38 @@ export function queryProject() {
|
|
|
189
195
|
*
|
|
190
196
|
* @param content - Full KNOWLEDGE.md content
|
|
191
197
|
* @param keywords - Keywords to match (case-insensitive)
|
|
192
|
-
* @returns Concatenated matching sections with
|
|
198
|
+
* @returns Concatenated matching sections with their original heading prefix, or empty string
|
|
193
199
|
*/
|
|
194
200
|
export async function queryKnowledge(content, keywords) {
|
|
195
201
|
if (!content || keywords.length === 0)
|
|
196
202
|
return '';
|
|
197
203
|
// Lazy import to avoid circular dependency
|
|
198
204
|
const { extractAllSections } = await import('./files.js');
|
|
199
|
-
|
|
205
|
+
// Prefer H3 granularity when available; fall back to H2 for H2-only files.
|
|
206
|
+
// This prevents single-H2-with-many-H3 layouts from returning the entire
|
|
207
|
+
// file on a keyword match against the H2 header or its first paragraph.
|
|
208
|
+
const h3Sections = extractAllSections(content, 3);
|
|
209
|
+
const useH3 = h3Sections.size > 0;
|
|
210
|
+
const sections = useH3 ? h3Sections : extractAllSections(content, 2);
|
|
200
211
|
if (sections.size === 0)
|
|
201
212
|
return '';
|
|
202
|
-
|
|
203
|
-
|
|
213
|
+
const prefix = useH3 ? '###' : '##';
|
|
214
|
+
// Trim, lowercase, drop empties, and de-dupe so callers can pass raw
|
|
215
|
+
// user-provided strings without risking empty-string / whitespace matches.
|
|
216
|
+
const normalizedKeywords = [...new Set(keywords
|
|
217
|
+
.map(k => k.trim().toLowerCase())
|
|
218
|
+
.filter(k => k.length > 0))];
|
|
219
|
+
if (normalizedKeywords.length === 0)
|
|
220
|
+
return '';
|
|
204
221
|
const matchingSections = [];
|
|
205
222
|
for (const [header, body] of sections) {
|
|
206
223
|
// Extract first paragraph: everything up to first blank line or next heading
|
|
207
224
|
const firstParagraph = body.split(/\n\s*\n|\n#/)[0] || '';
|
|
208
|
-
// Check if any keyword matches header or first paragraph
|
|
209
225
|
const headerLower = header.toLowerCase();
|
|
210
226
|
const paragraphLower = firstParagraph.toLowerCase();
|
|
211
227
|
const matches = normalizedKeywords.some(kw => headerLower.includes(kw) || paragraphLower.includes(kw));
|
|
212
228
|
if (matches) {
|
|
213
|
-
matchingSections.push(
|
|
229
|
+
matchingSections.push(`${prefix} ${header}\n\n${body}`);
|
|
214
230
|
}
|
|
215
231
|
}
|
|
216
232
|
return matchingSections.join('\n\n');
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* flow to show when entering a project directory.
|
|
7
7
|
*/
|
|
8
8
|
import { existsSync, openSync, readSync, closeSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
9
|
-
import { join } from "node:path";
|
|
9
|
+
import { dirname, join, parse as parsePath } from "node:path";
|
|
10
10
|
import { homedir } from "node:os";
|
|
11
11
|
import { gsdRoot } from "./paths.js";
|
|
12
12
|
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
@@ -951,6 +951,54 @@ function resolveVersionCatalogAccessors(basePath, versionCatalogFiles, settingsF
|
|
|
951
951
|
}
|
|
952
952
|
return accessors;
|
|
953
953
|
}
|
|
954
|
+
/**
|
|
955
|
+
* Walk ancestor directories of `startDir` looking for any file in
|
|
956
|
+
* `PROJECT_FILES`. Stops at the filesystem root or at a `.git` boundary
|
|
957
|
+
* (so ancestors above a git repo root — e.g. `$HOME` or `/usr/local` —
|
|
958
|
+
* can't trigger false positives). Returns true if an ancestor contains
|
|
959
|
+
* one of the project markers.
|
|
960
|
+
*
|
|
961
|
+
* Used by the worktree health check (#2347) to avoid warning about
|
|
962
|
+
* monorepos where package.json / Cargo.toml / etc. live in a parent
|
|
963
|
+
* directory rather than in the worktree's own checkout.
|
|
964
|
+
*
|
|
965
|
+
* `existsFn` is injectable so this remains deterministically testable
|
|
966
|
+
* without touching the real filesystem; defaults to `fs.existsSync`.
|
|
967
|
+
*/
|
|
968
|
+
export function hasProjectFileInAncestor(startDir, existsFn = existsSync) {
|
|
969
|
+
let checkDir = dirname(startDir);
|
|
970
|
+
const { root } = parsePath(checkDir);
|
|
971
|
+
while (checkDir !== root) {
|
|
972
|
+
if (PROJECT_FILES.some((f) => existsFn(join(checkDir, f)))) {
|
|
973
|
+
return true;
|
|
974
|
+
}
|
|
975
|
+
// Stop at git repository boundary — ancestors above the repo root
|
|
976
|
+
// may contain unrelated project files. Check AFTER project-file scan
|
|
977
|
+
// so a repo root containing both .git and a marker is still recognized.
|
|
978
|
+
if (existsFn(join(checkDir, ".git")))
|
|
979
|
+
return false;
|
|
980
|
+
checkDir = dirname(checkDir);
|
|
981
|
+
}
|
|
982
|
+
return false;
|
|
983
|
+
}
|
|
984
|
+
/**
|
|
985
|
+
* Check whether a project's `.gsd/` directory contains the bootstrap artifacts
|
|
986
|
+
* (`PREFERENCES.md` or `milestones/`) that indicate a completed init run.
|
|
987
|
+
*
|
|
988
|
+
* A zombie `.gsd/` state — symlink exists but neither artifact is present —
|
|
989
|
+
* must be treated as "needs init wizard". The previous guard checked only
|
|
990
|
+
* `existsSync(gsdRoot(basePath))`, which accepted zombie states and skipped
|
|
991
|
+
* the wizard (#2942).
|
|
992
|
+
*
|
|
993
|
+
* `existsFn` is injectable so tests can run deterministically; defaults to
|
|
994
|
+
* `fs.existsSync`.
|
|
995
|
+
*/
|
|
996
|
+
export function hasGsdBootstrapArtifacts(gsdPath, existsFn = existsSync) {
|
|
997
|
+
return (existsFn(gsdPath) &&
|
|
998
|
+
(existsFn(join(gsdPath, "PREFERENCES.md")) ||
|
|
999
|
+
existsFn(join(gsdPath, "preferences.md")) ||
|
|
1000
|
+
existsFn(join(gsdPath, "milestones"))));
|
|
1001
|
+
}
|
|
954
1002
|
export function scanProjectFiles(basePath) {
|
|
955
1003
|
const files = [];
|
|
956
1004
|
const queue = [{ path: basePath, depth: 0 }];
|
|
@@ -159,7 +159,7 @@ Setting `prefer_skills: []` does **not** disable skill discovery — it just mea
|
|
|
159
159
|
|
|
160
160
|
- `phases`: fine-grained control over which phases run. Usually set by `token_profile`, but can be overridden. Keys:
|
|
161
161
|
- `skip_research`: boolean — skip milestone-level research. Default: `false`.
|
|
162
|
-
- `reassess_after_slice`: boolean — run roadmap
|
|
162
|
+
- `reassess_after_slice`: boolean — run a dedicated roadmap-reassessment unit after each completed slice. Default: `false` (per ADR-003 §4). The plan-slice agent for the next slice performs JIT reassessment via a prompt preamble at zero additional token cost; a dedicated reassess session is opt-in. Set to `true` (e.g. via the `burn-max` profile) if you want the explicit session.
|
|
163
163
|
- `skip_reassess`: boolean — force-disable roadmap reassessment even if `reassess_after_slice` is enabled. Default: `false`.
|
|
164
164
|
- `skip_slice_research`: boolean — skip per-slice research. Default: `false`.
|
|
165
165
|
|
|
@@ -29,6 +29,7 @@ import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
|
29
29
|
import { loadEffectiveGSDPreferences, loadGlobalGSDPreferences, getGlobalGSDPreferencesPath } from "./preferences.js";
|
|
30
30
|
import { showNextAction } from "../shared/tui.js";
|
|
31
31
|
import { ensurePreferencesFile, serializePreferencesToFrontmatter } from "./commands-prefs-wizard.js";
|
|
32
|
+
import { summarizeWorktreeTelemetry, percentile } from "./worktree-telemetry.js";
|
|
32
33
|
// ─── Duplicate Detection ──────────────────────────────────────────────────────
|
|
33
34
|
const DEDUP_PROMPT_SECTION = `
|
|
34
35
|
## Pre-Investigation: Duplicate Check (REQUIRED)
|
|
@@ -214,6 +215,16 @@ export async function buildForensicReport(basePath) {
|
|
|
214
215
|
detectCrash(crashLock, anomalies);
|
|
215
216
|
detectDoctorIssues(doctorIssues, anomalies);
|
|
216
217
|
detectErrorTraces(unitTraces, anomalies);
|
|
218
|
+
// 11b. #4764 — worktree lifecycle telemetry
|
|
219
|
+
let worktreeTelemetry = null;
|
|
220
|
+
try {
|
|
221
|
+
worktreeTelemetry = summarizeWorktreeTelemetry(basePath);
|
|
222
|
+
detectWorktreeOrphans(worktreeTelemetry, anomalies);
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// Telemetry is best-effort — do not let an aggregator failure block the
|
|
226
|
+
// rest of the forensic report.
|
|
227
|
+
}
|
|
217
228
|
detectJournalAnomalies(journalSummary, anomalies);
|
|
218
229
|
return {
|
|
219
230
|
gsdVersion,
|
|
@@ -232,6 +243,7 @@ export async function buildForensicReport(basePath) {
|
|
|
232
243
|
recentUnits,
|
|
233
244
|
journalSummary,
|
|
234
245
|
activityLogMeta,
|
|
246
|
+
worktreeTelemetry,
|
|
235
247
|
};
|
|
236
248
|
}
|
|
237
249
|
// ─── Activity Log Scanner ─────────────────────────────────────────────────────
|
|
@@ -630,6 +642,45 @@ function detectMissingArtifacts(completedKeys, basePath, activeMilestone, anomal
|
|
|
630
642
|
}
|
|
631
643
|
}
|
|
632
644
|
}
|
|
645
|
+
/**
|
|
646
|
+
* #4764 — surface worktree lifecycle and orphan signals in the forensic report.
|
|
647
|
+
*
|
|
648
|
+
* Consumes only the aggregated summary (not raw journal events) to respect
|
|
649
|
+
* the forensics memory-bloat guard in forensics-journal.test.ts — per-event
|
|
650
|
+
* detail stays in the journal itself where the LLM can query it on demand.
|
|
651
|
+
*/
|
|
652
|
+
function detectWorktreeOrphans(summary, anomalies) {
|
|
653
|
+
// 1. Orphan aggregate — severity depends on reason. In-progress orphans are
|
|
654
|
+
// the #4761 consumer-side signal (live work sitting on an unmerged branch).
|
|
655
|
+
for (const [reason, count] of Object.entries(summary.orphansByReason)) {
|
|
656
|
+
if (count <= 0)
|
|
657
|
+
continue;
|
|
658
|
+
const severity = reason === "in-progress-unmerged" ? "warning" : "info";
|
|
659
|
+
anomalies.push({
|
|
660
|
+
type: "worktree-orphan",
|
|
661
|
+
severity,
|
|
662
|
+
summary: `${count} worktree orphan(s) detected (${reason})`,
|
|
663
|
+
details: reason === "in-progress-unmerged"
|
|
664
|
+
? "Auto-mode exited without completing a milestone; live work sits on an unmerged milestone branch. Run `/gsd auto` to resume, or merge manually."
|
|
665
|
+
: reason === "complete-unmerged"
|
|
666
|
+
? "A completed milestone's branch was never merged back to main. Run `/gsd health --fix` to resolve."
|
|
667
|
+
: `Reason: ${reason}.`,
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
// 2. Auto-exit producer signal — #4761's upstream cause.
|
|
671
|
+
if (summary.exitsWithUnmergedWork > 0) {
|
|
672
|
+
const reasonBreakdown = Object.entries(summary.exitsByReason)
|
|
673
|
+
.filter(([, n]) => n > 0)
|
|
674
|
+
.map(([r, n]) => `${r}=${n}`)
|
|
675
|
+
.join(", ");
|
|
676
|
+
anomalies.push({
|
|
677
|
+
type: "worktree-unmerged-exit",
|
|
678
|
+
severity: "warning",
|
|
679
|
+
summary: `${summary.exitsWithUnmergedWork} auto-exit(s) left milestone work unmerged`,
|
|
680
|
+
details: `Exit reasons: ${reasonBreakdown || "(none)"} · Producer-side signal for #4761-class orphans. Inspect .gsd/journal/*.jsonl with eventType:"auto-exit" for per-exit detail.`,
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
}
|
|
633
684
|
function detectCrash(crashLock, anomalies) {
|
|
634
685
|
if (!crashLock)
|
|
635
686
|
return;
|
|
@@ -808,6 +859,39 @@ function saveForensicReport(basePath, report, problemDescription) {
|
|
|
808
859
|
sections.push(`- Newest: ${meta.newestFile}`);
|
|
809
860
|
sections.push(``);
|
|
810
861
|
}
|
|
862
|
+
// #4764 — Worktree telemetry summary
|
|
863
|
+
if (report.worktreeTelemetry) {
|
|
864
|
+
const t = report.worktreeTelemetry;
|
|
865
|
+
const p50 = percentile(t.mergeDurationsMs, 0.5);
|
|
866
|
+
const p95 = percentile(t.mergeDurationsMs, 0.95);
|
|
867
|
+
sections.push(`## Worktree Telemetry`, ``);
|
|
868
|
+
sections.push(`- Worktrees created: ${t.worktreesCreated}`);
|
|
869
|
+
sections.push(`- Worktrees merged: ${t.worktreesMerged}`);
|
|
870
|
+
sections.push(`- Orphans detected: ${t.orphansDetected}`);
|
|
871
|
+
if (t.orphansDetected > 0) {
|
|
872
|
+
const breakdown = Object.entries(t.orphansByReason)
|
|
873
|
+
.map(([r, n]) => `${r}=${n}`).join(", ");
|
|
874
|
+
sections.push(` - By reason: ${breakdown}`);
|
|
875
|
+
}
|
|
876
|
+
sections.push(`- Merge conflicts: ${t.mergeConflicts}`);
|
|
877
|
+
if (t.mergeDurationsMs.length > 0) {
|
|
878
|
+
sections.push(`- Merge duration p50 / p95: ${p50 ?? "-"} / ${p95 ?? "-"} ms (n=${t.mergeDurationsMs.length})`);
|
|
879
|
+
}
|
|
880
|
+
sections.push(`- Auto-exits leaving unmerged work: ${t.exitsWithUnmergedWork}`);
|
|
881
|
+
if (Object.keys(t.exitsByReason).length > 0) {
|
|
882
|
+
const breakdown = Object.entries(t.exitsByReason)
|
|
883
|
+
.sort((a, b) => b[1] - a[1])
|
|
884
|
+
.map(([r, n]) => `${r}=${n}`).join(", ");
|
|
885
|
+
sections.push(` - Exit reasons: ${breakdown}`);
|
|
886
|
+
}
|
|
887
|
+
sections.push(`- Canonical-root redirects (#4761 fix fired): ${t.canonicalRedirects}`);
|
|
888
|
+
// #4765 slice-cadence counters
|
|
889
|
+
if (t.slicesMerged + t.sliceMergeConflicts + t.milestoneResquashes > 0) {
|
|
890
|
+
sections.push(`- Slices merged: ${t.slicesMerged} · Slice merge conflicts: ${t.sliceMergeConflicts}`);
|
|
891
|
+
sections.push(`- Milestone re-squashes: ${t.milestoneResquashes}`);
|
|
892
|
+
}
|
|
893
|
+
sections.push(``);
|
|
894
|
+
}
|
|
811
895
|
// Journal summary
|
|
812
896
|
if (report.journalSummary) {
|
|
813
897
|
const js = report.journalSummary;
|
|
@@ -940,6 +1024,28 @@ function formatReportForPrompt(report) {
|
|
|
940
1024
|
sections.push(`- Total duration: ${formatDuration(totals.duration)}`);
|
|
941
1025
|
sections.push("");
|
|
942
1026
|
}
|
|
1027
|
+
// #4764 — worktree telemetry (compact prompt form)
|
|
1028
|
+
if (report.worktreeTelemetry) {
|
|
1029
|
+
const t = report.worktreeTelemetry;
|
|
1030
|
+
const hasSignal = t.worktreesCreated + t.worktreesMerged + t.orphansDetected +
|
|
1031
|
+
t.exitsWithUnmergedWork + t.canonicalRedirects +
|
|
1032
|
+
t.slicesMerged + t.milestoneResquashes > 0;
|
|
1033
|
+
if (hasSignal) {
|
|
1034
|
+
sections.push("### Worktree Telemetry");
|
|
1035
|
+
sections.push(`- Created: ${t.worktreesCreated} · Merged: ${t.worktreesMerged} · Conflicts: ${t.mergeConflicts}`);
|
|
1036
|
+
sections.push(`- Orphans: ${t.orphansDetected} · Unmerged exits: ${t.exitsWithUnmergedWork} · Redirects (#4761): ${t.canonicalRedirects}`);
|
|
1037
|
+
if (t.orphansDetected > 0) {
|
|
1038
|
+
const breakdown = Object.entries(t.orphansByReason)
|
|
1039
|
+
.map(([r, n]) => `${r}=${n}`).join(", ");
|
|
1040
|
+
sections.push(`- Orphan reasons: ${breakdown}`);
|
|
1041
|
+
}
|
|
1042
|
+
// #4765 — slice-cadence counters (only shown when the feature was exercised)
|
|
1043
|
+
if (t.slicesMerged + t.sliceMergeConflicts + t.milestoneResquashes > 0) {
|
|
1044
|
+
sections.push(`- Slices merged: ${t.slicesMerged} · Slice conflicts: ${t.sliceMergeConflicts} · Re-squashes: ${t.milestoneResquashes}`);
|
|
1045
|
+
}
|
|
1046
|
+
sections.push("");
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
943
1049
|
// Activity log metadata
|
|
944
1050
|
if (report.activityLogMeta) {
|
|
945
1051
|
const meta = report.activityLogMeta;
|
|
@@ -135,7 +135,7 @@ function openRawDb(path) {
|
|
|
135
135
|
const Database = providerModule;
|
|
136
136
|
return new Database(path);
|
|
137
137
|
}
|
|
138
|
-
const SCHEMA_VERSION = 22;
|
|
138
|
+
export const SCHEMA_VERSION = 22;
|
|
139
139
|
function indexExists(db, name) {
|
|
140
140
|
return !!db.prepare("SELECT 1 as present FROM sqlite_master WHERE type = 'index' AND name = ?").get(name);
|
|
141
141
|
}
|
|
@@ -28,7 +28,7 @@ import { ensureGitignore, ensurePreferences, untrackRuntimeFiles } from "./gitig
|
|
|
28
28
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
29
29
|
import { resolveUokFlags } from "./uok/flags.js";
|
|
30
30
|
import { ensurePlanV2Graph, isMissingFinalizedContextResult } from "./uok/plan-v2.js";
|
|
31
|
-
import { detectProjectState } from "./detection.js";
|
|
31
|
+
import { detectProjectState, hasGsdBootstrapArtifacts } from "./detection.js";
|
|
32
32
|
import { showProjectInit, offerMigration } from "./init-wizard.js";
|
|
33
33
|
import { validateDirectory } from "./validate-directory.js";
|
|
34
34
|
import { showConfirm } from "../shared/tui.js";
|
|
@@ -1244,9 +1244,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
|
|
|
1244
1244
|
// A zombie .gsd/ state (symlink exists but missing PREFERENCES.md and
|
|
1245
1245
|
// milestones/) must trigger the init wizard, not skip it (#2942).
|
|
1246
1246
|
const gsdPath = gsdRoot(basePath);
|
|
1247
|
-
const hasBootstrapArtifacts =
|
|
1248
|
-
&& (existsSync(join(gsdPath, "PREFERENCES.md"))
|
|
1249
|
-
|| existsSync(join(gsdPath, "milestones")));
|
|
1247
|
+
const hasBootstrapArtifacts = hasGsdBootstrapArtifacts(gsdPath);
|
|
1250
1248
|
if (!hasBootstrapArtifacts) {
|
|
1251
1249
|
const detection = detectProjectState(basePath);
|
|
1252
1250
|
// v1 .planning/ detected — offer migration before anything else
|
|
@@ -62,7 +62,9 @@ export function buildMemoryLLMCall(ctx) {
|
|
|
62
62
|
// which returns undefined for OAuth users (Claude Max / Claude Pro).
|
|
63
63
|
// See: https://github.com/gsd-build/gsd-2/issues/2959
|
|
64
64
|
const resolvedKeyPromise = ctx.modelRegistry.getApiKey(selectedModel).catch(() => undefined);
|
|
65
|
-
|
|
65
|
+
// Expose on the returned fn so tests can await resolution deterministically
|
|
66
|
+
// (avoids arbitrary setTimeout polling for an internal microtask).
|
|
67
|
+
const llmCall = async (system, user) => {
|
|
66
68
|
const { completeSimple } = await import('@gsd/pi-ai');
|
|
67
69
|
const resolvedApiKey = await resolvedKeyPromise;
|
|
68
70
|
const result = await completeSimple(selectedModel, {
|
|
@@ -79,6 +81,10 @@ export function buildMemoryLLMCall(ctx) {
|
|
|
79
81
|
.map(c => c.text);
|
|
80
82
|
return textParts.join('');
|
|
81
83
|
};
|
|
84
|
+
// Attach the in-flight API-key resolution so tests (and callers) can
|
|
85
|
+
// `await llmCall.apiKeyReady` rather than relying on setTimeout polling.
|
|
86
|
+
llmCall.apiKeyReady = resolvedKeyPromise;
|
|
87
|
+
return llmCall;
|
|
82
88
|
}
|
|
83
89
|
catch {
|
|
84
90
|
return null;
|