gsd-pi 2.77.0 → 2.78.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -36
- package/dist/claude-cli-check.js +5 -1
- package/dist/cli-web-branch.d.ts +1 -0
- package/dist/cli-web-branch.js +3 -0
- package/dist/cli.js +38 -2
- package/dist/extension-discovery.d.ts +6 -0
- package/dist/extension-discovery.js +37 -0
- package/dist/extension-registry.d.ts +3 -0
- package/dist/extension-sort.d.ts +18 -0
- package/dist/extension-sort.js +114 -0
- package/dist/extension-validator.d.ts +47 -0
- package/dist/extension-validator.js +127 -0
- package/dist/headless.js +49 -4
- package/dist/loader.js +35 -7
- package/dist/provider-migrations.d.ts +18 -0
- package/dist/provider-migrations.js +14 -0
- package/dist/resource-loader.d.ts +40 -0
- package/dist/resource-loader.js +32 -13
- package/dist/resources/extensions/browser-tools/capture.js +9 -0
- package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
- package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
- package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
- package/dist/resources/extensions/browser-tools/tools/forms.js +5 -1
- package/dist/resources/extensions/browser-tools/tools/intent.js +5 -1
- package/dist/resources/extensions/claude-code-cli/readiness.js +5 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +552 -67
- package/dist/resources/extensions/cmux/index.js +20 -0
- package/dist/resources/extensions/github-sync/templates.js +103 -0
- package/dist/resources/extensions/google-search/extension-manifest.json +5 -4
- package/dist/resources/extensions/google-search/index.js +3 -375
- package/dist/resources/extensions/gsd/abandon-detect.js +44 -0
- package/dist/resources/extensions/gsd/auto/loop.js +124 -2
- package/dist/resources/extensions/gsd/auto/phases.js +57 -39
- package/dist/resources/extensions/gsd/auto/resolve.js +24 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +10 -2
- package/dist/resources/extensions/gsd/auto/session.js +6 -2
- package/dist/resources/extensions/gsd/auto/turn-epoch.js +95 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +201 -38
- package/dist/resources/extensions/gsd/auto-loop.js +1 -1
- package/dist/resources/extensions/gsd/auto-model-selection.js +124 -4
- package/dist/resources/extensions/gsd/auto-post-unit.js +215 -64
- package/dist/resources/extensions/gsd/auto-prompts.js +372 -104
- package/dist/resources/extensions/gsd/auto-recovery.js +210 -24
- package/dist/resources/extensions/gsd/auto-start.js +122 -30
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +11 -5
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +47 -7
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +11 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +180 -34
- package/dist/resources/extensions/gsd/auto.js +107 -35
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +19 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +209 -0
- package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +5 -6
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +11 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -3
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +11 -6
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +127 -9
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +31 -4
- package/dist/resources/extensions/gsd/commands-cmux.js +9 -6
- package/dist/resources/extensions/gsd/commands-extensions.js +634 -43
- package/dist/resources/extensions/gsd/component-loader.js +447 -0
- package/dist/resources/extensions/gsd/component-types.js +69 -0
- package/dist/resources/extensions/gsd/context-store.js +23 -7
- package/dist/resources/extensions/gsd/detection.js +49 -1
- package/dist/resources/extensions/gsd/dispatch-guard.js +29 -3
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/file-lock.js +49 -9
- package/dist/resources/extensions/gsd/forensics.js +106 -0
- package/dist/resources/extensions/gsd/gate-registry.js +2 -2
- package/dist/resources/extensions/gsd/git-constants.js +28 -1
- package/dist/resources/extensions/gsd/git-self-heal.js +27 -0
- package/dist/resources/extensions/gsd/git-service.js +127 -2
- package/dist/resources/extensions/gsd/gitignore.js +1 -0
- package/dist/resources/extensions/gsd/gsd-db.js +6 -3
- package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -1
- package/dist/resources/extensions/gsd/guided-flow.js +39 -13
- package/dist/resources/extensions/gsd/journal.js +17 -2
- package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
- package/dist/resources/extensions/gsd/milestone-actions.js +15 -0
- package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
- package/dist/resources/extensions/gsd/milestone-summary-classifier.js +37 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
- package/dist/resources/extensions/gsd/model-router.js +6 -0
- package/dist/resources/extensions/gsd/native-git-bridge.js +34 -4
- package/dist/resources/extensions/gsd/notifications.js +30 -16
- package/dist/resources/extensions/gsd/preferences-validation.js +23 -0
- package/dist/resources/extensions/gsd/prompt-cache-optimizer.js +4 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
- package/dist/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -0
- package/dist/resources/extensions/gsd/reports.js +5 -4
- package/dist/resources/extensions/gsd/safety/git-checkpoint.js +11 -0
- package/dist/resources/extensions/gsd/service-tier.js +5 -2
- package/dist/resources/extensions/gsd/session-lock.js +19 -10
- package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
- package/dist/resources/extensions/gsd/slice-cadence.js +238 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +278 -8
- package/dist/resources/extensions/gsd/state-transition-matrix.js +118 -0
- package/dist/resources/extensions/gsd/state.js +69 -58
- package/dist/resources/extensions/gsd/sync-lock.js +98 -42
- package/dist/resources/extensions/gsd/tools/complete-slice.js +21 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +31 -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 +370 -0
- package/dist/resources/extensions/gsd/uok/audit.js +18 -2
- package/dist/resources/extensions/gsd/uok/dispatch-envelope.js +33 -0
- package/dist/resources/extensions/gsd/uok/execution-graph.js +10 -0
- package/dist/resources/extensions/gsd/uok/gate-runner.js +53 -5
- package/dist/resources/extensions/gsd/uok/gitops.js +2 -1
- package/dist/resources/extensions/gsd/uok/loop-adapter.js +37 -10
- package/dist/resources/extensions/gsd/uok/parity-report.js +58 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +10 -4
- package/dist/resources/extensions/gsd/uok/writer.js +82 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +10 -2
- package/dist/resources/extensions/gsd/workflow-mcp.js +6 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +86 -8
- package/dist/resources/extensions/gsd/worktree-resolver.js +86 -7
- package/dist/resources/extensions/gsd/worktree-telemetry.js +198 -0
- package/dist/resources/extensions/mcp-client/auth.js +10 -1
- package/dist/resources/extensions/mcp-client/index.js +121 -10
- package/dist/resources/extensions/ollama/index.js +5 -1
- package/dist/resources/extensions/remote-questions/manager.js +11 -5
- package/dist/resources/extensions/shared/cmux-events.js +12 -0
- package/dist/resources/extensions/shared/rtk-session-stats.js +1 -2
- package/dist/resources/skills/create-skill/SKILL.md +2 -2
- package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
- package/dist/resources/skills/create-skill/workflows/audit-skill.md +4 -4
- package/dist/resources/skills/create-skill/workflows/create-new-skill.md +5 -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 +12 -12
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +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 +12 -12
- package/dist/web/standalone/.next/server/chunks/1926.js +1 -0
- package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- 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/static/chunks/2826.e9f5195e91f9cad2.js +11 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-5fc74f13a25fa1bb.js → webpack-2e68521d7c82f7c2.js} +1 -1
- package/package.json +17 -16
- package/packages/daemon/package.json +2 -2
- package/packages/daemon/src/logger.ts +4 -3
- package/packages/mcp-server/README.md +3 -3
- package/packages/mcp-server/dist/env-writer.d.ts +1 -0
- package/packages/mcp-server/dist/env-writer.d.ts.map +1 -1
- package/packages/mcp-server/dist/env-writer.js +74 -6
- package/packages/mcp-server/dist/env-writer.js.map +1 -1
- package/packages/mcp-server/dist/server.d.ts +24 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +111 -87
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +15 -6
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +7 -2
- package/packages/mcp-server/src/env-writer.test.ts +79 -1
- package/packages/mcp-server/src/env-writer.ts +76 -6
- 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/readers/readers.test.ts +5 -1
- package/packages/mcp-server/src/secure-env-collect.test.ts +232 -237
- package/packages/mcp-server/src/server.ts +158 -105
- package/packages/mcp-server/src/workflow-tools.test.ts +85 -0
- package/packages/mcp-server/src/workflow-tools.ts +19 -6
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +7 -2
- package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
- package/packages/native/src/__tests__/clipboard.test.mjs +69 -23
- 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/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/package.json +6 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +226 -31
- package/packages/pi-agent-core/src/agent.test.ts +96 -102
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/capability-patches.js +9 -2
- package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
- package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai.js +17 -0
- package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.test.js +43 -70
- package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
- package/packages/pi-ai/dist/models.test.js +36 -11
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- package/packages/pi-ai/package.json +6 -1
- package/packages/pi-ai/scripts/generate-models.ts +44 -0
- package/packages/pi-ai/src/models/capability-patches.ts +10 -2
- package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
- package/packages/pi-ai/src/models/generated/openai.ts +17 -0
- package/packages/pi-ai/src/models.generated.test.ts +46 -73
- package/packages/pi-ai/src/models.test.ts +48 -11
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js +75 -12
- package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +25 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +105 -6
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +230 -28
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +30 -2
- package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/utils.js +113 -12
- package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +29 -18
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js +130 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js +56 -1
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +8 -15
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts +25 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js +109 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts +67 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js +167 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +8 -2
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +85 -8
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +7 -0
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +41 -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 +19 -2
- 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/resource-loader.js +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.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/sdk.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +4 -1
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.js +19 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -1
- 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 +19 -5
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/path-utils.test.js +2 -1
- package/packages/pi-coding-agent/dist/core/tools/path-utils.test.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__/provider-display-name.test.js +15 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.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/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts +7 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +31 -9
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +30 -12
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +18 -3
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +139 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +105 -13
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
- package/packages/pi-coding-agent/package.json +6 -1
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
- package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +368 -28
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +122 -6
- package/packages/pi-coding-agent/src/core/compaction/utils.ts +111 -13
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.test.ts +154 -0
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +32 -18
- package/packages/pi-coding-agent/src/core/compaction-utils.test.ts +68 -1
- package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +9 -18
- package/packages/pi-coding-agent/src/core/extensions/extension-discovery.ts +119 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-registry.ts +222 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +82 -11
- package/packages/pi-coding-agent/src/core/extensions/types.ts +8 -0
- package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +48 -4
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +22 -2
- package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
- package/packages/pi-coding-agent/src/core/resource-loader.ts +1 -1
- 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/sdk.test.ts +25 -1
- package/packages/pi-coding-agent/src/core/sdk.ts +10 -3
- package/packages/pi-coding-agent/src/core/system-prompt.ts +38 -4
- package/packages/pi-coding-agent/src/core/tools/path-utils.test.ts +2 -1
- package/packages/pi-coding-agent/src/index.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/provider-display-name.test.ts +17 -7
- 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/footer.ts +14 -5
- package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +45 -11
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +48 -9
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +160 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +20 -3
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +2 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +119 -13
- package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js +31 -14
- 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 +51 -6
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
- package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
- package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
- package/packages/pi-tui/dist/components/editor.d.ts +14 -0
- package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/editor.js +19 -0
- package/packages/pi-tui/dist/components/editor.js.map +1 -1
- package/packages/pi-tui/dist/components/image.test.js +6 -5
- package/packages/pi-tui/dist/components/image.test.js.map +1 -1
- package/packages/pi-tui/dist/editor-component.d.ts +2 -0
- package/packages/pi-tui/dist/editor-component.d.ts.map +1 -1
- package/packages/pi-tui/dist/editor-component.js.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.d.ts +7 -0
- package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.js +20 -0
- package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/packages/pi-tui/package.json +6 -1
- package/packages/pi-tui/src/__tests__/autocomplete.test.ts +46 -15
- package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
- package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +62 -6
- package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
- package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
- package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
- package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
- package/packages/pi-tui/src/components/editor.ts +22 -0
- package/packages/pi-tui/src/components/image.test.ts +10 -5
- package/packages/pi-tui/src/editor-component.ts +3 -0
- package/packages/pi-tui/src/stdin-buffer.ts +26 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/dist/rpc-client.test.js +101 -51
- package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
- package/packages/rpc-client/package.json +6 -1
- package/packages/rpc-client/src/rpc-client.test.ts +109 -52
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +1 -1
- package/scripts/install.js +526 -0
- package/scripts/lib/workspace-manifest.cjs +86 -0
- package/scripts/link-workspace-packages.cjs +5 -17
- package/scripts/postinstall.js +9 -178
- package/src/resources/extensions/browser-tools/capture.ts +12 -0
- package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
- package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
- package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
- package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
- package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
- package/src/resources/extensions/claude-code-cli/readiness.ts +5 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +602 -73
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +1028 -91
- package/src/resources/extensions/cmux/index.ts +35 -10
- package/src/resources/extensions/github-sync/templates.ts +151 -0
- package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
- package/src/resources/extensions/github-sync/tests/templates.test.ts +92 -1
- package/src/resources/extensions/google-search/extension-manifest.json +5 -4
- package/src/resources/extensions/google-search/index.ts +9 -470
- package/src/resources/extensions/gsd/abandon-detect.ts +62 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -1
- package/src/resources/extensions/gsd/auto/loop.ts +142 -2
- package/src/resources/extensions/gsd/auto/phases.ts +62 -38
- package/src/resources/extensions/gsd/auto/resolve.ts +29 -0
- package/src/resources/extensions/gsd/auto/run-unit.ts +16 -2
- package/src/resources/extensions/gsd/auto/session.ts +7 -2
- package/src/resources/extensions/gsd/auto/turn-epoch.ts +108 -0
- package/src/resources/extensions/gsd/auto/types.ts +1 -1
- package/src/resources/extensions/gsd/auto-dispatch.ts +214 -37
- package/src/resources/extensions/gsd/auto-loop.ts +1 -1
- package/src/resources/extensions/gsd/auto-model-selection.ts +131 -4
- package/src/resources/extensions/gsd/auto-post-unit.ts +226 -73
- package/src/resources/extensions/gsd/auto-prompts.ts +385 -93
- package/src/resources/extensions/gsd/auto-recovery.ts +240 -25
- package/src/resources/extensions/gsd/auto-start.ts +146 -14
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -5
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +51 -7
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +14 -3
- package/src/resources/extensions/gsd/auto-worktree.ts +190 -31
- package/src/resources/extensions/gsd/auto.ts +127 -41
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +20 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +221 -0
- package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +6 -6
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +11 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -3
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +13 -9
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +158 -9
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +27 -8
- package/src/resources/extensions/gsd/commands-cmux.ts +10 -6
- package/src/resources/extensions/gsd/commands-extensions.ts +747 -41
- package/src/resources/extensions/gsd/component-loader.ts +598 -0
- package/src/resources/extensions/gsd/component-types.ts +362 -0
- package/src/resources/extensions/gsd/context-store.ts +25 -8
- package/src/resources/extensions/gsd/detection.ts +58 -1
- package/src/resources/extensions/gsd/dispatch-guard.ts +26 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/file-lock.ts +84 -11
- package/src/resources/extensions/gsd/forensics.ts +118 -1
- package/src/resources/extensions/gsd/gate-registry.ts +2 -2
- package/src/resources/extensions/gsd/git-constants.ts +30 -1
- package/src/resources/extensions/gsd/git-self-heal.ts +31 -0
- package/src/resources/extensions/gsd/git-service.ts +150 -2
- package/src/resources/extensions/gsd/gitignore.ts +1 -0
- package/src/resources/extensions/gsd/gsd-db.ts +6 -3
- package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -1
- package/src/resources/extensions/gsd/guided-flow.ts +57 -14
- package/src/resources/extensions/gsd/journal.ts +38 -3
- package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
- package/src/resources/extensions/gsd/milestone-actions.ts +18 -0
- package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
- package/src/resources/extensions/gsd/milestone-summary-classifier.ts +42 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
- package/src/resources/extensions/gsd/model-router.ts +6 -0
- package/src/resources/extensions/gsd/native-git-bridge.ts +34 -4
- package/src/resources/extensions/gsd/notifications.ts +27 -15
- package/src/resources/extensions/gsd/preferences-validation.ts +21 -0
- package/src/resources/extensions/gsd/prompt-cache-optimizer.ts +4 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
- package/src/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
- package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -0
- package/src/resources/extensions/gsd/reports.ts +5 -4
- package/src/resources/extensions/gsd/safety/git-checkpoint.ts +15 -0
- package/src/resources/extensions/gsd/service-tier.ts +5 -2
- package/src/resources/extensions/gsd/session-lock.ts +20 -10
- package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
- package/src/resources/extensions/gsd/slice-cadence.ts +299 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +309 -8
- package/src/resources/extensions/gsd/state-transition-matrix.ts +152 -0
- package/src/resources/extensions/gsd/state.ts +76 -66
- package/src/resources/extensions/gsd/sync-lock.ts +97 -39
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +270 -0
- package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +341 -0
- package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +264 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +135 -285
- package/src/resources/extensions/gsd/tests/auto-mode-guards.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +742 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +61 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +166 -0
- package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -194
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +64 -0
- 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/cmux.test.ts +5 -9
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +16 -8
- package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
- package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/context-store.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +50 -1
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +159 -0
- package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +91 -3
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +14 -9
- package/src/resources/extensions/gsd/tests/dispatch-guard-summary-db-mismatch.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +173 -0
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
- package/src/resources/extensions/gsd/tests/file-lock.test.ts +86 -12
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +8 -104
- package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +131 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
- package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -56
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +144 -7
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -16
- package/src/resources/extensions/gsd/tests/integration/worktree-e2e.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +9 -3
- package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +93 -1
- package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -55
- package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
- package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/milestone-summary-classifier.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +4 -2
- 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-commit-scope.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -130
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/prompt-cache-optimizer.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +15 -4
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +54 -41
- package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +213 -0
- package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +4 -5
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +13 -7
- package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +75 -2
- package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
- package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
- package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +170 -0
- 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/rewrite-docs-abandon-detect.test.ts +195 -0
- package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
- package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +158 -0
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
- package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +164 -1
- package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +7 -6
- package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/test-helpers.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/test-helpers.ts +153 -0
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +61 -1
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +50 -2
- package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +162 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +258 -0
- package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
- package/src/resources/extensions/gsd/tests/uok-loop-adapter-writer.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/uok-parity-report.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +19 -2
- package/src/resources/extensions/gsd/tests/uok-writer.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/validate-extension-package.test.ts +168 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +139 -5
- 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/workflow-mcp.test.ts +25 -2
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
- package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
- package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +210 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +262 -0
- package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
- package/src/resources/extensions/gsd/tools/complete-slice.ts +38 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +49 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +8 -2
- package/src/resources/extensions/gsd/types.ts +3 -3
- package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +574 -0
- package/src/resources/extensions/gsd/uok/audit.ts +20 -2
- package/src/resources/extensions/gsd/uok/contracts.ts +65 -0
- package/src/resources/extensions/gsd/uok/dispatch-envelope.ts +56 -0
- package/src/resources/extensions/gsd/uok/execution-graph.ts +22 -0
- package/src/resources/extensions/gsd/uok/gate-runner.ts +65 -5
- package/src/resources/extensions/gsd/uok/gitops.ts +6 -1
- package/src/resources/extensions/gsd/uok/loop-adapter.ts +45 -10
- package/src/resources/extensions/gsd/uok/parity-report.ts +84 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +13 -5
- package/src/resources/extensions/gsd/uok/writer.ts +113 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +22 -3
- package/src/resources/extensions/gsd/workflow-mcp.ts +6 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +109 -7
- package/src/resources/extensions/gsd/worktree-resolver.ts +96 -9
- package/src/resources/extensions/gsd/worktree-telemetry.ts +322 -0
- package/src/resources/extensions/mcp-client/auth.ts +12 -1
- package/src/resources/extensions/mcp-client/index.ts +132 -11
- 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/cmux-events.ts +59 -0
- package/src/resources/extensions/shared/rtk-session-stats.ts +1 -2
- 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/src/resources/skills/create-skill/SKILL.md +2 -2
- package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
- package/src/resources/skills/create-skill/workflows/audit-skill.md +4 -4
- package/src/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
- package/dist/web/standalone/.next/server/chunks/7461.js +0 -1
- package/dist/web/standalone/.next/static/chunks/2826.e59e8578e2e28639.js +0 -9
- 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 -142
- 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/{pV-mPo7rYGb5JBC09C8GG → C1zT2kEfoLhDdbWPWKrXd}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{pV-mPo7rYGb5JBC09C8GG → C1zT2kEfoLhDdbWPWKrXd}/_ssgManifest.js +0 -0
|
@@ -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
|
-
});
|
|
@@ -142,9 +142,9 @@ test("Rule 3: A-A-A-A triggers Rule 2 not Rule 3", () => {
|
|
|
142
142
|
|
|
143
143
|
test("Rule 4: same ENOENT path in two entries triggers stuck", () => {
|
|
144
144
|
const result = detectStuck([
|
|
145
|
-
{ key: "A", error: "ENOENT: no such file or directory, access '/home/user/.
|
|
145
|
+
{ key: "A", error: "ENOENT: no such file or directory, access '/home/user/.agents/skills/debug-like-expert/SKILL.md'" },
|
|
146
146
|
{ key: "B" },
|
|
147
|
-
{ key: "A", error: "ENOENT: no such file or directory, access '/home/user/.
|
|
147
|
+
{ key: "A", error: "ENOENT: no such file or directory, access '/home/user/.agents/skills/debug-like-expert/SKILL.md'" },
|
|
148
148
|
]);
|
|
149
149
|
assert.notEqual(result, null);
|
|
150
150
|
assert.equal(result!.stuck, true);
|
|
@@ -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",
|
|
@@ -1,108 +1,109 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* survivor-branch-complete.test.ts — #2358
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* The bug: `bootstrapAutoSession` found a survivor milestone branch
|
|
5
|
+
* (previous session's worktree/branch that was never merged) but only
|
|
6
|
+
* triggered recovery when `state.phase === "pre-planning"`. In
|
|
7
|
+
* `phase === "complete"` the milestone artifacts existed but the
|
|
8
|
+
* finalization path (merge + cleanup) never ran, leaving the worktree
|
|
9
|
+
* and branch alive indefinitely.
|
|
9
10
|
*
|
|
10
|
-
* The fix broadens the
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* The fix broadens the detection to include `phase === "complete"` and
|
|
12
|
+
* routes to a finalize-via-mergeAndExit path.
|
|
13
|
+
*
|
|
14
|
+
* The previous version of this file was 4 scenarios that re-implemented
|
|
15
|
+
* the decision logic inline and called `.includes(phase)` on
|
|
16
|
+
* locally-declared arrays — testing the test, not the code. Called out
|
|
17
|
+
* in #4832 and parent #4784 as a pure-tautology case (zero imports
|
|
18
|
+
* from production).
|
|
19
|
+
*
|
|
20
|
+
* This rewrite imports `decideSurvivorAction` from auto-start.ts (a
|
|
21
|
+
* helper extracted in the accompanying refactor) and drives the full
|
|
22
|
+
* decision table through the real function. The helper is wired into
|
|
23
|
+
* `bootstrapAutoSession` at the two call sites that previously used
|
|
24
|
+
* inline conditionals, so the assertions here fail if someone reverts
|
|
25
|
+
* the helper or narrows its branches.
|
|
13
26
|
*/
|
|
14
27
|
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const testPhase = "complete";
|
|
38
|
-
|
|
39
|
-
const detectedBefore = phasesBeforeFix.includes(testPhase);
|
|
40
|
-
assertEq(detectedBefore, false, "before fix: phase=complete should NOT trigger survivor detection");
|
|
41
|
-
|
|
42
|
-
const detectedAfter = phasesAfterFix.includes(testPhase);
|
|
43
|
-
assertEq(detectedAfter, true, "after fix: phase=complete SHOULD trigger survivor detection");
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// ═══ Test: pre-planning survivor detection still works ═══════════════════════
|
|
47
|
-
|
|
48
|
-
{
|
|
49
|
-
console.log("\n=== #2358: pre-planning survivor detection is not broken ===");
|
|
50
|
-
|
|
51
|
-
const phasesAfterFix = ["pre-planning", "complete"];
|
|
52
|
-
const testPhase = "pre-planning";
|
|
53
|
-
|
|
54
|
-
const detected = phasesAfterFix.includes(testPhase);
|
|
55
|
-
assertEq(detected, true, "pre-planning should still trigger survivor detection after fix");
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// ═══ Test: other phases do NOT trigger survivor detection ════════════════════
|
|
59
|
-
|
|
60
|
-
{
|
|
61
|
-
console.log("\n=== #2358: other phases should NOT trigger survivor detection ===");
|
|
62
|
-
|
|
63
|
-
const phasesAfterFix = ["pre-planning", "complete"];
|
|
64
|
-
|
|
65
|
-
for (const phase of ["planning", "executing", "blocked", "needs-discussion"]) {
|
|
66
|
-
const detected = phasesAfterFix.includes(phase);
|
|
67
|
-
assertEq(detected, false, `phase=${phase} should NOT trigger survivor detection`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// ═══ Test: phase=complete + hasSurvivorBranch should trigger finalization ═════
|
|
72
|
-
|
|
73
|
-
{
|
|
74
|
-
console.log("\n=== #2358: phase=complete + survivor branch triggers finalization path ===");
|
|
75
|
-
|
|
76
|
-
// Simulate the decision logic after the fix:
|
|
77
|
-
// if (hasSurvivorBranch && state.phase === "complete") -> finalize
|
|
78
|
-
// if (hasSurvivorBranch && state.phase === "needs-discussion") -> discuss
|
|
79
|
-
// if (!hasSurvivorBranch && state.phase === "complete") -> showSmartEntry
|
|
80
|
-
|
|
81
|
-
const scenarios = [
|
|
82
|
-
{ hasSurvivorBranch: true, phase: "complete", expected: "finalize" },
|
|
83
|
-
{ hasSurvivorBranch: true, phase: "needs-discussion", expected: "discuss" },
|
|
84
|
-
{ hasSurvivorBranch: true, phase: "pre-planning", expected: "continue" },
|
|
85
|
-
{ hasSurvivorBranch: false, phase: "complete", expected: "showSmartEntry" },
|
|
86
|
-
];
|
|
87
|
-
|
|
88
|
-
for (const { hasSurvivorBranch, phase, expected } of scenarios) {
|
|
89
|
-
let result: string;
|
|
90
|
-
if (hasSurvivorBranch && phase === "complete") {
|
|
91
|
-
result = "finalize";
|
|
92
|
-
} else if (hasSurvivorBranch && phase === "needs-discussion") {
|
|
93
|
-
result = "discuss";
|
|
94
|
-
} else if (!hasSurvivorBranch && (!phase || phase === "complete")) {
|
|
95
|
-
result = "showSmartEntry";
|
|
96
|
-
} else {
|
|
97
|
-
result = "continue";
|
|
28
|
+
import { describe, test } from "node:test";
|
|
29
|
+
import assert from "node:assert/strict";
|
|
30
|
+
|
|
31
|
+
import { decideSurvivorAction } from "../auto-start.ts";
|
|
32
|
+
import type { SurvivorAction } from "../auto-start.ts";
|
|
33
|
+
|
|
34
|
+
describe("decideSurvivorAction (#2358)", () => {
|
|
35
|
+
test("no survivor branch → no action, regardless of phase", () => {
|
|
36
|
+
const phases = [
|
|
37
|
+
"pre-planning",
|
|
38
|
+
"planning",
|
|
39
|
+
"executing",
|
|
40
|
+
"complete",
|
|
41
|
+
"needs-discussion",
|
|
42
|
+
"blocked",
|
|
43
|
+
"",
|
|
44
|
+
null,
|
|
45
|
+
undefined,
|
|
46
|
+
];
|
|
47
|
+
for (const phase of phases) {
|
|
48
|
+
const got: SurvivorAction = decideSurvivorAction(false, phase);
|
|
49
|
+
assert.equal(got, "none", `phase=${phase ?? "(nullish)"} → expected 'none', got '${got}'`);
|
|
98
50
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("survivor + needs-discussion → 'discuss' (#1726)", () => {
|
|
54
|
+
assert.equal(decideSurvivorAction(true, "needs-discussion"), "discuss");
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("survivor + complete → 'finalize' (#2358 — the bug this regression guards)", () => {
|
|
58
|
+
// This is THE assertion that fails if someone reverts the fix and
|
|
59
|
+
// narrows the recovery to pre-planning only.
|
|
60
|
+
assert.equal(decideSurvivorAction(true, "complete"), "finalize");
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("survivor + other phase → 'none' (caller continues normal flow)", () => {
|
|
64
|
+
// pre-planning, planning, executing, blocked — survivor alone is
|
|
65
|
+
// not sufficient to trigger recovery. Normal auto-mode picks up
|
|
66
|
+
// from state. This protects against regressions that try to run
|
|
67
|
+
// finalize on every survivor regardless of phase.
|
|
68
|
+
const passThroughPhases = ["pre-planning", "planning", "executing", "blocked", ""];
|
|
69
|
+
for (const phase of passThroughPhases) {
|
|
70
|
+
assert.equal(
|
|
71
|
+
decideSurvivorAction(true, phase),
|
|
72
|
+
"none",
|
|
73
|
+
`survivor + phase=${phase} → expected 'none', got ${decideSurvivorAction(true, phase)}`,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("decision table covers the three outcomes the bootstrap code needs", () => {
|
|
79
|
+
// Belt-and-suspenders: enumerate (hasSurvivor, phase) and assert
|
|
80
|
+
// the complete truth table. If someone adds a 4th outcome, this
|
|
81
|
+
// test fails loudly so they must update both the helper and the
|
|
82
|
+
// bootstrap wiring.
|
|
83
|
+
const cases: Array<{ hasSurvivor: boolean; phase: string | null; expected: SurvivorAction }> = [
|
|
84
|
+
{ hasSurvivor: true, phase: "needs-discussion", expected: "discuss" },
|
|
85
|
+
{ hasSurvivor: true, phase: "complete", expected: "finalize" },
|
|
86
|
+
{ hasSurvivor: true, phase: "pre-planning", expected: "none" },
|
|
87
|
+
{ hasSurvivor: true, phase: "planning", expected: "none" },
|
|
88
|
+
{ hasSurvivor: true, phase: null, expected: "none" },
|
|
89
|
+
{ hasSurvivor: false, phase: "complete", expected: "none" },
|
|
90
|
+
{ hasSurvivor: false, phase: "needs-discussion", expected: "none" },
|
|
91
|
+
{ hasSurvivor: false, phase: null, expected: "none" },
|
|
92
|
+
];
|
|
93
|
+
const outcomes = new Set<SurvivorAction>();
|
|
94
|
+
for (const { hasSurvivor, phase, expected } of cases) {
|
|
95
|
+
const got = decideSurvivorAction(hasSurvivor, phase);
|
|
96
|
+
outcomes.add(got);
|
|
97
|
+
assert.equal(
|
|
98
|
+
got,
|
|
99
|
+
expected,
|
|
100
|
+
`(hasSurvivor=${hasSurvivor}, phase=${phase}) → expected '${expected}', got '${got}'`,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
assert.deepEqual(
|
|
104
|
+
[...outcomes].sort(),
|
|
105
|
+
["discuss", "finalize", "none"],
|
|
106
|
+
"decision function should produce exactly three outcomes",
|
|
104
107
|
);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
report();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
@@ -120,3 +120,34 @@ test('sync-lock: overrides stale lock file (mtime backdated)', (t) => {
|
|
|
120
120
|
cleanupDir(base);
|
|
121
121
|
}
|
|
122
122
|
});
|
|
123
|
+
|
|
124
|
+
test('sync-lock: EPERM from live owner PID prevents stale lock stealing', () => {
|
|
125
|
+
const base = tempDir();
|
|
126
|
+
fs.mkdirSync(path.join(base, '.gsd'), { recursive: true });
|
|
127
|
+
const lockPath = path.join(base, '.gsd', 'sync.lock');
|
|
128
|
+
const fakePid = process.pid + 100_000;
|
|
129
|
+
const originalKill = process.kill;
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
fs.writeFileSync(lockPath, JSON.stringify({ pid: fakePid, acquired_at: new Date(0).toISOString() }));
|
|
133
|
+
const staleTime = new Date(Date.now() - 120_000);
|
|
134
|
+
fs.utimesSync(lockPath, staleTime, staleTime);
|
|
135
|
+
|
|
136
|
+
process.kill = ((pid: number, signal?: NodeJS.Signals | number) => {
|
|
137
|
+
if (pid === fakePid && signal === 0) {
|
|
138
|
+
const err = new Error('operation not permitted') as NodeJS.ErrnoException;
|
|
139
|
+
err.code = 'EPERM';
|
|
140
|
+
throw err;
|
|
141
|
+
}
|
|
142
|
+
return originalKill(pid, signal);
|
|
143
|
+
}) as typeof process.kill;
|
|
144
|
+
|
|
145
|
+
const result = acquireSyncLock(base, 100);
|
|
146
|
+
assert.strictEqual(result.acquired, false, 'EPERM owner should be treated as live');
|
|
147
|
+
const content = JSON.parse(fs.readFileSync(lockPath, 'utf-8'));
|
|
148
|
+
assert.strictEqual(content.pid, fakePid, 'lock file should not be overwritten');
|
|
149
|
+
} finally {
|
|
150
|
+
process.kill = originalKill;
|
|
151
|
+
cleanupDir(base);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
@@ -13,6 +13,7 @@ import { describe, it } from 'node:test'
|
|
|
13
13
|
import assert from 'node:assert/strict'
|
|
14
14
|
import { readFileSync } from 'node:fs'
|
|
15
15
|
import { resolve } from 'node:path'
|
|
16
|
+
import { extractSourceRegion } from "./test-helpers.ts";
|
|
16
17
|
|
|
17
18
|
const src = readFileSync(
|
|
18
19
|
resolve(process.cwd(), 'src', 'resources', 'extensions', 'gsd', 'auto-worktree.ts'),
|
|
@@ -33,14 +34,14 @@ describe('syncWorktreeStateBack skips current milestone (#3641)', () => {
|
|
|
33
34
|
assert.ok(fnStart !== -1)
|
|
34
35
|
|
|
35
36
|
// Get a reasonable portion of the function
|
|
36
|
-
const fnBlock = src
|
|
37
|
+
const fnBlock = extractSourceRegion(src, 'function syncWorktreeStateBack(', { fromIdx: fnStart })
|
|
37
38
|
|
|
38
39
|
// Find the for loop iterating milestones
|
|
39
40
|
const loopIdx = fnBlock.indexOf('for (const mid of wtMilestones)')
|
|
40
41
|
assert.ok(loopIdx !== -1, 'milestone iteration loop must exist')
|
|
41
42
|
|
|
42
43
|
// After the loop, there should be the skip guard
|
|
43
|
-
const loopBody = fnBlock
|
|
44
|
+
const loopBody = extractSourceRegion(fnBlock, 'for (const mid of wtMilestones)', { fromIdx: loopIdx })
|
|
44
45
|
assert.ok(
|
|
45
46
|
loopBody.includes('mid === milestoneId'),
|
|
46
47
|
'mid === milestoneId skip guard must exist inside the milestone loop',
|
|
@@ -55,7 +56,7 @@ describe('syncWorktreeStateBack skips current milestone (#3641)', () => {
|
|
|
55
56
|
const fnStart = src.indexOf('function syncWorktreeStateBack(')
|
|
56
57
|
assert.ok(fnStart !== -1)
|
|
57
58
|
|
|
58
|
-
const fnBlock = src
|
|
59
|
+
const fnBlock = extractSourceRegion(src, 'function syncWorktreeStateBack(', { fromIdx: fnStart })
|
|
59
60
|
|
|
60
61
|
assert.ok(
|
|
61
62
|
fnBlock.includes('syncMilestoneDir('),
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for test-helpers.ts — the timing helpers (waitForCondition,
|
|
3
|
+
* findLine) used to replace magic-number sleeps and positional line
|
|
4
|
+
* indexing in the test suite.
|
|
5
|
+
*
|
|
6
|
+
* The `extractSourceRegion` helper (introduced in #4773/#4774) is
|
|
7
|
+
* deliberately NOT tested here. It is the source-grep antipattern that
|
|
8
|
+
* #4784 names as the root problem; tests against toy fixtures only
|
|
9
|
+
* legitimize the pattern without validating behaviour. Its test cases
|
|
10
|
+
* were removed as part of #4834 — callers are being migrated to
|
|
11
|
+
* behaviour tests one file at a time, after which the helper is slated
|
|
12
|
+
* for deletion.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import test from "node:test";
|
|
16
|
+
import assert from "node:assert/strict";
|
|
17
|
+
|
|
18
|
+
import { waitForCondition, findLine } from "./test-helpers.ts";
|
|
19
|
+
|
|
20
|
+
// ─── waitForCondition ─────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
test("waitForCondition returns immediately when condition is true", async () => {
|
|
23
|
+
const result = await waitForCondition(() => true);
|
|
24
|
+
assert.equal(result, true);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("waitForCondition waits and returns when condition becomes true", async () => {
|
|
28
|
+
let flipped = false;
|
|
29
|
+
setTimeout(() => { flipped = true; }, 30);
|
|
30
|
+
const result = await waitForCondition(() => flipped, { intervalMs: 5 });
|
|
31
|
+
assert.equal(result, true);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("waitForCondition throws after timeout with description", async () => {
|
|
35
|
+
await assert.rejects(
|
|
36
|
+
waitForCondition(() => false, { timeoutMs: 50, intervalMs: 5, description: "the flag to flip" }),
|
|
37
|
+
/waiting for the flag to flip/i,
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("waitForCondition surfaces last error on timeout", async () => {
|
|
42
|
+
await assert.rejects(
|
|
43
|
+
waitForCondition(
|
|
44
|
+
() => { throw new Error("probe failed"); },
|
|
45
|
+
{ timeoutMs: 30, intervalMs: 5, description: "probe" },
|
|
46
|
+
),
|
|
47
|
+
/probe failed/,
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("waitForCondition returns the truthy value (not just true)", async () => {
|
|
52
|
+
let n = 0;
|
|
53
|
+
const result = await waitForCondition(() => {
|
|
54
|
+
n++;
|
|
55
|
+
return n >= 3 ? { ready: true, iteration: n } : null;
|
|
56
|
+
}, { intervalMs: 5 });
|
|
57
|
+
// The helper only resolves when the condition returns a truthy value, so
|
|
58
|
+
// result cannot be null here. Assert it and narrow for the follow-ups.
|
|
59
|
+
assert.ok(result, "waitForCondition must resolve with a truthy value, not null");
|
|
60
|
+
assert.equal(result.ready, true);
|
|
61
|
+
assert.equal(result.iteration, 3);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// ─── findLine ─────────────────────────────────────────────────────────────
|
|
65
|
+
|
|
66
|
+
test("findLine locates a line by regex", () => {
|
|
67
|
+
const output = "header\nstatus: ok\nfooter";
|
|
68
|
+
const match = findLine(output, /^status:/);
|
|
69
|
+
assert.equal(match.index, 1);
|
|
70
|
+
assert.equal(match.text, "status: ok");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("findLine locates a line by predicate", () => {
|
|
74
|
+
const output = "a\nb\nc";
|
|
75
|
+
const match = findLine(output, (l) => l === "b");
|
|
76
|
+
assert.equal(match.index, 1);
|
|
77
|
+
assert.equal(match.text, "b");
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("findLine throws with preview when no line matches", () => {
|
|
81
|
+
assert.throws(
|
|
82
|
+
() => findLine("a\nb\nc", /NOTFOUND/),
|
|
83
|
+
/First 10 lines/,
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("findLine resets lastIndex between lines for /g regex patterns", () => {
|
|
88
|
+
// Without the reset, RegExp.test with /g flag stateful-advances lastIndex
|
|
89
|
+
// and can skip matches on subsequent calls. Verify the reset keeps
|
|
90
|
+
// per-line testing deterministic.
|
|
91
|
+
const output = "foo\nfoo\nfoo";
|
|
92
|
+
const globalRe = /foo/g;
|
|
93
|
+
const match = findLine(output, globalRe);
|
|
94
|
+
assert.equal(match.index, 0);
|
|
95
|
+
// Second call on the same pattern must also match — would fail without reset
|
|
96
|
+
const match2 = findLine(output, globalRe);
|
|
97
|
+
assert.equal(match2.index, 0);
|
|
98
|
+
});
|