gsd-pi 2.57.0 → 2.58.0-dev.778d6ac
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 +1 -1
- package/dist/cli.js +49 -35
- package/dist/headless-ui.d.ts +17 -0
- package/dist/headless-ui.js +97 -3
- package/dist/headless.js +67 -6
- package/dist/help-text.js +1 -0
- package/dist/onboarding.js +44 -0
- package/dist/resource-loader.js +16 -1
- package/dist/resources/agents/researcher.md +1 -1
- package/dist/resources/extensions/ask-user-questions.js +16 -3
- package/dist/resources/extensions/async-jobs/extension-manifest.json +1 -1
- package/dist/resources/extensions/bg-shell/extension-manifest.json +1 -1
- package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +14 -6
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +59 -36
- package/dist/resources/extensions/context7/extension-manifest.json +1 -1
- package/dist/resources/extensions/get-secrets-from-user.js +8 -5
- package/dist/resources/extensions/google-search/extension-manifest.json +1 -1
- package/dist/resources/extensions/google-search/index.js +2 -1
- package/dist/resources/extensions/gsd/auto/infra-errors.js +4 -0
- package/dist/resources/extensions/gsd/auto/phases.js +25 -21
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
- package/dist/resources/extensions/gsd/auto-dashboard.js +37 -20
- package/dist/resources/extensions/gsd/auto-dispatch.js +20 -5
- package/dist/resources/extensions/gsd/auto-model-selection.js +26 -3
- package/dist/resources/extensions/gsd/auto-post-unit.js +16 -4
- package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
- package/dist/resources/extensions/gsd/auto-recovery.js +13 -5
- package/dist/resources/extensions/gsd/auto-start.js +35 -22
- package/dist/resources/extensions/gsd/auto-worktree.js +203 -14
- package/dist/resources/extensions/gsd/auto.js +4 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +82 -9
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -18
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +44 -11
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -0
- package/dist/resources/extensions/gsd/captures.js +56 -4
- package/dist/resources/extensions/gsd/db-writer.js +116 -8
- package/dist/resources/extensions/gsd/dispatch-guard.js +11 -1
- package/dist/resources/extensions/gsd/doctor-git-checks.js +28 -0
- package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +5 -4
- package/dist/resources/extensions/gsd/doctor.js +3 -1
- package/dist/resources/extensions/gsd/error-classifier.js +13 -10
- package/dist/resources/extensions/gsd/extension-manifest.json +16 -1
- package/dist/resources/extensions/gsd/forensics.js +123 -20
- package/dist/resources/extensions/gsd/git-service.js +23 -1
- package/dist/resources/extensions/gsd/gitignore.js +33 -0
- package/dist/resources/extensions/gsd/gsd-db.js +44 -10
- package/dist/resources/extensions/gsd/guided-flow.js +106 -44
- package/dist/resources/extensions/gsd/health-widget-core.js +31 -0
- package/dist/resources/extensions/gsd/health-widget.js +17 -0
- package/dist/resources/extensions/gsd/index.js +1 -1
- package/dist/resources/extensions/gsd/memory-extractor.js +7 -0
- package/dist/resources/extensions/gsd/migrate-external.js +8 -1
- package/dist/resources/extensions/gsd/milestone-validation-gates.js +45 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +18 -0
- package/dist/resources/extensions/gsd/model-router.js +35 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +17 -0
- package/dist/resources/extensions/gsd/notifications.js +16 -1
- package/dist/resources/extensions/gsd/parallel-eligibility.js +13 -2
- package/dist/resources/extensions/gsd/parallel-merge.js +78 -5
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +23 -6
- package/dist/resources/extensions/gsd/parsers-legacy.js +20 -3
- package/dist/resources/extensions/gsd/paths.js +43 -0
- package/dist/resources/extensions/gsd/preferences-models.js +14 -1
- package/dist/resources/extensions/gsd/preferences-types.js +2 -1
- package/dist/resources/extensions/gsd/preferences.js +42 -31
- package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -2
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -1
- package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
- package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -0
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/dist/resources/extensions/gsd/repo-identity.js +205 -11
- package/dist/resources/extensions/gsd/rethink.js +5 -0
- package/dist/resources/extensions/gsd/roadmap-slices.js +5 -4
- package/dist/resources/extensions/gsd/state.js +85 -27
- package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +34 -71
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +12 -2
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +29 -1
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +18 -3
- package/dist/resources/extensions/gsd/triage-resolution.js +22 -7
- package/dist/resources/extensions/gsd/undo.js +2 -2
- package/dist/resources/extensions/gsd/unit-ownership.js +164 -33
- package/dist/resources/extensions/gsd/verdict-parser.js +20 -8
- package/dist/resources/extensions/gsd/workflow-manifest.js +24 -5
- package/dist/resources/extensions/gsd/workflow-projections.js +95 -63
- package/dist/resources/extensions/gsd/workflow-reconcile.js +35 -5
- package/dist/resources/extensions/gsd/workspace-index.js +24 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +105 -1
- package/dist/resources/extensions/gsd/worktree-resolver.js +20 -3
- package/dist/resources/extensions/mcp-client/index.js +11 -7
- package/dist/resources/extensions/ollama/index.js +112 -0
- package/dist/resources/extensions/ollama/model-capabilities.js +115 -0
- package/dist/resources/extensions/ollama/ollama-client.js +168 -0
- package/dist/resources/extensions/ollama/ollama-commands.js +194 -0
- package/dist/resources/extensions/ollama/ollama-discovery.js +69 -0
- package/dist/resources/extensions/ollama/ollama-tool.js +184 -0
- package/dist/resources/extensions/ollama/types.js +2 -0
- package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
- package/dist/resources/extensions/shared/interview-ui.js +11 -1
- package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -3
- package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
- package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
- package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
- package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
- package/dist/startup-model-validation.d.ts +39 -0
- package/dist/startup-model-validation.js +50 -0
- 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 +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- 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 +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- 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 +4 -4
- 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 +2 -2
- 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/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 +5 -5
- 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 +5 -5
- 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 +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- 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 +12 -12
- package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
- 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-react-loadable-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/6502.7593d7797a4b3999.js +9 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-4332cbd5dd1be584.js → webpack-a1c1e452c6b32d04.js} +1 -1
- package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +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/dist/web-mode.js +2 -1
- package/package.json +2 -2
- package/packages/daemon/src/cli.ts +49 -0
- package/packages/daemon/src/daemon.test.ts +104 -1
- package/packages/daemon/src/daemon.ts +24 -1
- package/packages/daemon/src/discord-bot.ts +73 -3
- package/packages/daemon/src/event-bridge.ts +15 -9
- package/packages/daemon/src/event-formatter.ts +30 -2
- package/packages/daemon/src/index.ts +9 -0
- package/packages/daemon/src/launchd.test.ts +356 -0
- package/packages/daemon/src/launchd.ts +242 -0
- package/packages/daemon/src/message-batcher.test.ts +2 -2
- package/packages/daemon/src/message-batcher.ts +9 -3
- package/packages/daemon/src/orchestrator.test.ts +1 -0
- package/packages/daemon/src/orchestrator.ts +106 -2
- package/packages/native/dist/ast/index.js +9 -5
- package/packages/native/dist/ast/types.js +2 -1
- package/packages/native/dist/clipboard/index.js +12 -7
- package/packages/native/dist/clipboard/types.js +2 -1
- package/packages/native/dist/diff/index.js +12 -7
- package/packages/native/dist/diff/types.js +2 -1
- package/packages/native/dist/fd/index.js +6 -3
- package/packages/native/dist/fd/types.js +2 -1
- package/packages/native/dist/glob/index.js +9 -5
- package/packages/native/dist/glob/types.js +2 -1
- package/packages/native/dist/grep/index.js +9 -5
- package/packages/native/dist/grep/types.js +2 -1
- package/packages/native/dist/gsd-parser/index.js +18 -11
- package/packages/native/dist/gsd-parser/types.js +2 -1
- package/packages/native/dist/highlight/index.js +12 -7
- package/packages/native/dist/highlight/types.js +2 -1
- package/packages/native/dist/html/index.js +6 -3
- package/packages/native/dist/html/types.js +2 -1
- package/packages/native/dist/image/index.js +10 -5
- package/packages/native/dist/image/types.js +7 -4
- package/packages/native/dist/index.js +70 -17
- package/packages/native/dist/json-parse/index.js +13 -8
- package/packages/native/dist/native.js +47 -10
- package/packages/native/dist/ps/index.js +15 -9
- package/packages/native/dist/ps/types.js +2 -1
- package/packages/native/dist/stream-process/index.js +12 -7
- package/packages/native/dist/text/index.js +24 -14
- package/packages/native/dist/text/types.js +5 -2
- package/packages/native/dist/truncate/index.js +12 -7
- package/packages/native/dist/ttsr/index.js +12 -7
- package/packages/native/dist/ttsr/types.js +2 -1
- package/packages/native/dist/xxhash/index.js +9 -5
- package/packages/native/package.json +19 -19
- package/packages/native/src/__tests__/module-compat.test.mjs +91 -0
- package/packages/native/src/native.ts +9 -8
- package/packages/pi-agent-core/dist/agent-loop.js +3 -2
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
- package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/proxy.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +45 -0
- package/packages/pi-agent-core/src/agent-loop.ts +3 -2
- package/packages/pi-agent-core/src/proxy.ts +1 -1
- package/packages/pi-ai/dist/env-api-keys.js +1 -0
- package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
- package/packages/pi-ai/dist/index.d.ts +1 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -2
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js +25 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -0
- package/packages/pi-ai/dist/types.d.ts +3 -3
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.d.ts +3 -0
- package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.js +24 -1
- package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +37 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.js +75 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +73 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -0
- package/packages/pi-ai/src/env-api-keys.ts +1 -0
- package/packages/pi-ai/src/index.ts +1 -0
- package/packages/pi-ai/src/providers/anthropic-shared.test.ts +29 -0
- package/packages/pi-ai/src/providers/anthropic-shared.ts +17 -2
- package/packages/pi-ai/src/types.ts +3 -2
- package/packages/pi-ai/src/utils/json-parse.ts +28 -1
- package/packages/pi-ai/src/utils/repair-tool-json.ts +88 -0
- package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +102 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -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 +31 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +17 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +62 -2
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +176 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/exec.js +3 -1
- package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +28 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +37 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +63 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +19 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +115 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +109 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts +44 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +97 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +181 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/index.js +1 -1
- package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.js +3 -0
- package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -0
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.js +31 -2
- package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.test.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/messages.test.js +86 -0
- package/packages/pi-coding-agent/dist/core/messages.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +10 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +12 -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 +6 -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 +48 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +193 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +10 -3
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js +13 -4
- package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +16 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +80 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts +2 -2
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +5 -0
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +38 -1
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +236 -0
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +94 -1
- package/packages/pi-coding-agent/src/core/exec.ts +3 -1
- package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +77 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +62 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +134 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +137 -0
- package/packages/pi-coding-agent/src/core/extensions/index.ts +4 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
- package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +228 -0
- package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +118 -0
- package/packages/pi-coding-agent/src/core/index.ts +6 -0
- package/packages/pi-coding-agent/src/core/lsp/index.ts +3 -0
- package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -0
- package/packages/pi-coding-agent/src/core/messages.test.ts +114 -0
- package/packages/pi-coding-agent/src/core/messages.ts +29 -2
- package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
- package/packages/pi-coding-agent/src/core/resource-loader.ts +20 -1
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +255 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +52 -1
- package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +11 -3
- package/packages/pi-coding-agent/src/core/tools/read.ts +14 -4
- package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +92 -0
- package/packages/pi-coding-agent/src/index.ts +6 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +7 -0
- package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +6 -0
- package/packages/pi-tui/dist/terminal.d.ts +2 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +9 -0
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +9 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/terminal.ts +14 -0
- package/packages/pi-tui/src/tui.ts +8 -0
- package/pkg/package.json +1 -1
- package/scripts/ensure-workspace-builds.cjs +45 -14
- package/src/resources/agents/researcher.md +1 -1
- package/src/resources/extensions/ask-user-questions.ts +21 -3
- package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
- package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
- package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +13 -6
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +63 -35
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +28 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -1
- package/src/resources/extensions/context7/extension-manifest.json +1 -1
- package/src/resources/extensions/get-secrets-from-user.ts +8 -5
- package/src/resources/extensions/google-search/extension-manifest.json +1 -1
- package/src/resources/extensions/google-search/index.ts +2 -1
- package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/phases.ts +43 -34
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
- package/src/resources/extensions/gsd/auto-dashboard.ts +37 -19
- package/src/resources/extensions/gsd/auto-dispatch.ts +21 -5
- package/src/resources/extensions/gsd/auto-model-selection.ts +26 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
- package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +12 -5
- package/src/resources/extensions/gsd/auto-start.ts +35 -26
- package/src/resources/extensions/gsd/auto-worktree.ts +197 -11
- package/src/resources/extensions/gsd/auto.ts +5 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +87 -9
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +31 -19
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -11
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +75 -0
- package/src/resources/extensions/gsd/captures.ts +63 -3
- package/src/resources/extensions/gsd/db-writer.ts +140 -7
- package/src/resources/extensions/gsd/dispatch-guard.ts +12 -1
- package/src/resources/extensions/gsd/doctor-git-checks.ts +26 -0
- package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +5 -4
- package/src/resources/extensions/gsd/doctor.ts +3 -1
- package/src/resources/extensions/gsd/error-classifier.ts +14 -11
- package/src/resources/extensions/gsd/extension-manifest.json +16 -1
- package/src/resources/extensions/gsd/forensics.ts +144 -20
- package/src/resources/extensions/gsd/git-service.ts +26 -3
- package/src/resources/extensions/gsd/gitignore.ts +33 -0
- package/src/resources/extensions/gsd/gsd-db.ts +49 -8
- package/src/resources/extensions/gsd/guided-flow.ts +114 -45
- package/src/resources/extensions/gsd/health-widget-core.ts +34 -0
- package/src/resources/extensions/gsd/health-widget.ts +17 -0
- package/src/resources/extensions/gsd/index.ts +1 -0
- package/src/resources/extensions/gsd/memory-extractor.ts +8 -0
- package/src/resources/extensions/gsd/migrate-external.ts +9 -1
- package/src/resources/extensions/gsd/milestone-validation-gates.ts +56 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +19 -0
- package/src/resources/extensions/gsd/model-router.ts +35 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +17 -0
- package/src/resources/extensions/gsd/notifications.ts +16 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +15 -2
- package/src/resources/extensions/gsd/parallel-merge.ts +87 -4
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +23 -6
- package/src/resources/extensions/gsd/parsers-legacy.ts +22 -3
- package/src/resources/extensions/gsd/paths.ts +42 -0
- package/src/resources/extensions/gsd/preferences-models.ts +14 -1
- package/src/resources/extensions/gsd/preferences-types.ts +2 -1
- package/src/resources/extensions/gsd/preferences.ts +45 -29
- package/src/resources/extensions/gsd/prompt-loader.ts +4 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -2
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -1
- package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
- package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -0
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/src/resources/extensions/gsd/repo-identity.ts +186 -11
- package/src/resources/extensions/gsd/rethink.ts +6 -0
- package/src/resources/extensions/gsd/roadmap-slices.ts +5 -4
- package/src/resources/extensions/gsd/state.ts +84 -32
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +71 -1
- package/src/resources/extensions/gsd/tests/captures.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +131 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +7 -12
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +78 -5
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +129 -0
- package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +125 -12
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +164 -0
- package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +135 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +111 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +243 -0
- package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +959 -0
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +85 -2
- package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/model-router.test.ts +68 -3
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/notifications.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +159 -0
- package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +9 -8
- package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/preferences.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +297 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +178 -0
- package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +162 -0
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +134 -0
- package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +233 -0
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +305 -0
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +405 -0
- package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +257 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +1628 -0
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +221 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +289 -0
- package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +100 -17
- package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +154 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +27 -2
- package/src/resources/extensions/gsd/tests/validation-gate-patterns.test.ts +44 -2
- package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +175 -0
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +95 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +36 -74
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +13 -1
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +36 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -2
- package/src/resources/extensions/gsd/triage-resolution.ts +23 -6
- package/src/resources/extensions/gsd/types.ts +4 -2
- package/src/resources/extensions/gsd/undo.ts +2 -2
- package/src/resources/extensions/gsd/unit-ownership.ts +206 -35
- package/src/resources/extensions/gsd/verdict-parser.ts +21 -6
- package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
- package/src/resources/extensions/gsd/workflow-manifest.ts +22 -5
- package/src/resources/extensions/gsd/workflow-projections.ts +97 -64
- package/src/resources/extensions/gsd/workflow-reconcile.ts +39 -10
- package/src/resources/extensions/gsd/workspace-index.ts +30 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +120 -1
- package/src/resources/extensions/gsd/worktree-resolver.ts +22 -3
- package/src/resources/extensions/mcp-client/index.ts +13 -7
- package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +55 -0
- package/src/resources/extensions/ollama/index.ts +130 -0
- package/src/resources/extensions/ollama/model-capabilities.ts +145 -0
- package/src/resources/extensions/ollama/ollama-client.ts +196 -0
- package/src/resources/extensions/ollama/ollama-commands.ts +248 -0
- package/src/resources/extensions/ollama/ollama-discovery.ts +106 -0
- package/src/resources/extensions/ollama/ollama-tool.ts +218 -0
- package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +162 -0
- package/src/resources/extensions/ollama/tests/ollama-client.test.ts +38 -0
- package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +28 -0
- package/src/resources/extensions/ollama/types.ts +130 -0
- package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
- package/src/resources/extensions/shared/interview-ui.ts +12 -1
- package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +156 -0
- package/src/resources/skills/create-gsd-extension/SKILL.md +5 -3
- package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
- package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
- package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
- package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
- package/dist/web/standalone/.next/static/chunks/6502.2305d0afd2385711.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +0 -1
- package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +0 -79
- /package/dist/web/standalone/.next/static/{yowc5qPtuKxjOr22KmOAy → R0D4xaIPl5kg93edN7Oo0}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{yowc5qPtuKxjOr22KmOAy → R0D4xaIPl5kg93edN7Oo0}/_ssgManifest.js +0 -0
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
realpathSync,
|
|
16
16
|
rmSync,
|
|
17
17
|
unlinkSync,
|
|
18
|
+
statSync,
|
|
18
19
|
lstatSync as lstatSyncFn,
|
|
19
20
|
} from "node:fs";
|
|
20
21
|
import { isAbsolute, join, sep as pathSep } from "node:path";
|
|
@@ -62,6 +63,7 @@ import {
|
|
|
62
63
|
nativeDiffNumstat,
|
|
63
64
|
nativeUpdateRef,
|
|
64
65
|
nativeIsAncestor,
|
|
66
|
+
nativeMergeAbort,
|
|
65
67
|
} from "./native-git-bridge.js";
|
|
66
68
|
|
|
67
69
|
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
@@ -84,6 +86,7 @@ const ROOT_STATE_FILES = [
|
|
|
84
86
|
"QUEUE.md",
|
|
85
87
|
"completed-units.json",
|
|
86
88
|
"metrics.json",
|
|
89
|
+
"mcp.json",
|
|
87
90
|
// NOTE: project preferences are intentionally NOT in ROOT_STATE_FILES.
|
|
88
91
|
// Forward-sync (main → worktree) is handled explicitly in syncGsdStateToWorktree().
|
|
89
92
|
// Back-sync (worktree → main) must NEVER overwrite the project root's copy
|
|
@@ -102,6 +105,67 @@ function isSamePath(a: string, b: string): boolean {
|
|
|
102
105
|
}
|
|
103
106
|
}
|
|
104
107
|
|
|
108
|
+
// ─── ASSESSMENT Force-Sync Helper (#2821) ─────────────────────────────────
|
|
109
|
+
|
|
110
|
+
/** Regex matching YAML frontmatter `verdict:` field. */
|
|
111
|
+
const VERDICT_RE = /verdict:\s*[\w-]+/i;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Walk a milestone directory and force-overwrite ASSESSMENT files in the
|
|
115
|
+
* destination when the source copy contains a `verdict:` field.
|
|
116
|
+
*
|
|
117
|
+
* This is the targeted fix for the UAT stuck-loop (#2821): the main
|
|
118
|
+
* safeCopyRecursive uses force:false to protect worktree-authoritative
|
|
119
|
+
* files (#1886), but ASSESSMENT files written by run-uat must be
|
|
120
|
+
* forward-synced when the project root has a verdict. Without this,
|
|
121
|
+
* the worktree retains a stale FAIL or missing ASSESSMENT and
|
|
122
|
+
* checkNeedsRunUat re-dispatches run-uat indefinitely.
|
|
123
|
+
*
|
|
124
|
+
* Only overwrites when the source has a verdict — never clobbers a
|
|
125
|
+
* worktree ASSESSMENT with a verdictless project-root copy.
|
|
126
|
+
*/
|
|
127
|
+
function forceOverwriteAssessmentsWithVerdict(
|
|
128
|
+
srcMilestoneDir: string,
|
|
129
|
+
dstMilestoneDir: string,
|
|
130
|
+
): void {
|
|
131
|
+
if (!existsSync(srcMilestoneDir)) return;
|
|
132
|
+
|
|
133
|
+
// Walk slices/<SID>/ looking for *-ASSESSMENT.md files
|
|
134
|
+
const slicesDir = join(srcMilestoneDir, "slices");
|
|
135
|
+
if (!existsSync(slicesDir)) return;
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
for (const sliceEntry of readdirSync(slicesDir, { withFileTypes: true })) {
|
|
139
|
+
if (!sliceEntry.isDirectory()) continue;
|
|
140
|
+
const srcSliceDir = join(slicesDir, sliceEntry.name);
|
|
141
|
+
const dstSliceDir = join(dstMilestoneDir, "slices", sliceEntry.name);
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
for (const fileEntry of readdirSync(srcSliceDir, { withFileTypes: true })) {
|
|
145
|
+
if (!fileEntry.isFile()) continue;
|
|
146
|
+
if (!fileEntry.name.endsWith("-ASSESSMENT.md")) continue;
|
|
147
|
+
|
|
148
|
+
const srcFile = join(srcSliceDir, fileEntry.name);
|
|
149
|
+
try {
|
|
150
|
+
const srcContent = readFileSync(srcFile, "utf-8");
|
|
151
|
+
if (!VERDICT_RE.test(srcContent)) continue; // no verdict in source — skip
|
|
152
|
+
|
|
153
|
+
// Source has a verdict — force-copy into worktree
|
|
154
|
+
mkdirSync(dstSliceDir, { recursive: true });
|
|
155
|
+
safeCopy(srcFile, join(dstSliceDir, fileEntry.name), { force: true });
|
|
156
|
+
} catch {
|
|
157
|
+
/* non-fatal per file */
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
} catch {
|
|
161
|
+
/* non-fatal per slice */
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
} catch {
|
|
165
|
+
/* non-fatal */
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
105
169
|
// ─── Module State ──────────────────────────────────────────────────────────
|
|
106
170
|
|
|
107
171
|
/** Original project root before chdir into auto-worktree. */
|
|
@@ -214,6 +278,19 @@ export function syncProjectRootToWorktree(
|
|
|
214
278
|
{ force: false },
|
|
215
279
|
);
|
|
216
280
|
|
|
281
|
+
// Force-sync ASSESSMENT files that have a verdict from project root (#2821).
|
|
282
|
+
// The additive-only copy above preserves worktree-authoritative files, but
|
|
283
|
+
// ASSESSMENT files are special: after run-uat writes a verdict and post-unit
|
|
284
|
+
// syncs it to the project root, the worktree may retain a stale copy (e.g.
|
|
285
|
+
// verdict:fail while the project root has verdict:pass from a retry). On
|
|
286
|
+
// session resume the DB is rebuilt from disk, and if the stale ASSESSMENT
|
|
287
|
+
// persists, checkNeedsRunUat finds no passing verdict → re-dispatches
|
|
288
|
+
// run-uat indefinitely (stuck-loop ×9).
|
|
289
|
+
forceOverwriteAssessmentsWithVerdict(
|
|
290
|
+
join(prGsd, "milestones", milestoneId),
|
|
291
|
+
join(wtGsd, "milestones", milestoneId),
|
|
292
|
+
);
|
|
293
|
+
|
|
217
294
|
// Forward-sync completed-units.json from project root to worktree.
|
|
218
295
|
// Project root is authoritative for completion state after crash recovery;
|
|
219
296
|
// without this, the worktree re-dispatches already-completed units (#1886).
|
|
@@ -223,12 +300,18 @@ export function syncProjectRootToWorktree(
|
|
|
223
300
|
{ force: true },
|
|
224
301
|
);
|
|
225
302
|
|
|
226
|
-
// Delete worktree gsd.db
|
|
227
|
-
//
|
|
303
|
+
// Delete worktree gsd.db ONLY if it is empty (0 bytes).
|
|
304
|
+
// An empty DB is stale/corrupt and should be rebuilt (#853).
|
|
305
|
+
// A non-empty DB was populated by gsd-migrate on respawn and must be
|
|
306
|
+
// preserved — deleting it truncates the file to 0 bytes when
|
|
307
|
+
// openDatabase re-creates it, causing "no such table" failures (#2815).
|
|
228
308
|
try {
|
|
229
309
|
const wtDb = join(wtGsd, "gsd.db");
|
|
230
310
|
if (existsSync(wtDb)) {
|
|
231
|
-
|
|
311
|
+
const size = statSync(wtDb).size;
|
|
312
|
+
if (size === 0) {
|
|
313
|
+
unlinkSync(wtDb);
|
|
314
|
+
}
|
|
232
315
|
}
|
|
233
316
|
} catch {
|
|
234
317
|
/* non-fatal */
|
|
@@ -1004,6 +1087,7 @@ function copyPlanningArtifacts(srcBase: string, wtPath: string): void {
|
|
|
1004
1087
|
"STATE.md",
|
|
1005
1088
|
"KNOWLEDGE.md",
|
|
1006
1089
|
"OVERRIDES.md",
|
|
1090
|
+
"mcp.json",
|
|
1007
1091
|
]) {
|
|
1008
1092
|
safeCopy(join(srcGsd, file), join(dstGsd, file), { force: true });
|
|
1009
1093
|
}
|
|
@@ -1264,12 +1348,17 @@ export function mergeMilestoneToMain(
|
|
|
1264
1348
|
// 1. Auto-commit dirty state in worktree before leaving
|
|
1265
1349
|
autoCommitDirtyState(worktreeCwd);
|
|
1266
1350
|
|
|
1267
|
-
// Reconcile worktree DB into main DB before leaving worktree context
|
|
1351
|
+
// Reconcile worktree DB into main DB before leaving worktree context.
|
|
1352
|
+
// Skip when both paths resolve to the same physical file (shared WAL /
|
|
1353
|
+
// symlink layout) — ATTACHing a WAL-mode file to itself corrupts the
|
|
1354
|
+
// database (#2823).
|
|
1268
1355
|
if (isDbAvailable()) {
|
|
1269
1356
|
try {
|
|
1270
1357
|
const worktreeDbPath = join(worktreeCwd, ".gsd", "gsd.db");
|
|
1271
1358
|
const mainDbPath = join(originalBasePath_, ".gsd", "gsd.db");
|
|
1272
|
-
|
|
1359
|
+
if (!isSamePath(worktreeDbPath, mainDbPath)) {
|
|
1360
|
+
reconcileWorktreeDb(mainDbPath, worktreeDbPath);
|
|
1361
|
+
}
|
|
1273
1362
|
} catch {
|
|
1274
1363
|
/* non-fatal */
|
|
1275
1364
|
}
|
|
@@ -1409,9 +1498,19 @@ export function mergeMilestoneToMain(
|
|
|
1409
1498
|
encoding: "utf-8",
|
|
1410
1499
|
}).trim();
|
|
1411
1500
|
if (status) {
|
|
1501
|
+
// Use --include-untracked to stash untracked files that would block
|
|
1502
|
+
// the squash merge, but EXCLUDE .gsd/milestones/ (#2505).
|
|
1503
|
+
// --include-untracked without exclusion sweeps queued milestone
|
|
1504
|
+
// CONTEXT files into the stash. If stash pop later fails, those files
|
|
1505
|
+
// are permanently trapped in the stash entry and lost on the next
|
|
1506
|
+
// stash push or drop.
|
|
1412
1507
|
execFileSync(
|
|
1413
1508
|
"git",
|
|
1414
|
-
[
|
|
1509
|
+
[
|
|
1510
|
+
"stash", "push", "--include-untracked",
|
|
1511
|
+
"-m", `gsd: pre-merge stash for ${milestoneId}`,
|
|
1512
|
+
"--", ":(exclude).gsd/milestones",
|
|
1513
|
+
],
|
|
1415
1514
|
{ cwd: originalBasePath_, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" },
|
|
1416
1515
|
);
|
|
1417
1516
|
stashed = true;
|
|
@@ -1421,6 +1520,62 @@ export function mergeMilestoneToMain(
|
|
|
1421
1520
|
// report the dirty tree if it fails.
|
|
1422
1521
|
}
|
|
1423
1522
|
|
|
1523
|
+
// 7a. Shelter queued milestone directories before the squash merge (#2505).
|
|
1524
|
+
// The milestone branch may contain copies of queued milestone dirs (via
|
|
1525
|
+
// copyPlanningArtifacts), so `git merge --squash` rejects when those same
|
|
1526
|
+
// files exist as untracked in the working tree. Temporarily move them to
|
|
1527
|
+
// a backup location, then restore after the merge+commit.
|
|
1528
|
+
const milestonesDir = join(gsdRoot(originalBasePath_), "milestones");
|
|
1529
|
+
const shelterDir = join(gsdRoot(originalBasePath_), ".milestone-shelter");
|
|
1530
|
+
const shelteredDirs: string[] = [];
|
|
1531
|
+
|
|
1532
|
+
// Helper: restore sheltered milestone directories (#2505).
|
|
1533
|
+
// Called on both success and error paths to ensure queued CONTEXT files
|
|
1534
|
+
// are never permanently lost.
|
|
1535
|
+
const restoreShelter = (): void => {
|
|
1536
|
+
if (shelteredDirs.length === 0) return;
|
|
1537
|
+
for (const dirName of shelteredDirs) {
|
|
1538
|
+
try {
|
|
1539
|
+
mkdirSync(milestonesDir, { recursive: true });
|
|
1540
|
+
cpSync(join(shelterDir, dirName), join(milestonesDir, dirName), { recursive: true, force: true });
|
|
1541
|
+
} catch { /* best-effort */ }
|
|
1542
|
+
}
|
|
1543
|
+
try { rmSync(shelterDir, { recursive: true, force: true }); } catch { /* best-effort */ }
|
|
1544
|
+
};
|
|
1545
|
+
|
|
1546
|
+
try {
|
|
1547
|
+
if (existsSync(milestonesDir)) {
|
|
1548
|
+
const entries = readdirSync(milestonesDir, { withFileTypes: true });
|
|
1549
|
+
for (const entry of entries) {
|
|
1550
|
+
if (!entry.isDirectory()) continue;
|
|
1551
|
+
// Only shelter directories that do NOT belong to the milestone being merged
|
|
1552
|
+
if (entry.name === milestoneId) continue;
|
|
1553
|
+
const srcDir = join(milestonesDir, entry.name);
|
|
1554
|
+
const dstDir = join(shelterDir, entry.name);
|
|
1555
|
+
try {
|
|
1556
|
+
mkdirSync(shelterDir, { recursive: true });
|
|
1557
|
+
cpSync(srcDir, dstDir, { recursive: true, force: true });
|
|
1558
|
+
rmSync(srcDir, { recursive: true, force: true });
|
|
1559
|
+
shelteredDirs.push(entry.name);
|
|
1560
|
+
} catch {
|
|
1561
|
+
// Non-fatal — if shelter fails, the merge may still succeed
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
} catch {
|
|
1566
|
+
// Non-fatal — proceed with merge; untracked files may block it
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
// 7c. Clean stale MERGE_HEAD before the squash merge (#2912).
|
|
1570
|
+
// The native (libgit2) merge path or a prior interrupted merge may leave
|
|
1571
|
+
// MERGE_HEAD in the git dir. `git merge --squash` refuses to run when
|
|
1572
|
+
// MERGE_HEAD exists, so remove it preemptively.
|
|
1573
|
+
try {
|
|
1574
|
+
const gitDirPre = resolveGitDir(originalBasePath_);
|
|
1575
|
+
const mergeHeadPre = join(gitDirPre, "MERGE_HEAD");
|
|
1576
|
+
if (existsSync(mergeHeadPre)) unlinkSync(mergeHeadPre);
|
|
1577
|
+
} catch { /* best-effort */ }
|
|
1578
|
+
|
|
1424
1579
|
// 8. Squash merge — auto-resolve .gsd/ state file conflicts (#530)
|
|
1425
1580
|
const mergeResult = nativeMergeSquash(originalBasePath_, milestoneBranch);
|
|
1426
1581
|
|
|
@@ -1429,6 +1584,16 @@ export function mergeMilestoneToMain(
|
|
|
1429
1584
|
// untracked .gsd/ files left by syncStateToProjectRoot). Preserve the
|
|
1430
1585
|
// milestone branch so commits are not lost.
|
|
1431
1586
|
if (mergeResult.conflicts.includes("__dirty_working_tree__")) {
|
|
1587
|
+
// Defensively clean merge state — the native path may leave MERGE_HEAD
|
|
1588
|
+
// even when the merge is rejected (#2912).
|
|
1589
|
+
try {
|
|
1590
|
+
const gitDir_ = resolveGitDir(originalBasePath_);
|
|
1591
|
+
for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
|
|
1592
|
+
const p = join(gitDir_, f);
|
|
1593
|
+
if (existsSync(p)) unlinkSync(p);
|
|
1594
|
+
}
|
|
1595
|
+
} catch { /* best-effort */ }
|
|
1596
|
+
|
|
1432
1597
|
// Pop stash before throwing so local work is not lost.
|
|
1433
1598
|
if (stashed) {
|
|
1434
1599
|
try {
|
|
@@ -1439,6 +1604,7 @@ export function mergeMilestoneToMain(
|
|
|
1439
1604
|
});
|
|
1440
1605
|
} catch { /* stash pop conflict is non-fatal */ }
|
|
1441
1606
|
}
|
|
1607
|
+
restoreShelter();
|
|
1442
1608
|
// Restore cwd so the caller is not stranded on the integration branch
|
|
1443
1609
|
process.chdir(previousCwd);
|
|
1444
1610
|
// Surface the actual dirty filenames from git stderr instead of
|
|
@@ -1485,6 +1651,18 @@ export function mergeMilestoneToMain(
|
|
|
1485
1651
|
|
|
1486
1652
|
// If there are still real code conflicts, escalate
|
|
1487
1653
|
if (codeConflicts.length > 0) {
|
|
1654
|
+
// Abort merge state so MERGE_HEAD is not left on disk (#2912).
|
|
1655
|
+
// libgit2's merge creates MERGE_HEAD even for squash merges; if left
|
|
1656
|
+
// dangling, subsequent merges fail and doctor reports corrupt state.
|
|
1657
|
+
try { nativeMergeAbort(originalBasePath_); } catch { /* best-effort */ }
|
|
1658
|
+
try {
|
|
1659
|
+
const gitDir_ = resolveGitDir(originalBasePath_);
|
|
1660
|
+
for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
|
|
1661
|
+
const p = join(gitDir_, f);
|
|
1662
|
+
if (existsSync(p)) unlinkSync(p);
|
|
1663
|
+
}
|
|
1664
|
+
} catch { /* best-effort */ }
|
|
1665
|
+
|
|
1488
1666
|
// Pop stash before throwing so local work is not lost (#2151).
|
|
1489
1667
|
if (stashed) {
|
|
1490
1668
|
try {
|
|
@@ -1495,6 +1673,7 @@ export function mergeMilestoneToMain(
|
|
|
1495
1673
|
});
|
|
1496
1674
|
} catch { /* stash pop conflict is non-fatal */ }
|
|
1497
1675
|
}
|
|
1676
|
+
restoreShelter();
|
|
1498
1677
|
throw new MergeConflictError(
|
|
1499
1678
|
codeConflicts,
|
|
1500
1679
|
"squash",
|
|
@@ -1510,14 +1689,18 @@ export function mergeMilestoneToMain(
|
|
|
1510
1689
|
const commitResult = nativeCommit(originalBasePath_, commitMessage);
|
|
1511
1690
|
const nothingToCommit = commitResult === null;
|
|
1512
1691
|
|
|
1513
|
-
// 9a. Clean up
|
|
1692
|
+
// 9a. Clean up merge state files left by git merge --squash (#1853, #2912).
|
|
1514
1693
|
// git only removes SQUASH_MSG when the commit reads it directly (plain
|
|
1515
1694
|
// `git commit`). nativeCommit uses `-F -` (stdin) or libgit2, neither
|
|
1516
|
-
// of which trigger git's SQUASH_MSG cleanup.
|
|
1517
|
-
//
|
|
1695
|
+
// of which trigger git's SQUASH_MSG cleanup. MERGE_HEAD is created by
|
|
1696
|
+
// libgit2's merge even in squash mode and is not removed by nativeCommit.
|
|
1697
|
+
// If left on disk, doctor reports `corrupt_merge_state` on every subsequent run.
|
|
1518
1698
|
try {
|
|
1519
|
-
const
|
|
1520
|
-
|
|
1699
|
+
const gitDir_ = resolveGitDir(originalBasePath_);
|
|
1700
|
+
for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
|
|
1701
|
+
const p = join(gitDir_, f);
|
|
1702
|
+
if (existsSync(p)) unlinkSync(p);
|
|
1703
|
+
}
|
|
1521
1704
|
} catch { /* best-effort */ }
|
|
1522
1705
|
|
|
1523
1706
|
// 9a-ii. Restore stashed files now that the merge+commit is complete (#2151).
|
|
@@ -1576,6 +1759,9 @@ export function mergeMilestoneToMain(
|
|
|
1576
1759
|
}
|
|
1577
1760
|
}
|
|
1578
1761
|
|
|
1762
|
+
// 9a-iii. Restore sheltered queued milestone directories (#2505).
|
|
1763
|
+
restoreShelter();
|
|
1764
|
+
|
|
1579
1765
|
// 9b. Safety check (#1792): if nothing was committed, verify the milestone
|
|
1580
1766
|
// work is already on the integration branch before allowing teardown.
|
|
1581
1767
|
// Compare only non-.gsd/ paths — .gsd/ state files diverge normally and
|
|
@@ -1061,6 +1061,11 @@ export async function startAuto(
|
|
|
1061
1061
|
verboseMode: boolean,
|
|
1062
1062
|
options?: { step?: boolean },
|
|
1063
1063
|
): Promise<void> {
|
|
1064
|
+
if (s.active) {
|
|
1065
|
+
debugLog("startAuto", { phase: "already-active", skipping: true });
|
|
1066
|
+
return;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1064
1069
|
const requestedStepMode = options?.step ?? false;
|
|
1065
1070
|
|
|
1066
1071
|
// Escape stale worktree cwd from a previous milestone (#608).
|
|
@@ -68,6 +68,28 @@ export async function handleAgentEnd(
|
|
|
68
68
|
|
|
69
69
|
const lastMsg = event.messages[event.messages.length - 1];
|
|
70
70
|
if (lastMsg && "stopReason" in lastMsg && lastMsg.stopReason === "aborted") {
|
|
71
|
+
// Empty content with aborted stopReason is a non-fatal agent stop (the LLM
|
|
72
|
+
// chose to end without producing output). Only pause on genuine fatal aborts
|
|
73
|
+
// that carry error context — e.g. errorMessage field or non-empty content
|
|
74
|
+
// indicating a mid-stream failure. (#2695)
|
|
75
|
+
const content = "content" in lastMsg ? lastMsg.content : undefined;
|
|
76
|
+
const hasEmptyContent = Array.isArray(content) && content.length === 0;
|
|
77
|
+
const hasErrorMessage = "errorMessage" in lastMsg && !!lastMsg.errorMessage;
|
|
78
|
+
|
|
79
|
+
if (hasEmptyContent && !hasErrorMessage) {
|
|
80
|
+
// Non-fatal: treat as a normal agent end so the loop can continue
|
|
81
|
+
// instead of entering a stuck re-dispatch cycle.
|
|
82
|
+
try {
|
|
83
|
+
resetRetryState(retryState);
|
|
84
|
+
resolveAgentEnd(event);
|
|
85
|
+
} catch (err) {
|
|
86
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
87
|
+
ctx.ui.notify(`Auto-mode error after empty-content abort: ${message}. Stopping auto-mode.`, "error");
|
|
88
|
+
try { await pauseAuto(ctx, pi); } catch { /* best-effort */ }
|
|
89
|
+
}
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
71
93
|
await pauseAuto(ctx, pi);
|
|
72
94
|
return;
|
|
73
95
|
}
|
|
@@ -79,6 +101,15 @@ export async function handleAgentEnd(
|
|
|
79
101
|
// ── 1. Classify ──────────────────────────────────────────────────────
|
|
80
102
|
const cls = classifyError(errorMsg, explicitRetryAfterMs);
|
|
81
103
|
|
|
104
|
+
// Cap rate-limit backoff for CLI-style providers (openai-codex, google-gemini-cli)
|
|
105
|
+
// which use per-user quotas with shorter windows (#2922).
|
|
106
|
+
if (cls.kind === "rate-limit") {
|
|
107
|
+
const currentProvider = ctx.model?.provider;
|
|
108
|
+
if (currentProvider === "openai-codex" || currentProvider === "google-gemini-cli") {
|
|
109
|
+
cls.retryAfterMs = Math.min(cls.retryAfterMs, 30_000);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
82
113
|
// ── 2. Decide & Act ──────────────────────────────────────────────────
|
|
83
114
|
|
|
84
115
|
// --- Network errors: same-model retry with backoff ---
|
|
@@ -121,14 +121,6 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
121
121
|
};
|
|
122
122
|
}
|
|
123
123
|
try {
|
|
124
|
-
const db = await import("../gsd-db.js");
|
|
125
|
-
const existing = db.getRequirementById(params.id);
|
|
126
|
-
if (!existing) {
|
|
127
|
-
return {
|
|
128
|
-
content: [{ type: "text" as const, text: `Error: Requirement ${params.id} not found.` }],
|
|
129
|
-
details: { operation: "update_requirement", id: params.id, error: "not_found" } as any,
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
124
|
const { updateRequirementInDb } = await import("../db-writer.js");
|
|
133
125
|
const updates: Record<string, string | undefined> = {};
|
|
134
126
|
if (params.status !== undefined) updates.status = params.status;
|
|
@@ -196,6 +188,91 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
196
188
|
pi.registerTool(requirementUpdateTool);
|
|
197
189
|
registerAlias(pi, requirementUpdateTool, "gsd_update_requirement", "gsd_requirement_update");
|
|
198
190
|
|
|
191
|
+
// ─── gsd_requirement_save ─────────────────────────────────────────────
|
|
192
|
+
|
|
193
|
+
const requirementSaveExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
194
|
+
const dbAvailable = await ensureDbOpen();
|
|
195
|
+
if (!dbAvailable) {
|
|
196
|
+
return {
|
|
197
|
+
content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot save requirement." }],
|
|
198
|
+
details: { operation: "save_requirement", error: "db_unavailable" } as any,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
try {
|
|
202
|
+
const { saveRequirementToDb } = await import("../db-writer.js");
|
|
203
|
+
const result = await saveRequirementToDb(
|
|
204
|
+
{
|
|
205
|
+
class: params.class,
|
|
206
|
+
status: params.status,
|
|
207
|
+
description: params.description,
|
|
208
|
+
why: params.why,
|
|
209
|
+
source: params.source,
|
|
210
|
+
primary_owner: params.primary_owner,
|
|
211
|
+
supporting_slices: params.supporting_slices,
|
|
212
|
+
validation: params.validation,
|
|
213
|
+
notes: params.notes,
|
|
214
|
+
},
|
|
215
|
+
process.cwd(),
|
|
216
|
+
);
|
|
217
|
+
return {
|
|
218
|
+
content: [{ type: "text" as const, text: `Saved requirement ${result.id}` }],
|
|
219
|
+
details: { operation: "save_requirement", id: result.id } as any,
|
|
220
|
+
};
|
|
221
|
+
} catch (err) {
|
|
222
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
223
|
+
logError("tool", `gsd_requirement_save tool failed: ${msg}`, { tool: "gsd_requirement_save", error: String(err) });
|
|
224
|
+
return {
|
|
225
|
+
content: [{ type: "text" as const, text: `Error saving requirement: ${msg}` }],
|
|
226
|
+
details: { operation: "save_requirement", error: msg } as any,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
const requirementSaveTool = {
|
|
232
|
+
name: "gsd_requirement_save",
|
|
233
|
+
label: "Save Requirement",
|
|
234
|
+
description:
|
|
235
|
+
"Record a new requirement to the GSD database and regenerate REQUIREMENTS.md. " +
|
|
236
|
+
"Requirement IDs are auto-assigned — never provide an ID manually.",
|
|
237
|
+
promptSnippet: "Record a new GSD requirement to the database (auto-assigns ID, regenerates REQUIREMENTS.md)",
|
|
238
|
+
promptGuidelines: [
|
|
239
|
+
"Use gsd_requirement_save when recording a new functional, non-functional, or operational requirement.",
|
|
240
|
+
"Requirement IDs are auto-assigned (R001, R002, ...) — never guess or provide an ID.",
|
|
241
|
+
"class, description, why, and source are required. All other fields are optional.",
|
|
242
|
+
"The tool writes to the DB and regenerates .gsd/REQUIREMENTS.md automatically.",
|
|
243
|
+
],
|
|
244
|
+
parameters: Type.Object({
|
|
245
|
+
class: Type.String({ description: "Requirement class (e.g. 'functional', 'non-functional', 'operational')" }),
|
|
246
|
+
description: Type.String({ description: "Short description of the requirement" }),
|
|
247
|
+
why: Type.String({ description: "Why this requirement matters" }),
|
|
248
|
+
source: Type.String({ description: "Origin of the requirement (e.g. 'user-research', 'design', 'M001')" }),
|
|
249
|
+
status: Type.Optional(Type.String({ description: "Status (default: 'active')" })),
|
|
250
|
+
primary_owner: Type.Optional(Type.String({ description: "Primary owning slice" })),
|
|
251
|
+
supporting_slices: Type.Optional(Type.String({ description: "Supporting slices" })),
|
|
252
|
+
validation: Type.Optional(Type.String({ description: "Validation criteria" })),
|
|
253
|
+
notes: Type.Optional(Type.String({ description: "Additional notes" })),
|
|
254
|
+
}),
|
|
255
|
+
execute: requirementSaveExecute,
|
|
256
|
+
renderCall(args: any, theme: any) {
|
|
257
|
+
let text = theme.fg("toolTitle", theme.bold("requirement_save "));
|
|
258
|
+
if (args.class) text += theme.fg("accent", `[${args.class}] `);
|
|
259
|
+
if (args.description) text += theme.fg("muted", args.description);
|
|
260
|
+
return new Text(text, 0, 0);
|
|
261
|
+
},
|
|
262
|
+
renderResult(result: any, _options: any, theme: any) {
|
|
263
|
+
const d = result.details;
|
|
264
|
+
if (result.isError || d?.error) {
|
|
265
|
+
return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
|
|
266
|
+
}
|
|
267
|
+
let text = theme.fg("success", `Requirement ${d?.id ?? ""} saved`);
|
|
268
|
+
text += theme.fg("dim", ` → REQUIREMENTS.md`);
|
|
269
|
+
return new Text(text, 0, 0);
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
pi.registerTool(requirementSaveTool);
|
|
274
|
+
registerAlias(pi, requirementSaveTool, "gsd_save_requirement", "gsd_requirement_save");
|
|
275
|
+
|
|
199
276
|
// ─── gsd_summary_save (formerly gsd_save_summary) ──────────────────────
|
|
200
277
|
|
|
201
278
|
const summarySaveExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
@@ -924,7 +1001,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
924
1001
|
promptSnippet: "Validate a GSD milestone (DB write + VALIDATION.md render)",
|
|
925
1002
|
promptGuidelines: [
|
|
926
1003
|
"Use gsd_validate_milestone when all slices are done and the milestone needs validation before completion.",
|
|
927
|
-
"Parameters: milestoneId, verdict, remediationRound, successCriteriaChecklist, sliceDeliveryAudit, crossSliceIntegration, requirementCoverage, verdictRationale, remediationPlan (optional).",
|
|
1004
|
+
"Parameters: milestoneId, verdict, remediationRound, successCriteriaChecklist, sliceDeliveryAudit, crossSliceIntegration, requirementCoverage, verificationClasses (optional), verdictRationale, remediationPlan (optional).",
|
|
928
1005
|
"If verdict is 'needs-remediation', also provide remediationPlan and use gsd_reassess_roadmap to add remediation slices to the roadmap.",
|
|
929
1006
|
"On success, returns validationPath where VALIDATION.md was written.",
|
|
930
1007
|
],
|
|
@@ -936,6 +1013,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
936
1013
|
sliceDeliveryAudit: Type.String({ description: "Markdown table auditing each slice's claimed vs delivered output" }),
|
|
937
1014
|
crossSliceIntegration: Type.String({ description: "Markdown describing any cross-slice boundary mismatches" }),
|
|
938
1015
|
requirementCoverage: Type.String({ description: "Markdown describing any unaddressed requirements" }),
|
|
1016
|
+
verificationClasses: Type.Optional(Type.String({ description: "Markdown describing verification class compliance and gaps" })),
|
|
939
1017
|
verdictRationale: Type.String({ description: "Why this verdict was chosen" }),
|
|
940
1018
|
remediationPlan: Type.Optional(Type.String({ description: "Remediation plan (required if verdict is needs-remediation)" })),
|
|
941
1019
|
}),
|
|
@@ -32,6 +32,31 @@ export function resolveProjectRootDbPath(basePath: string): string {
|
|
|
32
32
|
return join(projectRoot, ".gsd", "gsd.db");
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
// Symlink-resolved layout: /.gsd/projects/<hash>/worktrees/M001/...
|
|
36
|
+
// The project root is everything before /.gsd/projects/ (#2517)
|
|
37
|
+
const symlinkMarker = `${sep}.gsd${sep}projects${sep}`;
|
|
38
|
+
const symlinkIdx = basePath.indexOf(symlinkMarker);
|
|
39
|
+
if (symlinkIdx !== -1) {
|
|
40
|
+
const afterProjects = basePath.slice(symlinkIdx + symlinkMarker.length);
|
|
41
|
+
// Expect: <hash>/worktrees/...
|
|
42
|
+
const worktreeSeg = `${sep}worktrees${sep}`;
|
|
43
|
+
if (afterProjects.includes(worktreeSeg)) {
|
|
44
|
+
const projectRoot = basePath.slice(0, symlinkIdx);
|
|
45
|
+
return join(projectRoot, ".gsd", "gsd.db");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Forward-slash variant for symlink-resolved layout
|
|
50
|
+
const fwdSymlinkMarker = "/.gsd/projects/";
|
|
51
|
+
const fwdSymlinkIdx = basePath.indexOf(fwdSymlinkMarker);
|
|
52
|
+
if (fwdSymlinkIdx !== -1) {
|
|
53
|
+
const afterProjects = basePath.slice(fwdSymlinkIdx + fwdSymlinkMarker.length);
|
|
54
|
+
if (afterProjects.includes("/worktrees/")) {
|
|
55
|
+
const projectRoot = basePath.slice(0, fwdSymlinkIdx);
|
|
56
|
+
return join(projectRoot, ".gsd", "gsd.db");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
35
60
|
return join(basePath, ".gsd", "gsd.db");
|
|
36
61
|
}
|
|
37
62
|
|
|
@@ -81,8 +106,20 @@ export async function ensureDbOpen(): Promise<boolean> {
|
|
|
81
106
|
return opened;
|
|
82
107
|
}
|
|
83
108
|
|
|
109
|
+
process.stderr.write(
|
|
110
|
+
`gsd-db: ensureDbOpen failed — no .gsd directory found (resolvedPath=${resolveProjectRootDbPath(basePath)}, cwd=${basePath})\n`,
|
|
111
|
+
);
|
|
84
112
|
return false;
|
|
85
|
-
} catch {
|
|
113
|
+
} catch (err) {
|
|
114
|
+
const basePath = process.cwd();
|
|
115
|
+
const diagnostic = {
|
|
116
|
+
resolvedPath: resolveProjectRootDbPath(basePath),
|
|
117
|
+
cwd: basePath,
|
|
118
|
+
error: (err as Error).message ?? String(err),
|
|
119
|
+
};
|
|
120
|
+
process.stderr.write(
|
|
121
|
+
`gsd-db: ensureDbOpen failed — ${JSON.stringify(diagnostic)}\n`,
|
|
122
|
+
);
|
|
86
123
|
return false;
|
|
87
124
|
}
|
|
88
125
|
}
|
|
@@ -6,8 +6,9 @@ import { isToolCallEventType } from "@gsd/pi-coding-agent";
|
|
|
6
6
|
import { buildMilestoneFileName, resolveMilestonePath, resolveSliceFile, resolveSlicePath } from "../paths.js";
|
|
7
7
|
import { buildBeforeAgentStartResult } from "./system-context.js";
|
|
8
8
|
import { handleAgentEnd } from "./agent-end-recovery.js";
|
|
9
|
-
import { clearDiscussionFlowState, isDepthVerified, isQueuePhaseActive, markDepthVerified, resetWriteGateState, shouldBlockContextWrite } from "./write-gate.js";
|
|
9
|
+
import { clearDiscussionFlowState, isDepthVerified, isQueuePhaseActive, markDepthVerified, resetWriteGateState, shouldBlockContextWrite, shouldBlockQueueExecution } from "./write-gate.js";
|
|
10
10
|
import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
|
|
11
|
+
import { cleanupQuickBranch } from "../quick.js";
|
|
11
12
|
import { getDiscussionMilestoneId } from "../guided-flow.js";
|
|
12
13
|
import { loadToolApiKeys } from "../commands-config.js";
|
|
13
14
|
import { loadFile, saveFile, formatContinue } from "../files.js";
|
|
@@ -16,8 +17,6 @@ import { getAutoDashboardData, isAutoActive, isAutoPaused, markToolEnd, markTool
|
|
|
16
17
|
import { isParallelActive, shutdownParallel } from "../parallel-orchestrator.js";
|
|
17
18
|
import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
|
|
18
19
|
import { saveActivityLog } from "../activity-log.js";
|
|
19
|
-
import { startRtkStatusUpdates, stopRtkStatusUpdates } from "../rtk-status.js";
|
|
20
|
-
import { rewriteCommandWithRtk } from "../../shared/rtk.js";
|
|
21
20
|
|
|
22
21
|
// Skip the welcome screen on the very first session_start — cli.ts already
|
|
23
22
|
// printed it before the TUI launched. Only re-print on /clear (subsequent sessions).
|
|
@@ -29,19 +28,10 @@ async function syncServiceTierStatus(ctx: ExtensionContext): Promise<void> {
|
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
export function registerHooks(pi: ExtensionAPI): void {
|
|
32
|
-
// Route all agent bash tool commands through RTK rewrite when opted in.
|
|
33
|
-
// This is a no-op when RTK is disabled or not installed.
|
|
34
|
-
pi.on("bash_transform", async (event) => {
|
|
35
|
-
const rewritten = rewriteCommandWithRtk(event.command);
|
|
36
|
-
if (rewritten === event.command) return undefined;
|
|
37
|
-
return { command: rewritten };
|
|
38
|
-
});
|
|
39
|
-
|
|
40
31
|
pi.on("session_start", async (_event, ctx) => {
|
|
41
32
|
resetWriteGateState();
|
|
42
33
|
resetToolCallLoopGuard();
|
|
43
34
|
await syncServiceTierStatus(ctx);
|
|
44
|
-
startRtkStatusUpdates(ctx);
|
|
45
35
|
|
|
46
36
|
// Apply show_token_cost preference (#1515)
|
|
47
37
|
try {
|
|
@@ -86,11 +76,6 @@ export function registerHooks(pi: ExtensionAPI): void {
|
|
|
86
76
|
clearDiscussionFlowState();
|
|
87
77
|
await syncServiceTierStatus(ctx);
|
|
88
78
|
loadToolApiKeys();
|
|
89
|
-
startRtkStatusUpdates(ctx);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
pi.on("session_fork", async (_event, ctx) => {
|
|
93
|
-
startRtkStatusUpdates(ctx);
|
|
94
79
|
});
|
|
95
80
|
|
|
96
81
|
pi.on("before_agent_start", async (event, ctx: ExtensionContext) => {
|
|
@@ -102,6 +87,17 @@ export function registerHooks(pi: ExtensionAPI): void {
|
|
|
102
87
|
await handleAgentEnd(pi, event, ctx);
|
|
103
88
|
});
|
|
104
89
|
|
|
90
|
+
// Squash-merge quick-task branch back to the original branch after the
|
|
91
|
+
// agent turn completes (#2668). cleanupQuickBranch is a no-op when no
|
|
92
|
+
// quick-return state is pending, so this is safe to call on every turn.
|
|
93
|
+
pi.on("turn_end", async () => {
|
|
94
|
+
try {
|
|
95
|
+
cleanupQuickBranch();
|
|
96
|
+
} catch {
|
|
97
|
+
// Best-effort: don't break the turn lifecycle if cleanup fails.
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
105
101
|
pi.on("session_before_compact", async () => {
|
|
106
102
|
if (isAutoActive() || isAutoPaused()) {
|
|
107
103
|
return { cancel: true };
|
|
@@ -139,7 +135,6 @@ export function registerHooks(pi: ExtensionAPI): void {
|
|
|
139
135
|
});
|
|
140
136
|
|
|
141
137
|
pi.on("session_shutdown", async (_event, ctx: ExtensionContext) => {
|
|
142
|
-
stopRtkStatusUpdates(ctx);
|
|
143
138
|
if (isParallelActive()) {
|
|
144
139
|
try {
|
|
145
140
|
await shutdownParallel(process.cwd());
|
|
@@ -161,6 +156,23 @@ export function registerHooks(pi: ExtensionAPI): void {
|
|
|
161
156
|
return { block: true, reason: loopCheck.reason };
|
|
162
157
|
}
|
|
163
158
|
|
|
159
|
+
// ── Queue-mode execution guard (#2545): block source-code mutations ──
|
|
160
|
+
// When /gsd queue is active, the agent should only create milestones,
|
|
161
|
+
// not execute work. Block write/edit to non-.gsd/ paths and bash commands
|
|
162
|
+
// that would modify files.
|
|
163
|
+
if (isQueuePhaseActive()) {
|
|
164
|
+
let queueInput = "";
|
|
165
|
+
if (isToolCallEventType("write", event)) {
|
|
166
|
+
queueInput = event.input.path;
|
|
167
|
+
} else if (isToolCallEventType("edit", event)) {
|
|
168
|
+
queueInput = event.input.path;
|
|
169
|
+
} else if (isToolCallEventType("bash", event)) {
|
|
170
|
+
queueInput = event.input.command;
|
|
171
|
+
}
|
|
172
|
+
const queueGuard = shouldBlockQueueExecution(event.toolName, queueInput, true);
|
|
173
|
+
if (queueGuard.block) return queueGuard;
|
|
174
|
+
}
|
|
175
|
+
|
|
164
176
|
// ── Single-writer engine: block direct writes to STATE.md ──────────
|
|
165
177
|
// Covers write, edit, and bash tools to prevent bypass vectors.
|
|
166
178
|
if (isToolCallEventType("write", event)) {
|
|
@@ -245,7 +257,7 @@ export function registerHooks(pi: ExtensionAPI): void {
|
|
|
245
257
|
|
|
246
258
|
pi.on("tool_execution_start", async (event) => {
|
|
247
259
|
if (!isAutoActive()) return;
|
|
248
|
-
markToolStart(event.toolCallId
|
|
260
|
+
markToolStart(event.toolCallId);
|
|
249
261
|
});
|
|
250
262
|
|
|
251
263
|
pi.on("tool_execution_end", async (event) => {
|