gsd-pi 2.57.0 → 2.58.0-dev.394cb18
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 +58 -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 +206 -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 +42 -34
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +66 -12
- 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/codebase-generator.js +279 -0
- package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
- package/dist/resources/extensions/gsd/commands-codebase.js +115 -0
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +41 -4
- package/dist/resources/extensions/gsd/complexity-classifier.js +8 -6
- 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 +76 -1
- package/dist/resources/extensions/gsd/doctor-proactive.js +34 -1
- 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 +12 -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 +105 -2
- 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 +39 -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 +45 -0
- package/dist/resources/extensions/gsd/preferences-models.js +14 -1
- package/dist/resources/extensions/gsd/preferences-types.js +3 -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/watch/header-renderer.js +241 -0
- 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 +9 -9
- 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 +9 -9
- 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/dist/welcome-screen.d.ts +1 -0
- package/dist/welcome-screen.js +32 -6
- 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/components/armin.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js +9 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +0 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js +5 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js +4 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +8 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +26 -12
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js +4 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts +3 -0
- 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 +46 -14
- 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 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +4 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +8 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.js +3 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.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 +19 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +16 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +27 -4
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +6 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.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/components/armin.ts +9 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +0 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +3 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/bordered-loader.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/branch-summary-message.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/compaction-summary-message.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/config-selector.ts +7 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/countdown-timer.ts +3 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/custom-message.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/daxnuts.ts +4 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +2 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +3 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/extension-input.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/extension-selector.ts +4 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +27 -13
- package/packages/pi-coding-agent/src/modes/interactive/components/oauth-selector.ts +4 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +45 -14
- package/packages/pi-coding-agent/src/modes/interactive/components/scoped-models-selector.ts +2 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +4 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +2 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +8 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message-selector.ts +3 -2
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +24 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +14 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +35 -3
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +7 -0
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +1 -1
- 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/dist/modes/interactive/theme/themes.js +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- 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 +200 -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 +41 -35
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +72 -12
- 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/codebase-generator.ts +351 -0
- package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
- package/src/resources/extensions/gsd/commands-codebase.ts +164 -0
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +46 -4
- package/src/resources/extensions/gsd/complexity-classifier.ts +8 -6
- 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 +75 -1
- package/src/resources/extensions/gsd/doctor-proactive.ts +35 -1
- 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-types.ts +2 -0
- package/src/resources/extensions/gsd/doctor.ts +3 -1
- package/src/resources/extensions/gsd/error-classifier.ts +13 -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 +119 -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 +41 -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 +44 -0
- package/src/resources/extensions/gsd/preferences-models.ts +14 -1
- package/src/resources/extensions/gsd/preferences-types.ts +10 -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/codebase-generator.test.ts +488 -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/complexity-classifier.test.ts +4 -4
- 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 +134 -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/doctor-git.test.ts +72 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +68 -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/terminated-transient.test.ts +44 -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/watch/header-renderer.ts +275 -0
- 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 → uDm3eO1oo9lDfY2TyoO9t}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{yowc5qPtuKxjOr22KmOAy → uDm3eO1oo9lDfY2TyoO9t}/_ssgManifest.js +0 -0
|
@@ -680,6 +680,16 @@ export function nativeAddAll(basePath: string): void {
|
|
|
680
680
|
gitFileExec(basePath, ["add", "-A"]);
|
|
681
681
|
}
|
|
682
682
|
|
|
683
|
+
/**
|
|
684
|
+
* Stage only already-tracked files (git add -u).
|
|
685
|
+
* Does NOT add new untracked files — only updates modifications and deletions
|
|
686
|
+
* for files git already knows about. Safe for automated snapshots where
|
|
687
|
+
* pulling in unknown untracked files (secrets, binaries) would be dangerous.
|
|
688
|
+
*/
|
|
689
|
+
export function nativeAddTracked(basePath: string): void {
|
|
690
|
+
gitFileExec(basePath, ["add", "-u"]);
|
|
691
|
+
}
|
|
692
|
+
|
|
683
693
|
/**
|
|
684
694
|
* Stage all files with pathspec exclusions (git add -A -- ':!pattern' ...).
|
|
685
695
|
* Excluded paths are never hashed by git, preventing hangs on large
|
|
@@ -931,6 +941,37 @@ export function nativeResetHard(basePath: string): void {
|
|
|
931
941
|
execSync("git reset --hard HEAD", { cwd: basePath, stdio: "pipe" });
|
|
932
942
|
}
|
|
933
943
|
|
|
944
|
+
/**
|
|
945
|
+
* Soft reset to a target ref (git reset --soft <ref>).
|
|
946
|
+
* Moves HEAD to `target` while keeping all changes staged in the index.
|
|
947
|
+
* Used to squash snapshot commits back into a single real commit.
|
|
948
|
+
*/
|
|
949
|
+
export function nativeResetSoft(basePath: string, target: string): void {
|
|
950
|
+
execFileSync("git", ["reset", "--soft", target], {
|
|
951
|
+
cwd: basePath,
|
|
952
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
953
|
+
encoding: "utf-8",
|
|
954
|
+
env: GIT_NO_PROMPT_ENV,
|
|
955
|
+
});
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
/**
|
|
959
|
+
* Get the subject line of a commit (git log -1 --format=%s <ref>).
|
|
960
|
+
* Returns empty string if the ref doesn't exist.
|
|
961
|
+
*/
|
|
962
|
+
export function nativeCommitSubject(basePath: string, ref: string): string {
|
|
963
|
+
try {
|
|
964
|
+
return execFileSync("git", ["log", "-1", "--format=%s", ref], {
|
|
965
|
+
cwd: basePath,
|
|
966
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
967
|
+
encoding: "utf-8",
|
|
968
|
+
env: GIT_NO_PROMPT_ENV,
|
|
969
|
+
}).trim();
|
|
970
|
+
} catch {
|
|
971
|
+
return "";
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
|
|
934
975
|
/**
|
|
935
976
|
* Delete a branch.
|
|
936
977
|
* Native: libgit2 branch delete.
|
|
@@ -23,7 +23,13 @@ export function sendDesktopNotification(
|
|
|
23
23
|
message: string,
|
|
24
24
|
level: NotifyLevel = "info",
|
|
25
25
|
kind: NotificationKind = "complete",
|
|
26
|
+
projectName?: string,
|
|
26
27
|
): void {
|
|
28
|
+
// When a projectName is provided and the title is the default "GSD",
|
|
29
|
+
// replace it with a project-qualified title for multi-project clarity.
|
|
30
|
+
if (projectName && title === "GSD") {
|
|
31
|
+
title = formatNotificationTitle(projectName);
|
|
32
|
+
}
|
|
27
33
|
const loaded = loadEffectiveGSDPreferences()?.preferences;
|
|
28
34
|
if (!shouldSendDesktopNotification(kind, loaded?.notifications)) return;
|
|
29
35
|
|
|
@@ -64,6 +70,16 @@ export function shouldSendDesktopNotification(
|
|
|
64
70
|
}
|
|
65
71
|
}
|
|
66
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Format a notification title that includes the project name for context.
|
|
75
|
+
* Returns "GSD — projectName" when a project name is available, otherwise "GSD".
|
|
76
|
+
*/
|
|
77
|
+
export function formatNotificationTitle(projectName?: string): string {
|
|
78
|
+
const trimmed = projectName?.trim();
|
|
79
|
+
if (trimmed) return `GSD — ${trimmed}`;
|
|
80
|
+
return "GSD";
|
|
81
|
+
}
|
|
82
|
+
|
|
67
83
|
export function buildDesktopNotificationCommand(
|
|
68
84
|
platform: NodeJS.Platform,
|
|
69
85
|
title: string,
|
|
@@ -112,7 +112,20 @@ export async function analyzeParallelEligibility(
|
|
|
112
112
|
for (const mid of milestoneIds) {
|
|
113
113
|
const entry = registryMap.get(mid);
|
|
114
114
|
const title = entry?.title ?? mid;
|
|
115
|
-
|
|
115
|
+
|
|
116
|
+
// Rule 0: milestones with no registry entry (ghost directories, unknown
|
|
117
|
+
// state) are ineligible — we cannot determine their status or deps (#2501)
|
|
118
|
+
if (!entry) {
|
|
119
|
+
ineligible.push({
|
|
120
|
+
milestoneId: mid,
|
|
121
|
+
title,
|
|
122
|
+
eligible: false,
|
|
123
|
+
reason: "Milestone has no planning data — cannot determine eligibility.",
|
|
124
|
+
});
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const status = entry.status;
|
|
116
129
|
|
|
117
130
|
// Rule 1: skip complete and parked milestones
|
|
118
131
|
if (status === "complete" || status === "parked") {
|
|
@@ -126,7 +139,7 @@ export async function analyzeParallelEligibility(
|
|
|
126
139
|
}
|
|
127
140
|
|
|
128
141
|
// Rule 2: check dependency satisfaction
|
|
129
|
-
const deps = entry
|
|
142
|
+
const deps = entry.dependsOn ?? [];
|
|
130
143
|
const unsatisfied = deps.filter(dep => {
|
|
131
144
|
const depEntry = registryMap.get(dep);
|
|
132
145
|
return !depEntry || depEntry.status !== "complete";
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
* with safety checks for parallel execution context.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { spawnSync } from "node:child_process";
|
|
8
11
|
import { loadFile } from "./files.js";
|
|
9
12
|
import { resolveMilestoneFile } from "./paths.js";
|
|
10
13
|
import { mergeMilestoneToMain } from "./auto-worktree.js";
|
|
@@ -28,22 +31,102 @@ export type MergeOrder = "sequential" | "by-completion";
|
|
|
28
31
|
|
|
29
32
|
// ─── Merge Queue ───────────────────────────────────────────────────────────
|
|
30
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Check whether a milestone is complete by querying its worktree SQLite DB.
|
|
36
|
+
* Uses a subprocess to avoid disrupting the global DB singleton.
|
|
37
|
+
* Returns true when milestones.status = 'complete' in the worktree's gsd.db.
|
|
38
|
+
*/
|
|
39
|
+
export function isMilestoneCompleteInWorktreeDb(basePath: string, mid: string): boolean {
|
|
40
|
+
const dbPath = join(basePath, ".gsd", "worktrees", mid, ".gsd", "gsd.db");
|
|
41
|
+
if (!existsSync(dbPath)) return false;
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const result = spawnSync(
|
|
45
|
+
"sqlite3",
|
|
46
|
+
[dbPath, `SELECT status FROM milestones WHERE id='${mid}' LIMIT 1`],
|
|
47
|
+
{ timeout: 3000, encoding: "utf-8" },
|
|
48
|
+
);
|
|
49
|
+
return (result.stdout || "").trim() === "complete";
|
|
50
|
+
} catch {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Discover milestone IDs with status='complete' in their worktree DB,
|
|
57
|
+
* scanning .gsd/worktrees/<MID>/.gsd/gsd.db for each worktree directory.
|
|
58
|
+
*/
|
|
59
|
+
function discoverDbCompletedMilestones(basePath: string): Set<string> {
|
|
60
|
+
const completed = new Set<string>();
|
|
61
|
+
const worktreeDir = join(basePath, ".gsd", "worktrees");
|
|
62
|
+
try {
|
|
63
|
+
for (const entry of readdirSync(worktreeDir)) {
|
|
64
|
+
if (entry.startsWith("M") && isMilestoneCompleteInWorktreeDb(basePath, entry)) {
|
|
65
|
+
completed.add(entry);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
} catch {
|
|
69
|
+
// worktrees dir may not exist
|
|
70
|
+
}
|
|
71
|
+
return completed;
|
|
72
|
+
}
|
|
73
|
+
|
|
31
74
|
/**
|
|
32
75
|
* Determine safe merge order for completed milestones.
|
|
33
76
|
* Sequential: merge in milestone ID order (M001 before M002).
|
|
34
77
|
* By-completion: merge in the order milestones finished.
|
|
78
|
+
*
|
|
79
|
+
* When basePath is provided, also checks worktree SQLite DBs as the
|
|
80
|
+
* source of truth — workers with stale orchestrator state (e.g. "error")
|
|
81
|
+
* are included if their worktree DB shows status='complete'.
|
|
82
|
+
* See: https://github.com/gsd-build/gsd-2/issues/2812
|
|
35
83
|
*/
|
|
36
84
|
export function determineMergeOrder(
|
|
37
85
|
workers: WorkerInfo[],
|
|
38
86
|
order: MergeOrder = "sequential",
|
|
87
|
+
basePath?: string,
|
|
39
88
|
): string[] {
|
|
40
|
-
|
|
89
|
+
// Start with workers the orchestrator already knows are stopped
|
|
90
|
+
const stoppedIds = new Set(
|
|
91
|
+
workers.filter(w => w.state === "stopped").map(w => w.milestoneId),
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
// When basePath is available, also check worktree DBs for milestones
|
|
95
|
+
// whose orchestrator state is stale but are actually complete (#2812)
|
|
96
|
+
const dbCompleted = basePath ? discoverDbCompletedMilestones(basePath) : new Set<string>();
|
|
97
|
+
|
|
98
|
+
// Union: milestone is mergeable if stopped OR DB-complete
|
|
99
|
+
const mergeableIds = new Set([...stoppedIds, ...dbCompleted]);
|
|
100
|
+
|
|
101
|
+
// Build the list from tracked workers + any DB-discovered milestones
|
|
102
|
+
// not tracked by the orchestrator at all
|
|
103
|
+
const workerMap = new Map(workers.map(w => [w.milestoneId, w]));
|
|
104
|
+
const allMergeable: WorkerInfo[] = [];
|
|
105
|
+
for (const mid of mergeableIds) {
|
|
106
|
+
const w = workerMap.get(mid);
|
|
107
|
+
if (w) {
|
|
108
|
+
allMergeable.push(w);
|
|
109
|
+
} else {
|
|
110
|
+
// Milestone discovered from worktree DB but not in workers list
|
|
111
|
+
allMergeable.push({
|
|
112
|
+
milestoneId: mid,
|
|
113
|
+
title: mid,
|
|
114
|
+
pid: 0,
|
|
115
|
+
process: null,
|
|
116
|
+
worktreePath: basePath ? join(basePath, ".gsd", "worktrees", mid) : "",
|
|
117
|
+
startedAt: 0,
|
|
118
|
+
state: "stopped",
|
|
119
|
+
cost: 0,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
41
124
|
if (order === "by-completion") {
|
|
42
|
-
return
|
|
125
|
+
return allMergeable
|
|
43
126
|
.sort((a, b) => a.startedAt - b.startedAt) // earliest first
|
|
44
127
|
.map(w => w.milestoneId);
|
|
45
128
|
}
|
|
46
|
-
return
|
|
129
|
+
return allMergeable
|
|
47
130
|
.sort((a, b) => a.milestoneId.localeCompare(b.milestoneId))
|
|
48
131
|
.map(w => w.milestoneId);
|
|
49
132
|
}
|
|
@@ -114,7 +197,7 @@ export async function mergeAllCompleted(
|
|
|
114
197
|
workers: WorkerInfo[],
|
|
115
198
|
order: MergeOrder = "sequential",
|
|
116
199
|
): Promise<MergeResult[]> {
|
|
117
|
-
const mergeOrder = determineMergeOrder(workers, order);
|
|
200
|
+
const mergeOrder = determineMergeOrder(workers, order, basePath);
|
|
118
201
|
const results: MergeResult[] = [];
|
|
119
202
|
|
|
120
203
|
for (const mid of mergeOrder) {
|
|
@@ -519,8 +519,19 @@ function createMilestoneWorktree(basePath: string, milestoneId: string): string
|
|
|
519
519
|
|
|
520
520
|
/**
|
|
521
521
|
* Spawn a worker process for a milestone.
|
|
522
|
-
* The worker runs `gsd --
|
|
522
|
+
* The worker runs `gsd headless --json auto` in the milestone's worktree
|
|
523
523
|
* with GSD_MILESTONE_LOCK set to isolate state derivation.
|
|
524
|
+
*
|
|
525
|
+
* IMPORTANT: We use `headless --json auto` instead of `--print "/gsd auto"`.
|
|
526
|
+
* --print mode calls session.prompt() which returns immediately after the
|
|
527
|
+
* extension command handler fires, because auto-mode's ctx.newSession()
|
|
528
|
+
* resets the session and unblocks the outer prompt() await. This causes
|
|
529
|
+
* process.exit(0) to fire before any LLM work happens. See #2792.
|
|
530
|
+
*
|
|
531
|
+
* The headless subcommand uses an RPC client that keeps the process alive
|
|
532
|
+
* until auto-mode emits a terminal notification or the idle timer fires.
|
|
533
|
+
* It outputs NDJSON events to stdout (with --json), which our
|
|
534
|
+
* processWorkerLine() parser already understands.
|
|
524
535
|
*/
|
|
525
536
|
export function spawnWorker(
|
|
526
537
|
basePath: string,
|
|
@@ -537,7 +548,7 @@ export function spawnWorker(
|
|
|
537
548
|
|
|
538
549
|
let child: ChildProcess;
|
|
539
550
|
try {
|
|
540
|
-
child = spawn(process.execPath, [binPath, "
|
|
551
|
+
child = spawn(process.execPath, [binPath, "headless", "--json", "auto"], {
|
|
541
552
|
cwd: worker.worktreePath,
|
|
542
553
|
env: {
|
|
543
554
|
...process.env,
|
|
@@ -577,9 +588,10 @@ export function spawnWorker(
|
|
|
577
588
|
}
|
|
578
589
|
|
|
579
590
|
// ── NDJSON stdout monitoring ────────────────────────────────────────
|
|
580
|
-
// Workers run
|
|
581
|
-
// We parse message_end events to extract
|
|
582
|
-
// the coordinator's cost tracking in sync
|
|
591
|
+
// Workers run via `headless --json`, which forwards all RPC events
|
|
592
|
+
// as NDJSON to stdout. We parse message_end events to extract
|
|
593
|
+
// cost/token usage, keeping the coordinator's cost tracking in sync
|
|
594
|
+
// with actual API spend.
|
|
583
595
|
if (child.stdout) {
|
|
584
596
|
let stdoutBuffer = "";
|
|
585
597
|
child.stdout.on("data", (data: Buffer) => {
|
|
@@ -808,7 +820,12 @@ export async function stopParallel(
|
|
|
808
820
|
} catch { /* process may already be dead */ }
|
|
809
821
|
}
|
|
810
822
|
|
|
811
|
-
|
|
823
|
+
// Wait for the headless process to cascade SIGTERM to its RPC child.
|
|
824
|
+
// The headless signal handler calls client.stop() which sends SIGTERM
|
|
825
|
+
// to the RPC child and waits up to 1000ms. The previous 750ms window
|
|
826
|
+
// was insufficient — the parent got SIGKILL before the child died,
|
|
827
|
+
// leaving orphaned RPC processes holding auto.lock. See #2798.
|
|
828
|
+
const exitedAfterTerm = await waitForWorkerExit(worker, 3000);
|
|
812
829
|
if (!exitedAfterTerm && worker.pid > 0) {
|
|
813
830
|
try {
|
|
814
831
|
if (worker.process) {
|
|
@@ -196,18 +196,28 @@ function _parsePlanImpl(content: string): SlicePlan {
|
|
|
196
196
|
const mhSection = extractSection(body, 'Must-Haves');
|
|
197
197
|
const mustHaves = mhSection ? parseBullets(mhSection) : [];
|
|
198
198
|
|
|
199
|
+
// Parse tasks from ## Tasks section first, then scan the full body for any
|
|
200
|
+
// task checkboxes that were missed. Multi-task plans can interleave T01 detail
|
|
201
|
+
// headings (## Steps, ## Must-Haves) before T02's checkbox, which causes
|
|
202
|
+
// extractSection("Tasks") to stop at the first ## heading and miss T02+ (#3105).
|
|
199
203
|
const tasksSection = extractSection(body, 'Tasks');
|
|
200
204
|
const tasks: TaskPlanEntry[] = [];
|
|
201
205
|
|
|
202
|
-
|
|
203
|
-
|
|
206
|
+
// Parse task entries from a set of lines, appending to `tasks`.
|
|
207
|
+
const parseTaskLines = (lines: string[], knownIds: Set<string>): void => {
|
|
204
208
|
let currentTask: TaskPlanEntry | null = null;
|
|
205
209
|
|
|
206
|
-
for (const line of
|
|
210
|
+
for (const line of lines) {
|
|
207
211
|
const cbMatch = line.match(/^-\s+\[([ xX])\]\s+\*\*([\w.]+):\s+(.+?)\*\*\s*(.*)/);
|
|
208
212
|
// Heading-style: ### T01 -- Title, ### T01: Title, ### T01 — Title
|
|
209
213
|
const hdMatch = !cbMatch ? line.match(/^#{2,4}\s+([\w.]+)\s*(?:--|—|:)\s*(.+)/) : null;
|
|
210
214
|
if (cbMatch || hdMatch) {
|
|
215
|
+
const taskId = cbMatch ? cbMatch[2] : hdMatch![1];
|
|
216
|
+
// Skip tasks already found in the Tasks section
|
|
217
|
+
if (knownIds.has(taskId)) {
|
|
218
|
+
currentTask = null;
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
211
221
|
if (currentTask) tasks.push(currentTask);
|
|
212
222
|
|
|
213
223
|
if (cbMatch) {
|
|
@@ -259,8 +269,17 @@ function _parsePlanImpl(content: string): SlicePlan {
|
|
|
259
269
|
}
|
|
260
270
|
}
|
|
261
271
|
if (currentTask) tasks.push(currentTask);
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
if (tasksSection) {
|
|
275
|
+
parseTaskLines(tasksSection.split('\n'), new Set());
|
|
262
276
|
}
|
|
263
277
|
|
|
278
|
+
// Second pass: scan the full body for task checkboxes outside ## Tasks.
|
|
279
|
+
// This handles interleaved plans where T02+ appear after T01's detail headings.
|
|
280
|
+
const foundIds = new Set(tasks.map(t => t.id));
|
|
281
|
+
parseTaskLines(body.split('\n'), foundIds);
|
|
282
|
+
|
|
264
283
|
const filesSection = extractSection(body, 'Files Likely Touched');
|
|
265
284
|
const filesLikelyTouched = filesSection ? parseBullets(filesSection) : [];
|
|
266
285
|
|
|
@@ -264,6 +264,7 @@ export const GSD_ROOT_FILES = {
|
|
|
264
264
|
REQUIREMENTS: "REQUIREMENTS.md",
|
|
265
265
|
OVERRIDES: "OVERRIDES.md",
|
|
266
266
|
KNOWLEDGE: "KNOWLEDGE.md",
|
|
267
|
+
CODEBASE: "CODEBASE.md",
|
|
267
268
|
} as const;
|
|
268
269
|
|
|
269
270
|
export type GSDRootFileKey = keyof typeof GSD_ROOT_FILES;
|
|
@@ -276,6 +277,7 @@ const LEGACY_GSD_ROOT_FILES: Record<GSDRootFileKey, string> = {
|
|
|
276
277
|
REQUIREMENTS: "requirements.md",
|
|
277
278
|
OVERRIDES: "overrides.md",
|
|
278
279
|
KNOWLEDGE: "knowledge.md",
|
|
280
|
+
CODEBASE: "codebase.md",
|
|
279
281
|
};
|
|
280
282
|
|
|
281
283
|
// ─── GSD Root Discovery ───────────────────────────────────────────────────────
|
|
@@ -307,16 +309,58 @@ export function gsdRoot(basePath: string): string {
|
|
|
307
309
|
return result;
|
|
308
310
|
}
|
|
309
311
|
|
|
312
|
+
/**
|
|
313
|
+
* Detect if a path is inside a .gsd/worktrees/<name>/ structure.
|
|
314
|
+
*
|
|
315
|
+
* GSD auto-worktrees live at <project>/.gsd/worktrees/<milestoneId>/.
|
|
316
|
+
* When gsdRoot() is called with such a path, we must NOT walk up to the
|
|
317
|
+
* project root's .gsd — each worktree manages its own .gsd state (#2594).
|
|
318
|
+
*
|
|
319
|
+
* Matches both forward-slash and platform-native separators to handle
|
|
320
|
+
* Windows paths (path.sep = '\\') and normalized Unix paths.
|
|
321
|
+
*/
|
|
322
|
+
function isInsideGsdWorktree(p: string): boolean {
|
|
323
|
+
// Match /.gsd/worktrees/<name> where <name> is the final segment or
|
|
324
|
+
// followed by a separator. The <name> segment must be non-empty.
|
|
325
|
+
const sepFwd = "/";
|
|
326
|
+
const sepNative = "\\";
|
|
327
|
+
const markers = [
|
|
328
|
+
`${sepFwd}.gsd${sepFwd}worktrees${sepFwd}`,
|
|
329
|
+
`${sepNative}.gsd${sepNative}worktrees${sepNative}`,
|
|
330
|
+
];
|
|
331
|
+
for (const marker of markers) {
|
|
332
|
+
const idx = p.indexOf(marker);
|
|
333
|
+
if (idx === -1) continue;
|
|
334
|
+
// Verify there's a non-empty worktree name after the marker
|
|
335
|
+
const afterMarker = p.slice(idx + marker.length);
|
|
336
|
+
// The name is everything up to the next separator (or end of string)
|
|
337
|
+
const nameEnd = afterMarker.search(/[/\\]/);
|
|
338
|
+
const name = nameEnd === -1 ? afterMarker : afterMarker.slice(0, nameEnd);
|
|
339
|
+
if (name.length > 0) return true;
|
|
340
|
+
}
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
|
|
310
344
|
function probeGsdRoot(rawBasePath: string): string {
|
|
311
345
|
// 1. Fast path — check the input path directly
|
|
312
346
|
const local = join(rawBasePath, ".gsd");
|
|
313
347
|
if (existsSync(local)) return local;
|
|
314
348
|
|
|
349
|
+
// 1b. Worktree guard (#2594) — if basePath is inside a .gsd/worktrees/<name>/
|
|
350
|
+
// structure, return the worktree-local .gsd path immediately. Without this,
|
|
351
|
+
// the git-root probe (step 2) or walk-up (step 3) escapes to the project
|
|
352
|
+
// root's .gsd, causing ensurePreconditions() and deriveState() to read/write
|
|
353
|
+
// state in the wrong location.
|
|
354
|
+
if (isInsideGsdWorktree(rawBasePath)) return local;
|
|
355
|
+
|
|
315
356
|
// Resolve symlinks so path comparisons work correctly across platforms
|
|
316
357
|
// (e.g. macOS /var → /private/var). Use rawBasePath as fallback if not resolvable.
|
|
317
358
|
let basePath: string;
|
|
318
359
|
try { basePath = realpathSync.native(rawBasePath); } catch { basePath = rawBasePath; }
|
|
319
360
|
|
|
361
|
+
// Also check the resolved path for the worktree pattern (macOS /tmp → /private/tmp)
|
|
362
|
+
if (basePath !== rawBasePath && isInsideGsdWorktree(basePath)) return local;
|
|
363
|
+
|
|
320
364
|
// 2. Git root anchor — used as both probe target and walk-up boundary
|
|
321
365
|
// Only walk if we're inside a git project — prevents escaping into
|
|
322
366
|
// unrelated filesystem territory when running outside any repo.
|
|
@@ -69,6 +69,7 @@ export function resolveModelWithFallbacksForUnit(unitType: string): ResolvedMode
|
|
|
69
69
|
break;
|
|
70
70
|
case "complete-slice":
|
|
71
71
|
case "complete-milestone":
|
|
72
|
+
case "worktree-merge":
|
|
72
73
|
case "run-uat":
|
|
73
74
|
phaseConfig = m.completion;
|
|
74
75
|
break;
|
|
@@ -137,6 +138,18 @@ export function getNextFallbackModel(
|
|
|
137
138
|
}
|
|
138
139
|
}
|
|
139
140
|
|
|
141
|
+
/**
|
|
142
|
+
* Detect whether an error message indicates a transient network error
|
|
143
|
+
* (worth retrying the same model) vs a permanent provider error
|
|
144
|
+
* (auth failure, quota exceeded, etc. -- should fall back immediately).
|
|
145
|
+
*/
|
|
146
|
+
export function isTransientNetworkError(errorMsg: string): boolean {
|
|
147
|
+
if (!errorMsg) return false;
|
|
148
|
+
const hasNetworkSignal = /network|ECONNRESET|ETIMEDOUT|ECONNREFUSED|socket hang up|fetch failed|connection.*reset|dns/i.test(errorMsg);
|
|
149
|
+
const hasPermanentSignal = /auth|unauthorized|forbidden|invalid.*key|quota|billing/i.test(errorMsg);
|
|
150
|
+
return hasNetworkSignal && !hasPermanentSignal;
|
|
151
|
+
}
|
|
152
|
+
|
|
140
153
|
/**
|
|
141
154
|
* Validate a model ID string.
|
|
142
155
|
* Returns true if the ID looks like a valid model identifier.
|
|
@@ -308,7 +321,7 @@ export function resolveContextSelection(): import("./types.js").ContextSelection
|
|
|
308
321
|
}
|
|
309
322
|
|
|
310
323
|
/**
|
|
311
|
-
* Resolve the search provider preference from
|
|
324
|
+
* Resolve the search provider preference from preferences.md.
|
|
312
325
|
* Returns undefined if not configured (caller falls back to existing behavior).
|
|
313
326
|
*/
|
|
314
327
|
export function resolveSearchProviderFromPreferences(): GSDPreferences["search_provider"] | undefined {
|
|
@@ -93,6 +93,7 @@ export const KNOWN_PREFERENCE_KEYS = new Set<string>([
|
|
|
93
93
|
"service_tier",
|
|
94
94
|
"forensics_dedup",
|
|
95
95
|
"show_token_cost",
|
|
96
|
+
"stale_commit_threshold_minutes",
|
|
96
97
|
"experimental",
|
|
97
98
|
]);
|
|
98
99
|
|
|
@@ -100,7 +101,8 @@ export const KNOWN_PREFERENCE_KEYS = new Set<string>([
|
|
|
100
101
|
export const KNOWN_UNIT_TYPES = [
|
|
101
102
|
"research-milestone", "plan-milestone", "research-slice", "plan-slice",
|
|
102
103
|
"execute-task", "reactive-execute", "gate-evaluate", "complete-slice", "replan-slice", "reassess-roadmap",
|
|
103
|
-
"run-uat", "complete-milestone",
|
|
104
|
+
"run-uat", "complete-milestone", "validate-milestone", "rewrite-docs",
|
|
105
|
+
"discuss-milestone", "discuss-slice", "worktree-merge",
|
|
104
106
|
] as const;
|
|
105
107
|
export type UnitType = (typeof KNOWN_UNIT_TYPES)[number];
|
|
106
108
|
|
|
@@ -252,6 +254,13 @@ export interface GSDPreferences {
|
|
|
252
254
|
forensics_dedup?: boolean;
|
|
253
255
|
/** Opt-in: show per-prompt and cumulative session token cost in the footer. Default: false. */
|
|
254
256
|
show_token_cost?: boolean;
|
|
257
|
+
/**
|
|
258
|
+
* Minutes without a commit before flagging uncommitted changes as stale.
|
|
259
|
+
* When the threshold is exceeded and the working tree is dirty, doctor will
|
|
260
|
+
* auto-commit a safety snapshot tagged with `[gsd safety]`. Default: 30.
|
|
261
|
+
* Set to 0 to disable.
|
|
262
|
+
*/
|
|
263
|
+
stale_commit_threshold_minutes?: number;
|
|
255
264
|
/**
|
|
256
265
|
* Opt-in experimental features. All features here are disabled by default.
|
|
257
266
|
* See the preferences reference for details on each feature.
|
|
@@ -22,6 +22,7 @@ import { normalizeStringArray } from "../shared/format-utils.js";
|
|
|
22
22
|
import { resolveProfileDefaults as _resolveProfileDefaults } from "./preferences-models.js";
|
|
23
23
|
|
|
24
24
|
import {
|
|
25
|
+
KNOWN_PREFERENCE_KEYS,
|
|
25
26
|
MODE_DEFAULTS,
|
|
26
27
|
type WorkflowMode,
|
|
27
28
|
type GSDPreferences,
|
|
@@ -68,6 +69,7 @@ export {
|
|
|
68
69
|
resolveModelForUnit,
|
|
69
70
|
resolveModelWithFallbacksForUnit,
|
|
70
71
|
getNextFallbackModel,
|
|
72
|
+
isTransientNetworkError,
|
|
71
73
|
validateModelId,
|
|
72
74
|
updatePreferencesModels,
|
|
73
75
|
resolveDynamicRoutingConfig,
|
|
@@ -86,7 +88,7 @@ function gsdHome(): string {
|
|
|
86
88
|
}
|
|
87
89
|
|
|
88
90
|
function globalPreferencesPath(): string {
|
|
89
|
-
return join(gsdHome(), "
|
|
91
|
+
return join(gsdHome(), "preferences.md");
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
function legacyGlobalPreferencesPath(): string {
|
|
@@ -94,15 +96,15 @@ function legacyGlobalPreferencesPath(): string {
|
|
|
94
96
|
}
|
|
95
97
|
|
|
96
98
|
function projectPreferencesPath(): string {
|
|
97
|
-
return join(gsdRoot(process.cwd()), "
|
|
99
|
+
return join(gsdRoot(process.cwd()), "preferences.md");
|
|
98
100
|
}
|
|
99
|
-
//
|
|
100
|
-
// Check
|
|
101
|
-
function
|
|
102
|
-
return join(gsdHome(), "
|
|
101
|
+
// Bootstrap in gitignore.ts historically created PREFERENCES.md (uppercase) by mistake.
|
|
102
|
+
// Check uppercase as a fallback so those files aren't silently ignored.
|
|
103
|
+
function globalPreferencesPathUppercase(): string {
|
|
104
|
+
return join(gsdHome(), "PREFERENCES.md");
|
|
103
105
|
}
|
|
104
|
-
function
|
|
105
|
-
return join(gsdRoot(process.cwd()), "
|
|
106
|
+
function projectPreferencesPathUppercase(): string {
|
|
107
|
+
return join(gsdRoot(process.cwd()), "PREFERENCES.md");
|
|
106
108
|
}
|
|
107
109
|
|
|
108
110
|
export function getGlobalGSDPreferencesPath(): string {
|
|
@@ -121,13 +123,13 @@ export function getProjectGSDPreferencesPath(): string {
|
|
|
121
123
|
|
|
122
124
|
export function loadGlobalGSDPreferences(): LoadedGSDPreferences | null {
|
|
123
125
|
return loadPreferencesFile(globalPreferencesPath(), "global")
|
|
124
|
-
?? loadPreferencesFile(
|
|
126
|
+
?? loadPreferencesFile(globalPreferencesPathUppercase(), "global")
|
|
125
127
|
?? loadPreferencesFile(legacyGlobalPreferencesPath(), "global");
|
|
126
128
|
}
|
|
127
129
|
|
|
128
130
|
export function loadProjectGSDPreferences(): LoadedGSDPreferences | null {
|
|
129
131
|
return loadPreferencesFile(projectPreferencesPath(), "project")
|
|
130
|
-
?? loadPreferencesFile(
|
|
132
|
+
?? loadPreferencesFile(projectPreferencesPathUppercase(), "project");
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
export function loadEffectiveGSDPreferences(): LoadedGSDPreferences | null {
|
|
@@ -222,7 +224,7 @@ export function parsePreferencesMarkdown(content: string): GSDPreferences | null
|
|
|
222
224
|
|
|
223
225
|
if (!_warnedUnrecognizedFormat) {
|
|
224
226
|
_warnedUnrecognizedFormat = true;
|
|
225
|
-
console.warn("[parsePreferencesMarkdown]
|
|
227
|
+
console.warn("[parsePreferencesMarkdown] preferences.md exists but uses an unrecognized format — skipping.");
|
|
226
228
|
}
|
|
227
229
|
return null;
|
|
228
230
|
}
|
|
@@ -250,7 +252,7 @@ function parseFrontmatterBlock(frontmatter: string): GSDPreferences {
|
|
|
250
252
|
* - planner: sonnet
|
|
251
253
|
*/
|
|
252
254
|
function parseHeadingListFormat(content: string): GSDPreferences {
|
|
253
|
-
const result: Record<string,
|
|
255
|
+
const result: Record<string, string[]> = {};
|
|
254
256
|
let currentSection: string | null = null;
|
|
255
257
|
|
|
256
258
|
for (const rawLine of content.split('\n')) {
|
|
@@ -258,27 +260,44 @@ function parseHeadingListFormat(content: string): GSDPreferences {
|
|
|
258
260
|
const headingMatch = line.match(/^##\s+(.+)$/);
|
|
259
261
|
if (headingMatch) {
|
|
260
262
|
currentSection = headingMatch[1].trim().toLowerCase().replace(/\s+/g, '_');
|
|
263
|
+
if (!result[currentSection]) result[currentSection] = [];
|
|
261
264
|
continue;
|
|
262
265
|
}
|
|
263
|
-
if (currentSection) {
|
|
264
|
-
|
|
265
|
-
if (itemMatch) {
|
|
266
|
-
if (!result[currentSection]) result[currentSection] = {};
|
|
267
|
-
const value = itemMatch[2].trim();
|
|
268
|
-
// Coerce "true"/"false" strings and numbers
|
|
269
|
-
result[currentSection][itemMatch[1].trim()] = value;
|
|
270
|
-
}
|
|
266
|
+
if (currentSection && line.trim() && !line.trimStart().startsWith('#')) {
|
|
267
|
+
result[currentSection].push(line);
|
|
271
268
|
}
|
|
272
269
|
}
|
|
273
270
|
|
|
274
|
-
// Convert string values to appropriate types via YAML parser for each section
|
|
275
271
|
const typed: Record<string, unknown> = {};
|
|
276
|
-
for (const [section,
|
|
277
|
-
|
|
272
|
+
for (const [section, lines] of Object.entries(result)) {
|
|
273
|
+
if (lines.length === 0) continue;
|
|
274
|
+
|
|
275
|
+
const usesLegacyListItems = lines.every((line) => /^\s*-\s+[^:]+:\s*.*$/.test(line));
|
|
276
|
+
const yamlBlock = usesLegacyListItems
|
|
277
|
+
? lines.map((line) => line.replace(/^\s*-\s+/, '')).join('\n')
|
|
278
|
+
: lines.join('\n');
|
|
279
|
+
|
|
278
280
|
try {
|
|
279
|
-
|
|
281
|
+
const parsed = parseYaml(yamlBlock);
|
|
282
|
+
if (typeof parsed !== 'object' || parsed === null) continue;
|
|
283
|
+
|
|
284
|
+
let targetSection = section;
|
|
285
|
+
let value: unknown = parsed;
|
|
286
|
+
|
|
287
|
+
if (!Array.isArray(parsed)) {
|
|
288
|
+
const keys = Object.keys(parsed);
|
|
289
|
+
if (keys.length === 1) {
|
|
290
|
+
const [onlyKey] = keys;
|
|
291
|
+
if (onlyKey === section || (!KNOWN_PREFERENCE_KEYS.has(section) && KNOWN_PREFERENCE_KEYS.has(onlyKey))) {
|
|
292
|
+
targetSection = onlyKey;
|
|
293
|
+
value = (parsed as Record<string, unknown>)[onlyKey];
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
typed[targetSection] = value;
|
|
280
299
|
} catch {
|
|
281
|
-
|
|
300
|
+
/* malformed section — skip */
|
|
282
301
|
}
|
|
283
302
|
}
|
|
284
303
|
|
|
@@ -352,9 +371,6 @@ function mergePreferences(base: GSDPreferences, override: GSDPreferences): GSDPr
|
|
|
352
371
|
service_tier: override.service_tier ?? base.service_tier,
|
|
353
372
|
forensics_dedup: override.forensics_dedup ?? base.forensics_dedup,
|
|
354
373
|
show_token_cost: override.show_token_cost ?? base.show_token_cost,
|
|
355
|
-
experimental: (base.experimental || override.experimental)
|
|
356
|
-
? { ...(base.experimental ?? {}), ...(override.experimental ?? {}) }
|
|
357
|
-
: undefined,
|
|
358
374
|
};
|
|
359
375
|
}
|
|
360
376
|
|
|
@@ -501,7 +517,7 @@ export function resolvePreDispatchHooks(): PreDispatchHookConfig[] {
|
|
|
501
517
|
* Resolve the effective git isolation mode from preferences.
|
|
502
518
|
* Returns "none" (default), "worktree", or "branch".
|
|
503
519
|
*
|
|
504
|
-
* Default is "none" so GSD works out of the box without
|
|
520
|
+
* Default is "none" so GSD works out of the box without preferences.md.
|
|
505
521
|
* Worktree isolation requires explicit opt-in because it depends on git
|
|
506
522
|
* branch infrastructure that must be set up before use.
|
|
507
523
|
*/
|
|
@@ -134,7 +134,10 @@ export function loadPrompt(name: string, vars: Record<string, string> = {}): str
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
for (const [key, value] of Object.entries(effectiveVars)) {
|
|
137
|
-
|
|
137
|
+
// Use split/join instead of replaceAll to avoid JavaScript's special
|
|
138
|
+
// replacement patterns ($', $`, $&) being interpreted in the value.
|
|
139
|
+
// See: https://github.com/gsd-build/gsd-2/issues/2968
|
|
140
|
+
content = content.split(`{{${key}}}`).join(value);
|
|
138
141
|
}
|
|
139
142
|
|
|
140
143
|
return content.trim();
|