gsd-pi 2.66.1-dev.ed243f2 → 2.67.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/dist/claude-cli-check.d.ts +8 -0
- package/dist/claude-cli-check.js +36 -0
- package/dist/cli.js +40 -0
- package/dist/onboarding.js +19 -2
- package/dist/resources/extensions/ask-user-questions.js +79 -11
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +4 -3
- package/dist/resources/extensions/claude-code-cli/readiness.js +63 -12
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +10 -3
- package/dist/resources/extensions/gsd/auto/loop.js +13 -1
- package/dist/resources/extensions/gsd/auto/phases.js +22 -3
- package/dist/resources/extensions/gsd/auto/run-unit.js +10 -2
- package/dist/resources/extensions/gsd/auto/session.js +1 -1
- package/dist/resources/extensions/gsd/auto-dashboard.js +65 -15
- package/dist/resources/extensions/gsd/auto-dispatch.js +30 -28
- package/dist/resources/extensions/gsd/auto-model-selection.js +12 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +173 -25
- package/dist/resources/extensions/gsd/auto-recovery.js +11 -12
- package/dist/resources/extensions/gsd/auto.js +13 -1
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +18 -6
- package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +5 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +59 -5
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +8 -5
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +186 -14
- package/dist/resources/extensions/gsd/codebase-generator.js +4 -0
- package/dist/resources/extensions/gsd/commands/handlers/core.js +3 -3
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -4
- package/dist/resources/extensions/gsd/context-store.js +134 -2
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +3 -1
- package/dist/resources/extensions/gsd/detection.js +6 -0
- package/dist/resources/extensions/gsd/files.js +19 -2
- package/dist/resources/extensions/gsd/guided-flow.js +12 -8
- package/dist/resources/extensions/gsd/index.js +1 -1
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +2 -0
- package/dist/resources/extensions/gsd/parsers-legacy.js +3 -1
- package/dist/resources/extensions/gsd/preferences.js +6 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-prepared.md +7 -7
- package/dist/resources/extensions/gsd/prompts/discuss.md +3 -3
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +3 -3
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +3 -1
- package/dist/resources/extensions/gsd/prompts/rethink.md +6 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +4 -4
- package/dist/resources/extensions/gsd/prompts/worktree-merge.md +3 -1
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +2 -1
- package/dist/resources/extensions/gsd/state.js +2 -1
- package/dist/resources/extensions/gsd/visualizer-overlay.js +27 -26
- package/dist/resources/extensions/gsd/workflow-reconcile.js +46 -7
- package/dist/resources/extensions/remote-questions/manager.js +8 -0
- package/dist/resources/extensions/shared/interview-ui.js +10 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- 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/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- 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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +14 -14
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +4 -3
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.js +11 -1
- package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.js +60 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
- package/packages/pi-ai/dist/utils/tests/json-parse.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/tests/json-parse.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/tests/json-parse.test.js +14 -0
- package/packages/pi-ai/dist/utils/tests/json-parse.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +10 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
- package/packages/pi-ai/src/providers/anthropic-shared.ts +4 -3
- package/packages/pi-ai/src/utils/json-parse.ts +11 -1
- package/packages/pi-ai/src/utils/repair-tool-json.ts +69 -1
- package/packages/pi-ai/src/utils/tests/json-parse.test.ts +17 -0
- package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +13 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +16 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +58 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +58 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js +17 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js.map +1 -0
- 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 +2 -1
- 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 +1 -0
- 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 +9 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +4 -0
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +69 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +66 -1
- package/packages/pi-coding-agent/src/core/sdk.ts +5 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/provider-display-name.test.ts +18 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +11 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/scoped-models-selector.ts +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +2 -2
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js +13 -0
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +35 -0
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/tui.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +43 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -0
- package/packages/pi-tui/dist/autocomplete.d.ts.map +1 -1
- package/packages/pi-tui/dist/autocomplete.js +9 -7
- package/packages/pi-tui/dist/autocomplete.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/editor.test.d.ts +2 -0
- package/packages/pi-tui/dist/components/__tests__/editor.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/components/__tests__/editor.test.js +54 -0
- package/packages/pi-tui/dist/components/__tests__/editor.test.js.map +1 -0
- package/packages/pi-tui/dist/components/editor.d.ts +3 -1
- package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/editor.js +14 -3
- package/packages/pi-tui/dist/components/editor.js.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.js +6 -0
- package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +8 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/__tests__/autocomplete.test.ts +15 -0
- package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +43 -0
- package/packages/pi-tui/src/__tests__/tui.test.ts +50 -0
- package/packages/pi-tui/src/autocomplete.ts +9 -7
- package/packages/pi-tui/src/components/__tests__/editor.test.ts +64 -0
- package/packages/pi-tui/src/components/editor.ts +14 -3
- package/packages/pi-tui/src/stdin-buffer.ts +7 -0
- package/packages/pi-tui/src/tui.ts +9 -0
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +103 -11
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +4 -3
- package/src/resources/extensions/claude-code-cli/readiness.ts +67 -12
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +12 -3
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +17 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +18 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -1
- package/src/resources/extensions/gsd/auto/loop.ts +14 -1
- package/src/resources/extensions/gsd/auto/phases.ts +27 -4
- package/src/resources/extensions/gsd/auto/run-unit.ts +14 -2
- package/src/resources/extensions/gsd/auto/session.ts +1 -1
- package/src/resources/extensions/gsd/auto-dashboard.ts +76 -16
- package/src/resources/extensions/gsd/auto-dispatch.ts +36 -35
- package/src/resources/extensions/gsd/auto-model-selection.ts +12 -3
- package/src/resources/extensions/gsd/auto-prompts.ts +195 -25
- package/src/resources/extensions/gsd/auto-recovery.ts +15 -15
- package/src/resources/extensions/gsd/auto.ts +12 -1
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +27 -6
- package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +6 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +67 -6
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +11 -8
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +209 -16
- package/src/resources/extensions/gsd/codebase-generator.ts +4 -0
- package/src/resources/extensions/gsd/commands/handlers/core.ts +6 -6
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +11 -4
- package/src/resources/extensions/gsd/context-store.ts +167 -2
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +3 -1
- package/src/resources/extensions/gsd/detection.ts +6 -0
- package/src/resources/extensions/gsd/files.ts +21 -2
- package/src/resources/extensions/gsd/guided-flow.ts +15 -8
- package/src/resources/extensions/gsd/index.ts +6 -0
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +2 -0
- package/src/resources/extensions/gsd/parsers-legacy.ts +3 -1
- package/src/resources/extensions/gsd/preferences.ts +6 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-prepared.md +7 -7
- package/src/resources/extensions/gsd/prompts/discuss.md +3 -3
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +3 -3
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +3 -1
- package/src/resources/extensions/gsd/prompts/rethink.md +6 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +4 -4
- package/src/resources/extensions/gsd/prompts/worktree-merge.md +3 -1
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +4 -1
- package/src/resources/extensions/gsd/state.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +52 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +50 -2
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +21 -7
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/context-store.test.ts +176 -0
- package/src/resources/extensions/gsd/tests/core-overlay-fallback.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/decision-scope-cascade.test.ts +370 -0
- package/src/resources/extensions/gsd/tests/detection.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +53 -13
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/measurement.test.ts +531 -0
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +3 -4
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +71 -2
- package/src/resources/extensions/gsd/tests/parsers.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +60 -0
- package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/reactive-graph.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/register-shortcuts.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/remote-questions.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +91 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +210 -35
- package/src/resources/extensions/gsd/visualizer-overlay.ts +31 -27
- package/src/resources/extensions/gsd/workflow-reconcile.ts +59 -8
- package/src/resources/extensions/remote-questions/manager.ts +9 -0
- package/src/resources/extensions/shared/interview-ui.ts +13 -0
- package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
- /package/dist/web/standalone/.next/static/{HAq0VE4k68rhRvJbQL1VW → DFZllMYDbO0OwyS6FSvm5}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{HAq0VE4k68rhRvJbQL1VW → DFZllMYDbO0OwyS6FSvm5}/_ssgManifest.js +0 -0
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
detectProjectState,
|
|
18
18
|
detectV1Planning,
|
|
19
19
|
detectProjectSignals,
|
|
20
|
+
scanProjectFiles,
|
|
20
21
|
} from "../detection.ts";
|
|
21
22
|
|
|
22
23
|
function makeTempDir(prefix: string): string {
|
|
@@ -1188,3 +1189,39 @@ test("detectProjectSignals: Spring Boot settings-defined catalog accessor emits
|
|
|
1188
1189
|
cleanup(dir);
|
|
1189
1190
|
}
|
|
1190
1191
|
});
|
|
1192
|
+
|
|
1193
|
+
// ─── scanProjectFiles: RECURSIVE_SCAN_IGNORED_DIRS ──────────────────────
|
|
1194
|
+
|
|
1195
|
+
test("scanProjectFiles: excludes .claude, .gsd, .planning, .plans, .cursor, .vscode directories", () => {
|
|
1196
|
+
const dir = makeTempDir("scan-ignore-dotdirs");
|
|
1197
|
+
try {
|
|
1198
|
+
// Create project files that should be included
|
|
1199
|
+
mkdirSync(join(dir, "src"), { recursive: true });
|
|
1200
|
+
writeFileSync(join(dir, "src", "main.ts"), "// main\n", "utf-8");
|
|
1201
|
+
writeFileSync(join(dir, "README.md"), "# Project\n", "utf-8");
|
|
1202
|
+
|
|
1203
|
+
// Create tool directories that should be excluded
|
|
1204
|
+
const excludedDirs = [".claude", ".gsd", ".planning", ".plans", ".cursor", ".vscode"];
|
|
1205
|
+
for (const d of excludedDirs) {
|
|
1206
|
+
mkdirSync(join(dir, d), { recursive: true });
|
|
1207
|
+
writeFileSync(join(dir, d, "config.json"), "{}\n", "utf-8");
|
|
1208
|
+
}
|
|
1209
|
+
// Nested .claude directory
|
|
1210
|
+
mkdirSync(join(dir, ".claude", "memory"), { recursive: true });
|
|
1211
|
+
writeFileSync(join(dir, ".claude", "memory", "user.md"), "# Memory\n", "utf-8");
|
|
1212
|
+
|
|
1213
|
+
const files = scanProjectFiles(dir);
|
|
1214
|
+
|
|
1215
|
+
// Should include project files
|
|
1216
|
+
assert.ok(files.includes("src/main.ts"), "should include src/main.ts");
|
|
1217
|
+
assert.ok(files.includes("README.md"), "should include README.md");
|
|
1218
|
+
|
|
1219
|
+
// Should exclude all tool directories
|
|
1220
|
+
for (const d of excludedDirs) {
|
|
1221
|
+
const hasExcluded = files.some((f) => f.startsWith(`${d}/`));
|
|
1222
|
+
assert.ok(!hasExcluded, `should exclude ${d}/ directory but found: ${files.filter((f) => f.startsWith(`${d}/`)).join(", ")}`);
|
|
1223
|
+
}
|
|
1224
|
+
} finally {
|
|
1225
|
+
cleanup(dir);
|
|
1226
|
+
}
|
|
1227
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
4
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
|
|
8
|
+
import { validateFileChanges } from "../safety/file-change-validator.ts";
|
|
9
|
+
|
|
10
|
+
function git(cwd: string, ...args: string[]): string {
|
|
11
|
+
return execFileSync("git", args, {
|
|
12
|
+
cwd,
|
|
13
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
14
|
+
encoding: "utf-8",
|
|
15
|
+
}).trim();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
test("validateFileChanges ignores inline descriptions in expected output paths", (t) => {
|
|
19
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-file-change-validator-"));
|
|
20
|
+
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
21
|
+
|
|
22
|
+
mkdirSync(join(base, "definitions"), { recursive: true });
|
|
23
|
+
git(base, "init");
|
|
24
|
+
git(base, "config", "user.email", "test@example.com");
|
|
25
|
+
git(base, "config", "user.name", "Test User");
|
|
26
|
+
|
|
27
|
+
const target = join(base, "definitions", "ac-audit.md");
|
|
28
|
+
writeFileSync(target, "initial\n");
|
|
29
|
+
git(base, "add", ".");
|
|
30
|
+
git(base, "commit", "-m", "initial");
|
|
31
|
+
|
|
32
|
+
writeFileSync(target, "updated\n");
|
|
33
|
+
git(base, "add", ".");
|
|
34
|
+
git(base, "commit", "-m", "update");
|
|
35
|
+
|
|
36
|
+
const audit = validateFileChanges(
|
|
37
|
+
base,
|
|
38
|
+
["definitions/ac-audit.md — current state of AC CRM, tags, pipelines, automations"],
|
|
39
|
+
[],
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
assert.ok(audit, "audit should be produced when expected output exists");
|
|
43
|
+
assert.deepEqual(audit.unexpectedFiles, []);
|
|
44
|
+
assert.deepEqual(audit.missingFiles, []);
|
|
45
|
+
assert.equal(
|
|
46
|
+
audit.violations.some((v) => v.severity === "warning"),
|
|
47
|
+
false,
|
|
48
|
+
"described expected output should not trigger unexpected-file warnings",
|
|
49
|
+
);
|
|
50
|
+
});
|
|
@@ -245,6 +245,41 @@ describe('gsd-tools', () => {
|
|
|
245
245
|
}
|
|
246
246
|
});
|
|
247
247
|
|
|
248
|
+
test('gsd_summary_save supports CONTEXT-DRAFT persistence', async () => {
|
|
249
|
+
const tmpDir = makeTmpDir();
|
|
250
|
+
try {
|
|
251
|
+
const dbPath = path.join(tmpDir, '.gsd', 'gsd.db');
|
|
252
|
+
openDatabase(dbPath);
|
|
253
|
+
|
|
254
|
+
await saveArtifactToDb(
|
|
255
|
+
{
|
|
256
|
+
path: 'milestones/M001/M001-CONTEXT-DRAFT.md',
|
|
257
|
+
artifact_type: 'CONTEXT-DRAFT',
|
|
258
|
+
content: '# M001 Draft Context\n\nDraft notes.',
|
|
259
|
+
milestone_id: 'M001',
|
|
260
|
+
},
|
|
261
|
+
tmpDir,
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
const draftPath = path.join(tmpDir, '.gsd', 'milestones', 'M001', 'M001-CONTEXT-DRAFT.md');
|
|
265
|
+
assert.ok(fs.existsSync(draftPath), 'Draft context file should be created');
|
|
266
|
+
const draftContent = fs.readFileSync(draftPath, 'utf-8');
|
|
267
|
+
assert.ok(draftContent.includes('Draft Context'), 'Draft context file should contain draft content');
|
|
268
|
+
|
|
269
|
+
const adapter = _getAdapter();
|
|
270
|
+
assert.ok(adapter !== null, 'Adapter should be available');
|
|
271
|
+
const rows = adapter!.prepare(
|
|
272
|
+
"SELECT * FROM artifacts WHERE path = 'milestones/M001/M001-CONTEXT-DRAFT.md'",
|
|
273
|
+
).all();
|
|
274
|
+
assert.deepStrictEqual(rows.length, 1, 'Should have 1 draft artifact row');
|
|
275
|
+
assert.deepStrictEqual(rows[0]['artifact_type'] as string, 'CONTEXT-DRAFT', 'Artifact type should be CONTEXT-DRAFT');
|
|
276
|
+
|
|
277
|
+
closeDatabase();
|
|
278
|
+
} finally {
|
|
279
|
+
cleanupDir(tmpDir);
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
|
|
248
283
|
test('DB unavailable error paths', async () => {
|
|
249
284
|
// (d) All tools return isError when DB unavailable
|
|
250
285
|
// Close any open DB and don't open a new one
|
|
@@ -10,11 +10,15 @@
|
|
|
10
10
|
|
|
11
11
|
import { describe, test, beforeEach } from "node:test";
|
|
12
12
|
import assert from "node:assert/strict";
|
|
13
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
import { tmpdir } from "node:os";
|
|
13
16
|
|
|
14
17
|
import {
|
|
15
18
|
getDiscussionMilestoneId,
|
|
16
19
|
setPendingAutoStart,
|
|
17
20
|
clearPendingAutoStart,
|
|
21
|
+
checkAutoStartAfterDiscuss,
|
|
18
22
|
} from "../guided-flow.ts";
|
|
19
23
|
|
|
20
24
|
// ─── Tests ─────────────────────────────────────────────────────────────────
|
|
@@ -95,3 +99,33 @@ describe("#2985 Bug 4 — getDiscussionMilestoneId must be keyed by basePath", (
|
|
|
95
99
|
assert.equal(result, "M001", "should return the only active milestone for backward compat");
|
|
96
100
|
});
|
|
97
101
|
});
|
|
102
|
+
|
|
103
|
+
test("checkAutoStartAfterDiscuss fails closed when a multi-milestone manifest is missing", () => {
|
|
104
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-auto-start-manifest-"));
|
|
105
|
+
try {
|
|
106
|
+
const gsdDir = join(base, ".gsd");
|
|
107
|
+
const milestoneDir = join(gsdDir, "milestones", "M001");
|
|
108
|
+
mkdirSync(milestoneDir, { recursive: true });
|
|
109
|
+
mkdirSync(join(gsdDir, "milestones", "M002"), { recursive: true });
|
|
110
|
+
writeFileSync(
|
|
111
|
+
join(gsdDir, "PROJECT.md"),
|
|
112
|
+
`# Project\n\n| M001 | First milestone | active |\n| M002 | Second milestone | queued |\n`,
|
|
113
|
+
);
|
|
114
|
+
writeFileSync(join(gsdDir, "STATE.md"), "# State\n");
|
|
115
|
+
writeFileSync(join(milestoneDir, "M001-CONTEXT.md"), "# M001 Context\n");
|
|
116
|
+
|
|
117
|
+
clearPendingAutoStart();
|
|
118
|
+
setPendingAutoStart(base, {
|
|
119
|
+
basePath: base,
|
|
120
|
+
milestoneId: "M001",
|
|
121
|
+
ctx: { ui: { notify: () => undefined } } as any,
|
|
122
|
+
pi: { setActiveTools: () => undefined, getActiveTools: () => [] } as any,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const started = checkAutoStartAfterDiscuss();
|
|
126
|
+
assert.equal(started, false, "auto-start should fail closed without the manifest");
|
|
127
|
+
} finally {
|
|
128
|
+
clearPendingAutoStart();
|
|
129
|
+
rmSync(base, { recursive: true, force: true });
|
|
130
|
+
}
|
|
131
|
+
});
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
formatRelativeTime,
|
|
10
10
|
type HealthWidgetData,
|
|
11
11
|
} from "../health-widget-core.ts";
|
|
12
|
+
import { registerHooks } from "../bootstrap/register-hooks.ts";
|
|
12
13
|
|
|
13
14
|
function makeTempDir(prefix: string): string {
|
|
14
15
|
const dir = join(
|
|
@@ -177,3 +178,47 @@ test("detectHealthWidgetProjectState: metrics file alone does not imply project"
|
|
|
177
178
|
);
|
|
178
179
|
assert.equal(detectHealthWidgetProjectState(dir), "initialized");
|
|
179
180
|
});
|
|
181
|
+
|
|
182
|
+
test("session_start bootstraps the health widget alongside notifications", async (t) => {
|
|
183
|
+
const dir = makeTempDir("bootstrap");
|
|
184
|
+
mkdirSync(join(dir, ".gsd"), { recursive: true });
|
|
185
|
+
|
|
186
|
+
const originalCwd = process.cwd();
|
|
187
|
+
process.chdir(dir);
|
|
188
|
+
t.after(() => {
|
|
189
|
+
process.chdir(originalCwd);
|
|
190
|
+
cleanup(dir);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
const widgets: string[] = [];
|
|
194
|
+
const handlers = new Map<string, (event: unknown, ctx: any) => Promise<void> | void>();
|
|
195
|
+
const pi = {
|
|
196
|
+
on(event: string, handler: (event: unknown, ctx: any) => Promise<void> | void) {
|
|
197
|
+
handlers.set(event, handler);
|
|
198
|
+
},
|
|
199
|
+
} as any;
|
|
200
|
+
|
|
201
|
+
registerHooks(pi);
|
|
202
|
+
const sessionStart = handlers.get("session_start");
|
|
203
|
+
assert.ok(sessionStart, "session_start handler is registered");
|
|
204
|
+
|
|
205
|
+
await sessionStart!({}, {
|
|
206
|
+
hasUI: true,
|
|
207
|
+
ui: {
|
|
208
|
+
notify: () => {},
|
|
209
|
+
setStatus: () => {},
|
|
210
|
+
setWorkingMessage: () => {},
|
|
211
|
+
onTerminalInput: () => () => {},
|
|
212
|
+
setWidget: (key: string) => {
|
|
213
|
+
widgets.push(key);
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
sessionManager: {
|
|
217
|
+
getSessionId: () => null,
|
|
218
|
+
},
|
|
219
|
+
model: null,
|
|
220
|
+
} as any);
|
|
221
|
+
|
|
222
|
+
assert.ok(widgets.includes("gsd-health"), "health widget is bootstrapped");
|
|
223
|
+
assert.ok(widgets.includes("gsd-notifications"), "notification widget still boots");
|
|
224
|
+
});
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import { mkdirSync, writeFileSync, existsSync, readFileSync, rmSync } from "node:fs";
|
|
3
|
+
import { mkdirSync, writeFileSync, existsSync, readFileSync, rmSync, chmodSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
7
|
+
import { execFileSync } from "node:child_process";
|
|
7
8
|
|
|
8
9
|
import {
|
|
9
10
|
resolveExpectedArtifactPath,
|
|
@@ -11,6 +12,7 @@ import {
|
|
|
11
12
|
diagnoseExpectedArtifact,
|
|
12
13
|
buildLoopRemediationSteps,
|
|
13
14
|
hasImplementationArtifacts,
|
|
15
|
+
reconcileMergeState,
|
|
14
16
|
} from "../../auto-recovery.ts";
|
|
15
17
|
import { parseRoadmap, parsePlan } from "../../parsers-legacy.ts";
|
|
16
18
|
import { parseTaskPlanFile, clearParseCache } from "../../files.ts";
|
|
@@ -669,8 +671,6 @@ test("#793: invalidateAllCaches clears all caches so deriveState sees fresh disk
|
|
|
669
671
|
|
|
670
672
|
// ─── hasImplementationArtifacts (#1703) ───────────────────────────────────
|
|
671
673
|
|
|
672
|
-
import { execFileSync } from "node:child_process";
|
|
673
|
-
|
|
674
674
|
function makeGitBase(): string {
|
|
675
675
|
const base = join(tmpdir(), `gsd-test-git-${randomUUID()}`);
|
|
676
676
|
mkdirSync(base, { recursive: true });
|
|
@@ -745,9 +745,6 @@ test("verifyExpectedArtifact complete-milestone fails with only .gsd/ files (#17
|
|
|
745
745
|
|
|
746
746
|
// ─── reconcileMergeState: silent nativeCommit failure (#2542) ─────────────
|
|
747
747
|
|
|
748
|
-
import { reconcileMergeState } from "../../auto-recovery.ts";
|
|
749
|
-
import { chmodSync } from "node:fs";
|
|
750
|
-
|
|
751
748
|
function makeMockCtx(): { ctx: any; notifications: Array<{ msg: string; level: string }> } {
|
|
752
749
|
const notifications: Array<{ msg: string; level: string }> = [];
|
|
753
750
|
const ctx = {
|
|
@@ -760,7 +757,7 @@ function makeMockCtx(): { ctx: any; notifications: Array<{ msg: string; level: s
|
|
|
760
757
|
return { ctx, notifications };
|
|
761
758
|
}
|
|
762
759
|
|
|
763
|
-
test("reconcileMergeState returns
|
|
760
|
+
test("reconcileMergeState returns blocked and notifies error when nativeCommit fails (#2542)", (t) => {
|
|
764
761
|
const base = makeGitBase();
|
|
765
762
|
t.after(() => cleanup(base));
|
|
766
763
|
|
|
@@ -786,9 +783,7 @@ test("reconcileMergeState returns false and notifies error when nativeCommit fai
|
|
|
786
783
|
const { ctx, notifications } = makeMockCtx();
|
|
787
784
|
const result = reconcileMergeState(base, ctx);
|
|
788
785
|
|
|
789
|
-
|
|
790
|
-
// (Currently it silently swallows the error and returns true — this test should FAIL before the fix)
|
|
791
|
-
assert.equal(result, false, "reconcileMergeState should return false when nativeCommit fails");
|
|
786
|
+
assert.equal(result, "blocked", "reconcileMergeState should return blocked when nativeCommit fails");
|
|
792
787
|
const errorNotifications = notifications.filter(n => n.level === "error");
|
|
793
788
|
assert.ok(errorNotifications.length > 0, "should notify an error when nativeCommit fails");
|
|
794
789
|
assert.ok(
|
|
@@ -797,18 +792,63 @@ test("reconcileMergeState returns false and notifies error when nativeCommit fai
|
|
|
797
792
|
);
|
|
798
793
|
});
|
|
799
794
|
|
|
800
|
-
test("reconcileMergeState returns
|
|
801
|
-
// When there's no MERGE_HEAD or SQUASH_MSG, reconcileMergeState returns false (no dirty state)
|
|
795
|
+
test("reconcileMergeState returns clean when no merge state present", (t) => {
|
|
802
796
|
const base = makeGitBase();
|
|
803
797
|
t.after(() => cleanup(base));
|
|
804
798
|
|
|
805
799
|
const { ctx, notifications } = makeMockCtx();
|
|
806
800
|
const result = reconcileMergeState(base, ctx);
|
|
807
801
|
|
|
808
|
-
assert.equal(result,
|
|
802
|
+
assert.equal(result, "clean", "should return clean when no merge state exists");
|
|
809
803
|
assert.equal(notifications.length, 0, "should not notify when no merge state present");
|
|
810
804
|
});
|
|
811
805
|
|
|
806
|
+
test("reconcileMergeState blocks and preserves unresolved code conflicts", (t) => {
|
|
807
|
+
const base = makeGitBase();
|
|
808
|
+
t.after(() => cleanup(base));
|
|
809
|
+
|
|
810
|
+
writeFileSync(join(base, "conflict.txt"), "base\n");
|
|
811
|
+
execFileSync("git", ["add", "conflict.txt"], { cwd: base, stdio: "ignore" });
|
|
812
|
+
execFileSync("git", ["commit", "-m", "add conflict base"], { cwd: base, stdio: "ignore" });
|
|
813
|
+
|
|
814
|
+
execFileSync("git", ["checkout", "-b", "feature"], { cwd: base, stdio: "ignore" });
|
|
815
|
+
writeFileSync(join(base, "conflict.txt"), "feature\n");
|
|
816
|
+
execFileSync("git", ["add", "conflict.txt"], { cwd: base, stdio: "ignore" });
|
|
817
|
+
execFileSync("git", ["commit", "-m", "feature change"], { cwd: base, stdio: "ignore" });
|
|
818
|
+
|
|
819
|
+
execFileSync("git", ["checkout", "main"], { cwd: base, stdio: "ignore" });
|
|
820
|
+
writeFileSync(join(base, "conflict.txt"), "main\n");
|
|
821
|
+
execFileSync("git", ["add", "conflict.txt"], { cwd: base, stdio: "ignore" });
|
|
822
|
+
execFileSync("git", ["commit", "-m", "main change"], { cwd: base, stdio: "ignore" });
|
|
823
|
+
|
|
824
|
+
let mergeFailed = false;
|
|
825
|
+
try {
|
|
826
|
+
execFileSync("git", ["merge", "--no-ff", "feature"], { cwd: base, stdio: "ignore" });
|
|
827
|
+
} catch {
|
|
828
|
+
mergeFailed = true;
|
|
829
|
+
}
|
|
830
|
+
assert.equal(mergeFailed, true, "merge should produce a conflict");
|
|
831
|
+
assert.ok(existsSync(join(base, ".git", "MERGE_HEAD")), "MERGE_HEAD should remain present before reconcile");
|
|
832
|
+
|
|
833
|
+
const beforeContents = readFileSync(join(base, "conflict.txt"), "utf8");
|
|
834
|
+
assert.match(beforeContents, /<<<<<<<|=======|>>>>>>>/, "fixture should contain conflict markers");
|
|
835
|
+
|
|
836
|
+
const { ctx, notifications } = makeMockCtx();
|
|
837
|
+
const result = reconcileMergeState(base, ctx);
|
|
838
|
+
|
|
839
|
+
assert.equal(result, "blocked", "code conflicts should block reconciliation");
|
|
840
|
+
assert.ok(existsSync(join(base, ".git", "MERGE_HEAD")), "MERGE_HEAD should be preserved for manual resolution");
|
|
841
|
+
assert.equal(
|
|
842
|
+
readFileSync(join(base, "conflict.txt"), "utf8"),
|
|
843
|
+
beforeContents,
|
|
844
|
+
"reconcile should preserve the conflicted file contents",
|
|
845
|
+
);
|
|
846
|
+
assert.ok(
|
|
847
|
+
notifications.some((n) => n.level === "error" && n.msg.includes("manual conflict resolution is preserved")),
|
|
848
|
+
"should notify that auto-mode paused and preserved manual work",
|
|
849
|
+
);
|
|
850
|
+
});
|
|
851
|
+
|
|
812
852
|
test("verifyExpectedArtifact complete-milestone passes with impl files (#1703)", (t) => {
|
|
813
853
|
const base = makeGitBase();
|
|
814
854
|
t.after(() => cleanup(base));
|
package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts
CHANGED
|
@@ -360,8 +360,8 @@ describe("session management", () => {
|
|
|
360
360
|
assert.equal(s.unitRecoveryCount.size, 0, "recovery counts cleared");
|
|
361
361
|
});
|
|
362
362
|
|
|
363
|
-
test("NEW_SESSION_TIMEOUT_MS is
|
|
364
|
-
assert.equal(NEW_SESSION_TIMEOUT_MS,
|
|
363
|
+
test("NEW_SESSION_TIMEOUT_MS is 120 seconds", () => {
|
|
364
|
+
assert.equal(NEW_SESSION_TIMEOUT_MS, 120_000, "session timeout should be 120s");
|
|
365
365
|
});
|
|
366
366
|
|
|
367
367
|
test("MAX_UNIT_DISPATCHES limits retries for a single unit", () => {
|
|
@@ -72,7 +72,7 @@ function makeMockDeps(
|
|
|
72
72
|
getCurrentBranch: () => "main",
|
|
73
73
|
autoWorktreeBranch: () => "auto/M001",
|
|
74
74
|
resolveMilestoneFile: () => null,
|
|
75
|
-
reconcileMergeState: () =>
|
|
75
|
+
reconcileMergeState: () => "clean",
|
|
76
76
|
getLedger: () => ({ units: [] }),
|
|
77
77
|
getProjectTotals: () => ({ cost: 0 }),
|
|
78
78
|
formatCost: (c: number) => `$${c.toFixed(2)}`,
|
|
@@ -590,9 +590,9 @@ test("unit-end event contains errorContext when unit is cancelled with structure
|
|
|
590
590
|
resolveAgentEndCancelled({ message: "Hard timeout error: exceeded limit", category: "timeout", isTransient: true });
|
|
591
591
|
|
|
592
592
|
const result = await unitPromise;
|
|
593
|
-
//
|
|
593
|
+
// Transient timeout cancellations pause (recoverable) instead of hard-stopping
|
|
594
594
|
assert.equal(result.action, "break");
|
|
595
|
-
assert.equal((result as any).reason, "session-
|
|
595
|
+
assert.equal((result as any).reason, "session-timeout");
|
|
596
596
|
|
|
597
597
|
// Verify error classification used structured errorContext on the window entry
|
|
598
598
|
const entry = loopState.recentUnits[loopState.recentUnits.length - 1];
|