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,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for slice-cadence collapse — #4765.
|
|
3
|
+
*
|
|
4
|
+
* Covers mergeSliceToMain (squash + advance), resquashMilestoneOnMain,
|
|
5
|
+
* and the preference accessors.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, test, beforeEach, afterEach } from "node:test";
|
|
9
|
+
import assert from "node:assert/strict";
|
|
10
|
+
import { mkdtempSync, mkdirSync, writeFileSync, rmSync, realpathSync, readFileSync, existsSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { tmpdir } from "node:os";
|
|
13
|
+
import { execFileSync } from "node:child_process";
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
mergeSliceToMain,
|
|
17
|
+
resquashMilestoneOnMain,
|
|
18
|
+
getCollapseCadence,
|
|
19
|
+
getMilestoneResquash,
|
|
20
|
+
} from "../slice-cadence.ts";
|
|
21
|
+
import { MergeConflictError } from "../git-service.ts";
|
|
22
|
+
import { summarizeWorktreeTelemetry } from "../worktree-telemetry.ts";
|
|
23
|
+
|
|
24
|
+
function git(args: string[], cwd: string): string {
|
|
25
|
+
return execFileSync("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Create a temp git repo with an initial commit on main. */
|
|
29
|
+
function createRepo(): string {
|
|
30
|
+
const dir = realpathSync(mkdtempSync(join(tmpdir(), "slice-cad-test-")));
|
|
31
|
+
git(["init"], dir);
|
|
32
|
+
git(["config", "user.email", "test@test.com"], dir);
|
|
33
|
+
git(["config", "user.name", "Test"], dir);
|
|
34
|
+
writeFileSync(join(dir, "README.md"), "# test\n");
|
|
35
|
+
git(["add", "."], dir);
|
|
36
|
+
git(["commit", "-m", "init"], dir);
|
|
37
|
+
git(["branch", "-M", "main"], dir);
|
|
38
|
+
mkdirSync(join(dir, ".gsd"), { recursive: true });
|
|
39
|
+
return dir;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function enterMilestoneBranch(dir: string, milestoneId: string): void {
|
|
43
|
+
git(["checkout", "-b", `milestone/${milestoneId}`], dir);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function commitFile(dir: string, file: string, content: string, msg: string): string {
|
|
47
|
+
writeFileSync(join(dir, file), content);
|
|
48
|
+
git(["add", "."], dir);
|
|
49
|
+
git(["commit", "-m", msg], dir);
|
|
50
|
+
return git(["rev-parse", "HEAD"], dir);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
describe("getCollapseCadence / getMilestoneResquash", () => {
|
|
54
|
+
test("defaults to milestone cadence", () => {
|
|
55
|
+
assert.equal(getCollapseCadence(undefined), "milestone");
|
|
56
|
+
assert.equal(getCollapseCadence(null), "milestone");
|
|
57
|
+
assert.equal(getCollapseCadence({}), "milestone");
|
|
58
|
+
assert.equal(getCollapseCadence({ git: {} }), "milestone");
|
|
59
|
+
});
|
|
60
|
+
test("reads slice cadence when set", () => {
|
|
61
|
+
assert.equal(getCollapseCadence({ git: { collapse_cadence: "slice" } }), "slice");
|
|
62
|
+
});
|
|
63
|
+
test("milestone_resquash defaults to true when not set", () => {
|
|
64
|
+
assert.equal(getMilestoneResquash(undefined), true);
|
|
65
|
+
assert.equal(getMilestoneResquash({ git: {} }), true);
|
|
66
|
+
assert.equal(getMilestoneResquash({ git: { milestone_resquash: true } }), true);
|
|
67
|
+
});
|
|
68
|
+
test("milestone_resquash can be disabled explicitly", () => {
|
|
69
|
+
assert.equal(getMilestoneResquash({ git: { milestone_resquash: false } }), false);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe("mergeSliceToMain", () => {
|
|
74
|
+
let dir: string;
|
|
75
|
+
let originalCwd: string;
|
|
76
|
+
|
|
77
|
+
beforeEach(() => {
|
|
78
|
+
dir = createRepo();
|
|
79
|
+
originalCwd = process.cwd();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
afterEach(() => {
|
|
83
|
+
try { process.chdir(originalCwd); } catch { /* */ }
|
|
84
|
+
rmSync(dir, { recursive: true, force: true });
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("squashes one slice's commits onto main and advances the milestone branch", () => {
|
|
88
|
+
enterMilestoneBranch(dir, "M001");
|
|
89
|
+
commitFile(dir, "feature.txt", "slice 1 work\n", "feat: S01 work");
|
|
90
|
+
|
|
91
|
+
process.chdir(dir);
|
|
92
|
+
const result = mergeSliceToMain(dir, "M001", "S01");
|
|
93
|
+
|
|
94
|
+
assert.equal(result.skipped, false);
|
|
95
|
+
assert.ok(result.commitSha, "expected a commit SHA");
|
|
96
|
+
assert.equal(result.milestoneBranch, "milestone/M001");
|
|
97
|
+
assert.equal(result.mainBranch, "main");
|
|
98
|
+
|
|
99
|
+
const mainLog = git(["log", "main", "--oneline"], dir);
|
|
100
|
+
assert.ok(mainLog.includes("S01 of M001 (slice-cadence)"), `main log: ${mainLog}`);
|
|
101
|
+
assert.equal(readFileSync(join(dir, "feature.txt"), "utf-8"), "slice 1 work\n");
|
|
102
|
+
|
|
103
|
+
const mainSha = git(["rev-parse", "main"], dir);
|
|
104
|
+
const milestoneSha = git(["rev-parse", "milestone/M001"], dir);
|
|
105
|
+
assert.equal(milestoneSha, mainSha, "milestone branch must be advanced to main");
|
|
106
|
+
|
|
107
|
+
const summary = summarizeWorktreeTelemetry(dir);
|
|
108
|
+
assert.equal(summary.slicesMerged, 1);
|
|
109
|
+
assert.equal(summary.sliceMergeConflicts, 0);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("handles sequential slice merges cleanly", () => {
|
|
113
|
+
enterMilestoneBranch(dir, "M001");
|
|
114
|
+
commitFile(dir, "a.txt", "slice 1\n", "feat: S01");
|
|
115
|
+
|
|
116
|
+
process.chdir(dir);
|
|
117
|
+
mergeSliceToMain(dir, "M001", "S01");
|
|
118
|
+
|
|
119
|
+
git(["checkout", "milestone/M001"], dir);
|
|
120
|
+
commitFile(dir, "b.txt", "slice 2\n", "feat: S02");
|
|
121
|
+
|
|
122
|
+
const result = mergeSliceToMain(dir, "M001", "S02");
|
|
123
|
+
assert.equal(result.skipped, false);
|
|
124
|
+
|
|
125
|
+
const mainLog = git(["log", "main", "--oneline"], dir);
|
|
126
|
+
assert.ok(mainLog.includes("S01 of M001"));
|
|
127
|
+
assert.ok(mainLog.includes("S02 of M001"));
|
|
128
|
+
|
|
129
|
+
assert.equal(readFileSync(join(dir, "a.txt"), "utf-8"), "slice 1\n");
|
|
130
|
+
assert.equal(readFileSync(join(dir, "b.txt"), "utf-8"), "slice 2\n");
|
|
131
|
+
|
|
132
|
+
const summary = summarizeWorktreeTelemetry(dir);
|
|
133
|
+
assert.equal(summary.slicesMerged, 2);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test("returns skipped when milestone branch has no commits ahead of main", () => {
|
|
137
|
+
enterMilestoneBranch(dir, "M001");
|
|
138
|
+
|
|
139
|
+
process.chdir(dir);
|
|
140
|
+
const result = mergeSliceToMain(dir, "M001", "S01");
|
|
141
|
+
|
|
142
|
+
assert.equal(result.skipped, true);
|
|
143
|
+
assert.equal(result.skippedReason, "no-commits-ahead");
|
|
144
|
+
assert.equal(result.commitSha, null);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test("throws MergeConflictError on a real conflict and leaves no merge artifacts", () => {
|
|
148
|
+
writeFileSync(join(dir, "shared.txt"), "main version\n");
|
|
149
|
+
git(["add", "."], dir);
|
|
150
|
+
git(["commit", "-m", "main-seed"], dir);
|
|
151
|
+
|
|
152
|
+
enterMilestoneBranch(dir, "M001");
|
|
153
|
+
commitFile(dir, "shared.txt", "slice version\n", "feat: S01 conflicting");
|
|
154
|
+
|
|
155
|
+
git(["checkout", "main"], dir);
|
|
156
|
+
commitFile(dir, "shared.txt", "main evolved\n", "main evolved");
|
|
157
|
+
git(["checkout", "milestone/M001"], dir);
|
|
158
|
+
|
|
159
|
+
process.chdir(dir);
|
|
160
|
+
assert.throws(
|
|
161
|
+
() => mergeSliceToMain(dir, "M001", "S01"),
|
|
162
|
+
(err: unknown) => err instanceof MergeConflictError,
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
const gitDir = join(dir, ".git");
|
|
166
|
+
for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
|
|
167
|
+
assert.ok(!existsSync(join(gitDir, f)), `${f} should be cleaned up`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const summary = summarizeWorktreeTelemetry(dir);
|
|
171
|
+
assert.equal(summary.sliceMergeConflicts, 1);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("restores cwd even when merge fails (dirty working tree)", () => {
|
|
175
|
+
enterMilestoneBranch(dir, "M001");
|
|
176
|
+
commitFile(dir, "feature.txt", "slice 1\n", "feat: S01");
|
|
177
|
+
// Introduce an untracked file AFTER the slice commit so it's still
|
|
178
|
+
// present when mergeSliceToMain runs its status check.
|
|
179
|
+
writeFileSync(join(dir, "dirty.txt"), "uncommitted\n");
|
|
180
|
+
|
|
181
|
+
process.chdir(dir);
|
|
182
|
+
const cwdBefore = process.cwd();
|
|
183
|
+
assert.throws(() => mergeSliceToMain(dir, "M001", "S01"));
|
|
184
|
+
assert.equal(process.cwd(), cwdBefore, "cwd must be restored on failure");
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
describe("resquashMilestoneOnMain", () => {
|
|
189
|
+
let dir: string;
|
|
190
|
+
let originalCwd: string;
|
|
191
|
+
|
|
192
|
+
beforeEach(() => {
|
|
193
|
+
dir = createRepo();
|
|
194
|
+
originalCwd = process.cwd();
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
afterEach(() => {
|
|
198
|
+
try { process.chdir(originalCwd); } catch { /* */ }
|
|
199
|
+
rmSync(dir, { recursive: true, force: true });
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test("collapses N slice commits on main into one milestone commit", () => {
|
|
203
|
+
const startSha = git(["rev-parse", "main"], dir);
|
|
204
|
+
|
|
205
|
+
enterMilestoneBranch(dir, "M001");
|
|
206
|
+
commitFile(dir, "a.txt", "slice 1\n", "feat: S01");
|
|
207
|
+
process.chdir(dir);
|
|
208
|
+
mergeSliceToMain(dir, "M001", "S01");
|
|
209
|
+
|
|
210
|
+
git(["checkout", "milestone/M001"], dir);
|
|
211
|
+
commitFile(dir, "b.txt", "slice 2\n", "feat: S02");
|
|
212
|
+
mergeSliceToMain(dir, "M001", "S02");
|
|
213
|
+
|
|
214
|
+
const beforeCount = parseInt(git(["rev-list", "--count", `${startSha}..main`], dir), 10);
|
|
215
|
+
assert.equal(beforeCount, 2);
|
|
216
|
+
|
|
217
|
+
const result = resquashMilestoneOnMain(dir, "M001", startSha);
|
|
218
|
+
assert.equal(result.resquashed, true);
|
|
219
|
+
assert.ok(result.newSha);
|
|
220
|
+
|
|
221
|
+
git(["checkout", "main"], dir);
|
|
222
|
+
const afterCount = parseInt(git(["rev-list", "--count", `${startSha}..main`], dir), 10);
|
|
223
|
+
assert.equal(afterCount, 1, "slice commits collapsed into one milestone commit");
|
|
224
|
+
|
|
225
|
+
const msg = git(["log", "-1", "--format=%s", "main"], dir);
|
|
226
|
+
assert.ok(msg.includes("M001") && msg.includes("2 slices"), `commit message should describe the resquash; got: ${msg}`);
|
|
227
|
+
|
|
228
|
+
assert.equal(readFileSync(join(dir, "a.txt"), "utf-8"), "slice 1\n");
|
|
229
|
+
assert.equal(readFileSync(join(dir, "b.txt"), "utf-8"), "slice 2\n");
|
|
230
|
+
|
|
231
|
+
const summary = summarizeWorktreeTelemetry(dir);
|
|
232
|
+
assert.equal(summary.milestoneResquashes, 1);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
test("no-op when startSha equals HEAD", () => {
|
|
236
|
+
const startSha = git(["rev-parse", "main"], dir);
|
|
237
|
+
process.chdir(dir);
|
|
238
|
+
const result = resquashMilestoneOnMain(dir, "M001", startSha);
|
|
239
|
+
assert.equal(result.resquashed, false);
|
|
240
|
+
assert.equal(result.newSha, null);
|
|
241
|
+
});
|
|
242
|
+
});
|
|
@@ -11,6 +11,7 @@ import assert from "node:assert/strict";
|
|
|
11
11
|
import { readFileSync } from "node:fs";
|
|
12
12
|
import { join, dirname } from "node:path";
|
|
13
13
|
import { fileURLToPath } from "node:url";
|
|
14
|
+
import { extractSourceRegion } from "./test-helpers.ts";
|
|
14
15
|
|
|
15
16
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
17
|
const autoPromptsPath = join(__dirname, "..", "auto-prompts.ts");
|
|
@@ -32,7 +33,7 @@ describe("slice CONTEXT.md injection into prompt builders (#3452)", () => {
|
|
|
32
33
|
assert.ok(fnStart !== -1, `${builder} should exist in auto-prompts.ts`);
|
|
33
34
|
|
|
34
35
|
// Get a reasonable chunk after the function start
|
|
35
|
-
const chunk = source
|
|
36
|
+
const chunk = extractSourceRegion(source, `export async function ${builder}`);
|
|
36
37
|
|
|
37
38
|
// ADR-011: buildPlanSlicePrompt / buildRefineSlicePrompt now delegate to
|
|
38
39
|
// a shared helper (renderSlicePrompt) that performs the slice CONTEXT
|
|
@@ -42,7 +43,7 @@ describe("slice CONTEXT.md injection into prompt builders (#3452)", () => {
|
|
|
42
43
|
? (() => {
|
|
43
44
|
const helperStart = source.indexOf("async function renderSlicePrompt");
|
|
44
45
|
assert.ok(helperStart !== -1, "renderSlicePrompt helper must exist");
|
|
45
|
-
return source
|
|
46
|
+
return extractSourceRegion(source, "async function renderSlicePrompt");
|
|
46
47
|
})()
|
|
47
48
|
: chunk;
|
|
48
49
|
|
|
@@ -4,6 +4,7 @@ import { tmpdir } from "node:os";
|
|
|
4
4
|
|
|
5
5
|
import { deriveState } from "../state.js";
|
|
6
6
|
import { resolveMilestoneFile } from "../paths.js";
|
|
7
|
+
import { extractSourceRegion } from "./test-helpers.ts";
|
|
7
8
|
|
|
8
9
|
let passed = 0;
|
|
9
10
|
let failed = 0;
|
|
@@ -81,7 +82,7 @@ assert(
|
|
|
81
82
|
|
|
82
83
|
// Check the branch has draft-aware menu options
|
|
83
84
|
const branchIdx = guidedFlowSource.indexOf('state.phase === "needs-discussion"');
|
|
84
|
-
const branchChunk = guidedFlowSource
|
|
85
|
+
const branchChunk = extractSourceRegion(guidedFlowSource, 'state.phase === "needs-discussion"');
|
|
85
86
|
|
|
86
87
|
assert(
|
|
87
88
|
branchChunk.includes("discuss_draft"),
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import { readFileSync } from "node:fs";
|
|
15
15
|
import { join } from "node:path";
|
|
16
|
-
import { createTestContext } from "./test-helpers.ts";
|
|
16
|
+
import { createTestContext, extractSourceRegion } from "./test-helpers.ts";
|
|
17
17
|
|
|
18
18
|
const { assertTrue, report } = createTestContext();
|
|
19
19
|
|
|
@@ -35,7 +35,7 @@ assertTrue(
|
|
|
35
35
|
);
|
|
36
36
|
|
|
37
37
|
// Extract the region from the closeout comment to the next section comment
|
|
38
|
-
const closeoutRegion = phasesSrc
|
|
38
|
+
const closeoutRegion = extractSourceRegion(phasesSrc, closeoutComment);
|
|
39
39
|
assertTrue(
|
|
40
40
|
closeoutRegion.includes("if (s.currentUnit)"),
|
|
41
41
|
"closeoutUnit call is guarded by `if (s.currentUnit)` check (#2939)",
|
|
@@ -52,7 +52,7 @@ assertTrue(
|
|
|
52
52
|
"phases.ts contains the 'Zero tool-call guard' comment block",
|
|
53
53
|
);
|
|
54
54
|
|
|
55
|
-
const zeroToolRegion = phasesSrc
|
|
55
|
+
const zeroToolRegion = extractSourceRegion(phasesSrc, zeroToolComment);
|
|
56
56
|
|
|
57
57
|
// The non-null assertion `s.currentUnit!.startedAt` must be replaced with
|
|
58
58
|
// optional chaining `s.currentUnit?.startedAt`
|
|
@@ -271,96 +271,15 @@ describe("structured-data-formatter: measureSavings", () => {
|
|
|
271
271
|
});
|
|
272
272
|
|
|
273
273
|
// ---------------------------------------------------------------------------
|
|
274
|
-
//
|
|
274
|
+
// Dropped (#4836): the previous "realistic savings" suite asserted that the
|
|
275
|
+
// compact formatter beat hand-authored "typical markdown" baselines by 30%+.
|
|
276
|
+
// Those baselines were written by the test author to make the assertion pass
|
|
277
|
+
// — they are not the format GSD actually emits anywhere else, so shifting
|
|
278
|
+
// the compact output by any amount could be absorbed by padding the baseline.
|
|
279
|
+
// There was no regression signal.
|
|
280
|
+
//
|
|
281
|
+
// The unit tests above already pin the compact format's structure byte for
|
|
282
|
+
// byte; a genuine regression changes one of those exact-string assertions.
|
|
283
|
+
// If a size-budget guarantee is needed later, capture a real production
|
|
284
|
+
// baseline into a fixture file and assert against a checked-in byte count.
|
|
275
285
|
// ---------------------------------------------------------------------------
|
|
276
|
-
|
|
277
|
-
describe("structured-data-formatter: realistic savings", () => {
|
|
278
|
-
it("decisions compact format saves 30%+ vs markdown table", () => {
|
|
279
|
-
const decisions = [sampleDecision, sampleDecision2];
|
|
280
|
-
|
|
281
|
-
// Simulate a typical markdown table
|
|
282
|
-
const markdownTable = [
|
|
283
|
-
"| ID | When | Scope | Decision | Choice | Rationale | Revisable |",
|
|
284
|
-
"|------|------------|--------------|-------------------------|------------------------|--------------------------|-----------|",
|
|
285
|
-
"| D001 | M001/S01 | architecture | Use SQLite for storage | WAL mode, single-writer | Built-in, no external deps | yes |",
|
|
286
|
-
"| D002 | M001/S02 | testing | Unit test all parsers | node:test framework | Fast, zero-dependency | no |",
|
|
287
|
-
].join("\n");
|
|
288
|
-
|
|
289
|
-
const compactOutput = formatDecisionsCompact(decisions);
|
|
290
|
-
const savings = measureSavings(compactOutput, markdownTable);
|
|
291
|
-
assert.ok(
|
|
292
|
-
savings >= 30,
|
|
293
|
-
`expected >=30% savings, got ${savings.toFixed(1)}%`,
|
|
294
|
-
);
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
it("requirements compact format saves 30%+ vs markdown sections", () => {
|
|
298
|
-
const requirements = [sampleRequirement, sampleRequirement2];
|
|
299
|
-
|
|
300
|
-
// Simulate verbose markdown format with all fields
|
|
301
|
-
const markdownSections = [
|
|
302
|
-
"## R001",
|
|
303
|
-
"",
|
|
304
|
-
"- **Class:** functional",
|
|
305
|
-
"- **Status:** active",
|
|
306
|
-
"- **Description:** Response latency < 200ms for API endpoints",
|
|
307
|
-
"- **Why:** Critical for user experience",
|
|
308
|
-
"- **Source:** architecture review",
|
|
309
|
-
"- **Primary Owner:** S01",
|
|
310
|
-
"- **Supporting Slices:** S02, S03",
|
|
311
|
-
"- **Validation:** Load test confirms P99 < 200ms",
|
|
312
|
-
"- **Notes:** Monitor in production",
|
|
313
|
-
"",
|
|
314
|
-
"## R002",
|
|
315
|
-
"",
|
|
316
|
-
"- **Class:** non-functional",
|
|
317
|
-
"- **Status:** active",
|
|
318
|
-
"- **Description:** Data consistency across writes",
|
|
319
|
-
"- **Why:** Prevents data loss",
|
|
320
|
-
"- **Source:** data team review",
|
|
321
|
-
"- **Primary Owner:** S02",
|
|
322
|
-
"- **Supporting Slices:** S01",
|
|
323
|
-
"- **Validation:** Integration test suite",
|
|
324
|
-
"- **Notes:** Requires WAL mode",
|
|
325
|
-
].join("\n");
|
|
326
|
-
|
|
327
|
-
const compactOutput = formatRequirementsCompact(requirements);
|
|
328
|
-
const savings = measureSavings(compactOutput, markdownSections);
|
|
329
|
-
assert.ok(
|
|
330
|
-
savings >= 30,
|
|
331
|
-
`expected >=30% savings, got ${savings.toFixed(1)}%`,
|
|
332
|
-
);
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
it("task plan compact format saves 30%+ vs markdown sections", () => {
|
|
336
|
-
const tasks = [sampleTaskDone, sampleTaskPending];
|
|
337
|
-
|
|
338
|
-
// Simulate verbose markdown task format
|
|
339
|
-
const markdownTasks = [
|
|
340
|
-
"## T01 - Database schema",
|
|
341
|
-
"",
|
|
342
|
-
"- **Status:** Done",
|
|
343
|
-
"- **Estimate:** 30m",
|
|
344
|
-
"- **Description:** Create tables for decisions and requirements",
|
|
345
|
-
"- **Files:**",
|
|
346
|
-
" - src/db.ts",
|
|
347
|
-
" - src/schema.ts",
|
|
348
|
-
"",
|
|
349
|
-
"## T02 - API endpoints",
|
|
350
|
-
"",
|
|
351
|
-
"- **Status:** Pending",
|
|
352
|
-
"- **Estimate:** 1h",
|
|
353
|
-
"- **Description:** REST endpoints for CRUD operations",
|
|
354
|
-
"- **Files:**",
|
|
355
|
-
" - src/api.ts",
|
|
356
|
-
"- **Verify:** npm test",
|
|
357
|
-
].join("\n");
|
|
358
|
-
|
|
359
|
-
const compactOutput = formatTaskPlanCompact(tasks);
|
|
360
|
-
const savings = measureSavings(compactOutput, markdownTasks);
|
|
361
|
-
assert.ok(
|
|
362
|
-
savings >= 30,
|
|
363
|
-
`expected >=30% savings, got ${savings.toFixed(1)}%`,
|
|
364
|
-
);
|
|
365
|
-
});
|
|
366
|
-
});
|
|
@@ -15,6 +15,7 @@ import { join, dirname } from "node:path";
|
|
|
15
15
|
import { tmpdir } from "node:os";
|
|
16
16
|
import { fileURLToPath } from "node:url";
|
|
17
17
|
import { validatePreferences } from "../preferences-validation.ts";
|
|
18
|
+
import { extractSourceRegion } from "./test-helpers.ts";
|
|
18
19
|
|
|
19
20
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
21
|
const promptsSrc = readFileSync(join(__dirname, "..", "auto-prompts.ts"), "utf-8");
|
|
@@ -59,7 +60,7 @@ test("reactive_execution: subagent_model rejects empty string", () => {
|
|
|
59
60
|
test("buildReactiveExecutePrompt: accepts subagentModel parameter", () => {
|
|
60
61
|
const fnStart = promptsSrc.indexOf("export async function buildReactiveExecutePrompt");
|
|
61
62
|
assert.ok(fnStart !== -1, "buildReactiveExecutePrompt should be exported");
|
|
62
|
-
const signature = promptsSrc
|
|
63
|
+
const signature = extractSourceRegion(promptsSrc, "export async function buildReactiveExecutePrompt", { fromIdx: fnStart });
|
|
63
64
|
assert.ok(
|
|
64
65
|
signature.includes("subagentModel"),
|
|
65
66
|
"buildReactiveExecutePrompt should accept a subagentModel parameter",
|
|
@@ -69,7 +70,7 @@ test("buildReactiveExecutePrompt: accepts subagentModel parameter", () => {
|
|
|
69
70
|
test("buildParallelResearchSlicesPrompt: accepts subagentModel parameter", () => {
|
|
70
71
|
const fnStart = promptsSrc.indexOf("export async function buildParallelResearchSlicesPrompt");
|
|
71
72
|
assert.ok(fnStart !== -1, "buildParallelResearchSlicesPrompt should be exported");
|
|
72
|
-
const signature = promptsSrc
|
|
73
|
+
const signature = extractSourceRegion(promptsSrc, "export async function buildParallelResearchSlicesPrompt", { fromIdx: fnStart });
|
|
73
74
|
assert.ok(
|
|
74
75
|
signature.includes("subagentModel"),
|
|
75
76
|
"buildParallelResearchSlicesPrompt should accept a subagentModel parameter",
|
|
@@ -79,7 +80,7 @@ test("buildParallelResearchSlicesPrompt: accepts subagentModel parameter", () =>
|
|
|
79
80
|
test("buildGateEvaluatePrompt: accepts subagentModel parameter", () => {
|
|
80
81
|
const fnStart = promptsSrc.indexOf("export async function buildGateEvaluatePrompt");
|
|
81
82
|
assert.ok(fnStart !== -1, "buildGateEvaluatePrompt should be exported");
|
|
82
|
-
const signature = promptsSrc
|
|
83
|
+
const signature = extractSourceRegion(promptsSrc, "export async function buildGateEvaluatePrompt", { fromIdx: fnStart });
|
|
83
84
|
assert.ok(
|
|
84
85
|
signature.includes("subagentModel"),
|
|
85
86
|
"buildGateEvaluatePrompt should accept a subagentModel parameter",
|
|
@@ -129,7 +130,7 @@ test("auto-dispatch: passes model to buildReactiveExecutePrompt", () => {
|
|
|
129
130
|
// Find the reactive-execute dispatch rule
|
|
130
131
|
const ruleStart = dispatchSrc.indexOf("reactive-execute (parallel dispatch)");
|
|
131
132
|
assert.ok(ruleStart !== -1, "reactive-execute dispatch rule should exist");
|
|
132
|
-
const ruleBlock = dispatchSrc
|
|
133
|
+
const ruleBlock = extractSourceRegion(dispatchSrc, "reactive-execute (parallel dispatch)", { fromIdx: ruleStart });
|
|
133
134
|
assert.ok(
|
|
134
135
|
ruleBlock.includes("subagent_model") || ruleBlock.includes("subagentModel"),
|
|
135
136
|
"reactive-execute rule should resolve and pass the subagent model",
|
|
@@ -140,7 +141,7 @@ test("auto-dispatch: passes model to buildParallelResearchSlicesPrompt", () => {
|
|
|
140
141
|
const callIdx = dispatchSrc.indexOf("buildParallelResearchSlicesPrompt(");
|
|
141
142
|
assert.ok(callIdx !== -1, "buildParallelResearchSlicesPrompt call should exist");
|
|
142
143
|
// The call site should pass a model argument (not just 4 args)
|
|
143
|
-
const callSite = dispatchSrc
|
|
144
|
+
const callSite = extractSourceRegion(dispatchSrc, "buildParallelResearchSlicesPrompt(", { fromIdx: callIdx });
|
|
144
145
|
assert.ok(
|
|
145
146
|
callSite.includes("subagentModel") || callSite.includes("resolveModelWithFallbacksForUnit"),
|
|
146
147
|
"buildParallelResearchSlicesPrompt call should include model argument",
|
|
@@ -150,7 +151,7 @@ test("auto-dispatch: passes model to buildParallelResearchSlicesPrompt", () => {
|
|
|
150
151
|
test("auto-dispatch: passes model to buildGateEvaluatePrompt", () => {
|
|
151
152
|
const callIdx = dispatchSrc.indexOf("buildGateEvaluatePrompt(");
|
|
152
153
|
assert.ok(callIdx !== -1, "buildGateEvaluatePrompt call should exist");
|
|
153
|
-
const callSite = dispatchSrc
|
|
154
|
+
const callSite = extractSourceRegion(dispatchSrc, "buildGateEvaluatePrompt(", { fromIdx: callIdx });
|
|
154
155
|
assert.ok(
|
|
155
156
|
callSite.includes("subagentModel") || callSite.includes("resolveModelWithFallbacksForUnit"),
|
|
156
157
|
"buildGateEvaluatePrompt call should include model argument",
|