gsd-pi 2.76.0 → 2.77.0-dev.c9c8932c6
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 +32 -30
- package/dist/claude-cli-check.js +32 -3
- package/dist/cli.js +14 -0
- package/dist/extension-discovery.d.ts +6 -0
- package/dist/extension-discovery.js +37 -0
- package/dist/extension-registry.d.ts +3 -0
- package/dist/extension-sort.d.ts +18 -0
- package/dist/extension-sort.js +114 -0
- package/dist/extension-validator.d.ts +47 -0
- package/dist/extension-validator.js +127 -0
- package/dist/loader.js +35 -7
- package/dist/mcp-server.d.ts +7 -0
- package/dist/mcp-server.js +35 -1
- package/dist/onboarding.js +45 -0
- package/dist/resource-loader.d.ts +1 -1
- package/dist/resource-loader.js +2 -8
- package/dist/resources/agents/researcher.md +1 -1
- package/dist/resources/extensions/claude-code-cli/readiness.js +31 -8
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +134 -57
- package/dist/resources/extensions/cmux/index.js +20 -0
- package/dist/resources/extensions/google-search/extension-manifest.json +5 -4
- package/dist/resources/extensions/google-search/index.js +2 -375
- package/dist/resources/extensions/gsd/auto/loop.js +9 -0
- package/dist/resources/extensions/gsd/auto/phases.js +104 -11
- package/dist/resources/extensions/gsd/auto/run-unit.js +38 -2
- package/dist/resources/extensions/gsd/auto/session.js +22 -1
- package/dist/resources/extensions/gsd/auto-dispatch.js +56 -17
- package/dist/resources/extensions/gsd/auto-model-selection.js +53 -16
- package/dist/resources/extensions/gsd/auto-post-unit.js +59 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +14 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +69 -1
- package/dist/resources/extensions/gsd/auto-start.js +74 -59
- package/dist/resources/extensions/gsd/auto-verification.js +33 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +51 -53
- package/dist/resources/extensions/gsd/auto.js +92 -37
- package/dist/resources/extensions/gsd/blocked-models.js +68 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +93 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +39 -9
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +93 -0
- package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +3 -0
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +23 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +52 -6
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +95 -29
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +34 -2
- package/dist/resources/extensions/gsd/clean-root-preflight.js +93 -0
- package/dist/resources/extensions/gsd/commands-cmux.js +9 -6
- package/dist/resources/extensions/gsd/commands-extensions.js +634 -43
- package/dist/resources/extensions/gsd/commands-extract-learnings.js +54 -89
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +968 -23
- package/dist/resources/extensions/gsd/compaction-snapshot.js +121 -0
- package/dist/resources/extensions/gsd/complexity-classifier.js +5 -3
- package/dist/resources/extensions/gsd/db-writer.js +88 -16
- package/dist/resources/extensions/gsd/dispatch-guard.js +44 -3
- package/dist/resources/extensions/gsd/doctor-git-checks.js +23 -29
- package/dist/resources/extensions/gsd/doctor-providers.js +51 -5
- package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +1 -0
- package/dist/resources/extensions/gsd/error-classifier.js +31 -3
- package/dist/resources/extensions/gsd/exec-history.js +120 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +258 -0
- package/dist/resources/extensions/gsd/gitignore.js +1 -0
- package/dist/resources/extensions/gsd/gsd-db.js +168 -23
- package/dist/resources/extensions/gsd/guided-flow.js +190 -1
- package/dist/resources/extensions/gsd/health-widget.js +4 -1
- package/dist/resources/extensions/gsd/hook-emitter.js +108 -0
- package/dist/resources/extensions/gsd/init-wizard.js +15 -1
- package/dist/resources/extensions/gsd/key-manager.js +28 -0
- package/dist/resources/extensions/gsd/memory-backfill.js +126 -0
- package/dist/resources/extensions/gsd/memory-store.js +19 -0
- package/dist/resources/extensions/gsd/model-router.js +36 -3
- package/dist/resources/extensions/gsd/notifications.js +30 -16
- package/dist/resources/extensions/gsd/pre-execution-checks.js +44 -9
- package/dist/resources/extensions/gsd/preferences-types.js +9 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +83 -0
- package/dist/resources/extensions/gsd/preferences.js +17 -17
- package/dist/resources/extensions/gsd/prompt-loader.js +22 -7
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
- package/dist/resources/extensions/gsd/prompts/discuss.md +29 -2
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/system.md +1 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +96 -0
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +13 -5
- package/dist/resources/extensions/gsd/safety/safety-harness.js +5 -1
- package/dist/resources/extensions/gsd/state.js +43 -4
- package/dist/resources/extensions/gsd/token-counter.js +22 -5
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +16 -10
- package/dist/resources/extensions/gsd/tools/exec-search-tool.js +59 -0
- package/dist/resources/extensions/gsd/tools/exec-tool.js +126 -0
- package/dist/resources/extensions/gsd/tools/memory-tools.js +26 -1
- package/dist/resources/extensions/gsd/tools/resume-tool.js +23 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +20 -3
- package/dist/resources/extensions/gsd/workflow-mcp.js +3 -0
- package/dist/resources/extensions/gsd/workflow-templates/spike.md +6 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +50 -10
- package/dist/resources/extensions/search-the-web/command-search-provider.js +5 -4
- package/dist/resources/extensions/search-the-web/native-search.js +45 -13
- package/dist/resources/extensions/shared/cmux-events.js +12 -0
- package/dist/resources/extensions/shared/rtk-session-stats.js +1 -2
- package/dist/resources/skills/api-design/SKILL.md +190 -0
- package/dist/resources/skills/create-mcp-server/SKILL.md +121 -0
- package/dist/resources/skills/decompose-into-slices/SKILL.md +139 -0
- package/dist/resources/skills/dependency-upgrade/SKILL.md +158 -0
- package/dist/resources/skills/design-an-interface/SKILL.md +102 -0
- package/dist/resources/skills/forensics/SKILL.md +153 -0
- package/dist/resources/skills/grill-me/SKILL.md +93 -0
- package/dist/resources/skills/handoff/SKILL.md +121 -0
- package/dist/resources/skills/observability/SKILL.md +174 -0
- package/dist/resources/skills/security-review/SKILL.md +181 -0
- package/dist/resources/skills/spike-wrap-up/SKILL.md +138 -0
- package/dist/resources/skills/tdd/SKILL.md +112 -0
- package/dist/resources/skills/verify-before-complete/SKILL.md +98 -0
- package/dist/resources/skills/write-docs/SKILL.md +82 -0
- package/dist/resources/skills/write-milestone-brief/SKILL.md +135 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
- package/dist/web/standalone/.next/build-manifest.json +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 +4 -4
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/63.js +3 -3
- package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- package/dist/web/standalone/.next/server/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 +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2826.d445fb428ef41fa1.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-5b113fd32bc2a1c3.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-5fc74f13a25fa1bb.js → webpack-1832629448831fdc.js} +1 -1
- 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/welcome-screen.js +6 -1
- package/dist/wizard.js +2 -0
- package/package.json +14 -12
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/dist/remote-questions.d.ts +45 -0
- package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -0
- package/packages/mcp-server/dist/remote-questions.js +732 -0
- package/packages/mcp-server/dist/remote-questions.js.map +1 -0
- package/packages/mcp-server/dist/server.d.ts +7 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +70 -8
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/session-manager.d.ts +14 -0
- package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
- package/packages/mcp-server/dist/session-manager.js +49 -1
- package/packages/mcp-server/dist/session-manager.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +163 -25
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +9 -3
- package/packages/mcp-server/src/mcp-server.test.ts +67 -0
- package/packages/mcp-server/src/readers/readers.test.ts +5 -1
- package/packages/mcp-server/src/remote-questions.test.ts +294 -0
- package/packages/mcp-server/src/remote-questions.ts +916 -0
- package/packages/mcp-server/src/server.ts +89 -14
- package/packages/mcp-server/src/session-manager.ts +43 -1
- package/packages/mcp-server/src/workflow-tools.test.ts +146 -1
- package/packages/mcp-server/src/workflow-tools.ts +215 -43
- package/packages/mcp-server/tsconfig.test.json +19 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +6 -1
- package/packages/native/src/__tests__/clipboard.test.mjs +69 -23
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +12 -0
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +30 -0
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/package.json +6 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +220 -15
- package/packages/pi-agent-core/src/agent-loop.ts +14 -0
- package/packages/pi-agent-core/src/types.ts +34 -0
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/models/custom.d.ts +38 -0
- package/packages/pi-ai/dist/models/custom.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/custom.js +41 -0
- package/packages/pi-ai/dist/models/custom.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +13 -0
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +27 -4
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +13 -4
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +80 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +60 -15
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.d.ts +10 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +16 -1
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/providers/think-tag-parser.d.ts +17 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.js +75 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.js.map +1 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.js +41 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js +12 -2
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +164 -14
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +15 -3
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +67 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +16 -3
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +67 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +289 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +1 -0
- package/packages/pi-ai/package.json +6 -1
- package/packages/pi-ai/src/models/custom.ts +42 -0
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +1 -1
- package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -0
- package/packages/pi-ai/src/providers/anthropic-shared.ts +26 -5
- package/packages/pi-ai/src/providers/anthropic.ts +15 -4
- package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +98 -0
- package/packages/pi-ai/src/providers/openai-completions.ts +57 -16
- package/packages/pi-ai/src/providers/simple-options.ts +17 -1
- package/packages/pi-ai/src/providers/think-tag-parser.test.ts +44 -0
- package/packages/pi-ai/src/providers/think-tag-parser.ts +94 -0
- package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +200 -23
- package/packages/pi-ai/src/utils/oauth/github-copilot.ts +12 -2
- package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +84 -0
- package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +15 -5
- package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +84 -0
- package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +16 -5
- package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +363 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +3 -2
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +2 -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 +32 -2
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +25 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +105 -6
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +230 -28
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +30 -2
- package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/utils.js +113 -12
- package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +8 -2
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js +56 -1
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +8 -15
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts +25 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js +109 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts +67 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js +167 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +3 -2
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +28 -8
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +35 -2
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +233 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +212 -2
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts +53 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.js +337 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +234 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/index.js +1 -0
- package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +11 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.d.ts +3 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.js +92 -12
- package/packages/pi-coding-agent/dist/core/model-discovery.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.test.js +16 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js +40 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +2 -2
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js +203 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-discovery.test.js +61 -1
- package/packages/pi-coding-agent/dist/core/model-registry-discovery.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +90 -10
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.js +49 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.js +67 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.js +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +10 -6
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js +45 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +55 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +3 -3
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/path-utils.test.js +2 -1
- package/packages/pi-coding-agent/dist/core/tools/path-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +5 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +13 -7
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts +7 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +29 -21
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +13 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +6 -1
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +3 -2
- package/packages/pi-coding-agent/src/core/agent-session.ts +38 -2
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +368 -28
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +122 -6
- package/packages/pi-coding-agent/src/core/compaction/utils.ts +111 -13
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +8 -1
- package/packages/pi-coding-agent/src/core/compaction-utils.test.ts +68 -1
- package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +9 -18
- package/packages/pi-coding-agent/src/core/extensions/extension-discovery.ts +119 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-registry.ts +222 -0
- package/packages/pi-coding-agent/src/core/extensions/index.ts +16 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +29 -11
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +351 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +266 -0
- package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +269 -0
- package/packages/pi-coding-agent/src/core/hooks-runner.ts +460 -0
- package/packages/pi-coding-agent/src/core/index.ts +10 -0
- package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +13 -0
- package/packages/pi-coding-agent/src/core/model-discovery.test.ts +19 -0
- package/packages/pi-coding-agent/src/core/model-discovery.ts +99 -12
- package/packages/pi-coding-agent/src/core/model-registry-auth-header.test.ts +44 -0
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +2 -2
- package/packages/pi-coding-agent/src/core/model-registry-custom-caps.test.ts +245 -0
- package/packages/pi-coding-agent/src/core/model-registry-discovery.test.ts +75 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +102 -10
- package/packages/pi-coding-agent/src/core/redact-secrets.test.ts +86 -0
- package/packages/pi-coding-agent/src/core/redact-secrets.ts +58 -0
- package/packages/pi-coding-agent/src/core/resource-loader.ts +1 -1
- package/packages/pi-coding-agent/src/core/session-manager.test.ts +65 -1
- package/packages/pi-coding-agent/src/core/session-manager.ts +10 -6
- package/packages/pi-coding-agent/src/core/settings-manager.ts +57 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +3 -3
- package/packages/pi-coding-agent/src/core/tools/path-utils.test.ts +2 -1
- package/packages/pi-coding-agent/src/index.ts +16 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +6 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +16 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +36 -22
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +14 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +13 -1
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js +12 -5
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
- package/packages/pi-tui/package.json +6 -1
- package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -5
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +6 -1
- package/pkg/package.json +1 -1
- package/scripts/install.js +512 -0
- package/scripts/lib/workspace-manifest.cjs +86 -0
- package/scripts/link-workspace-packages.cjs +5 -16
- package/scripts/postinstall.js +9 -178
- package/src/resources/agents/researcher.md +1 -1
- package/src/resources/extensions/claude-code-cli/readiness.ts +32 -8
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +148 -61
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +236 -5
- package/src/resources/extensions/cmux/index.ts +35 -10
- package/src/resources/extensions/google-search/extension-manifest.json +5 -4
- package/src/resources/extensions/google-search/index.ts +8 -470
- package/src/resources/extensions/gsd/auto/loop-deps.ts +15 -1
- package/src/resources/extensions/gsd/auto/loop.ts +9 -0
- package/src/resources/extensions/gsd/auto/phases.ts +131 -10
- package/src/resources/extensions/gsd/auto/run-unit.ts +40 -2
- package/src/resources/extensions/gsd/auto/session.ts +35 -2
- package/src/resources/extensions/gsd/auto/types.ts +1 -1
- package/src/resources/extensions/gsd/auto-dispatch.ts +59 -16
- package/src/resources/extensions/gsd/auto-model-selection.ts +71 -15
- package/src/resources/extensions/gsd/auto-post-unit.ts +62 -3
- package/src/resources/extensions/gsd/auto-prompts.ts +28 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +62 -1
- package/src/resources/extensions/gsd/auto-start.ts +80 -74
- package/src/resources/extensions/gsd/auto-verification.ts +33 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +62 -63
- package/src/resources/extensions/gsd/auto.ts +100 -41
- package/src/resources/extensions/gsd/blocked-models.ts +98 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +120 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +40 -9
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +109 -0
- package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +5 -0
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +26 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +54 -6
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +102 -35
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +35 -2
- package/src/resources/extensions/gsd/clean-root-preflight.ts +111 -0
- package/src/resources/extensions/gsd/commands-cmux.ts +10 -6
- package/src/resources/extensions/gsd/commands-extensions.ts +747 -41
- package/src/resources/extensions/gsd/commands-extract-learnings.ts +55 -90
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +898 -32
- package/src/resources/extensions/gsd/compaction-snapshot.ts +165 -0
- package/src/resources/extensions/gsd/complexity-classifier.ts +5 -3
- package/src/resources/extensions/gsd/db-writer.ts +88 -17
- package/src/resources/extensions/gsd/dispatch-guard.ts +44 -2
- package/src/resources/extensions/gsd/doctor-git-checks.ts +23 -27
- package/src/resources/extensions/gsd/doctor-providers.ts +59 -6
- package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +2 -0
- package/src/resources/extensions/gsd/error-classifier.ts +36 -3
- package/src/resources/extensions/gsd/exec-history.ts +153 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +326 -0
- package/src/resources/extensions/gsd/gitignore.ts +1 -1
- package/src/resources/extensions/gsd/gsd-db.ts +186 -23
- package/src/resources/extensions/gsd/guided-flow.ts +222 -1
- package/src/resources/extensions/gsd/health-widget.ts +3 -1
- package/src/resources/extensions/gsd/hook-emitter.ts +188 -0
- package/src/resources/extensions/gsd/init-wizard.ts +15 -1
- package/src/resources/extensions/gsd/journal.ts +2 -1
- package/src/resources/extensions/gsd/key-manager.ts +28 -0
- package/src/resources/extensions/gsd/memory-backfill.ts +140 -0
- package/src/resources/extensions/gsd/memory-store.ts +26 -0
- package/src/resources/extensions/gsd/model-router.ts +42 -1
- package/src/resources/extensions/gsd/notifications.ts +27 -15
- package/src/resources/extensions/gsd/pre-execution-checks.ts +46 -10
- package/src/resources/extensions/gsd/preferences-types.ts +46 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +79 -0
- package/src/resources/extensions/gsd/preferences.ts +17 -17
- package/src/resources/extensions/gsd/prompt-loader.ts +30 -7
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
- package/src/resources/extensions/gsd/prompts/discuss.md +29 -2
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/system.md +1 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +119 -0
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +17 -4
- package/src/resources/extensions/gsd/safety/safety-harness.ts +9 -0
- package/src/resources/extensions/gsd/state.ts +45 -4
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +188 -2
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +95 -1
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +141 -0
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +33 -3
- package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/blocked-models.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/cmux.test.ts +5 -9
- package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +68 -66
- package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +61 -1
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +9 -9
- package/src/resources/extensions/gsd/tests/dispatch-guard-summary-db-mismatch.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +148 -3
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +306 -1
- package/src/resources/extensions/gsd/tests/escalation.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/exec-history.test.ts +237 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +210 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +40 -9
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +121 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +447 -1
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-git-symlink-cwd.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/integration/gitignore-tracked-gsd.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/integration/worktree-e2e.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/issue-4540-regressions.test.ts +288 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/load-memory-block.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/pre-exec-gate-loop.test.ts +272 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +356 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +103 -4
- package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +388 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +9 -3
- package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +230 -0
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +205 -0
- package/src/resources/extensions/gsd/tests/save-gate-result-render.test.ts +95 -0
- package/src/resources/extensions/gsd/tests/schema-v21-sequence.test.ts +413 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +32 -40
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/token-counter.test.ts +105 -1
- package/src/resources/extensions/gsd/tests/tool-compatibility.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/validate-extension-package.test.ts +168 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +136 -8
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +25 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +65 -2
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -5
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +3 -1
- package/src/resources/extensions/gsd/token-counter.ts +22 -5
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +15 -9
- package/src/resources/extensions/gsd/tools/exec-search-tool.ts +81 -0
- package/src/resources/extensions/gsd/tools/exec-tool.ts +183 -0
- package/src/resources/extensions/gsd/tools/memory-tools.ts +31 -1
- package/src/resources/extensions/gsd/tools/resume-tool.ts +40 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +26 -3
- package/src/resources/extensions/gsd/workflow-logger.ts +4 -1
- package/src/resources/extensions/gsd/workflow-mcp.ts +3 -0
- package/src/resources/extensions/gsd/workflow-templates/spike.md +6 -0
- package/src/resources/extensions/gsd/worktree-resolver.ts +54 -9
- package/src/resources/extensions/search-the-web/command-search-provider.ts +5 -4
- package/src/resources/extensions/search-the-web/native-search.ts +48 -12
- package/src/resources/extensions/shared/cmux-events.ts +59 -0
- package/src/resources/extensions/shared/rtk-session-stats.ts +1 -2
- package/src/resources/skills/api-design/SKILL.md +190 -0
- package/src/resources/skills/create-mcp-server/SKILL.md +121 -0
- package/src/resources/skills/decompose-into-slices/SKILL.md +139 -0
- package/src/resources/skills/dependency-upgrade/SKILL.md +158 -0
- package/src/resources/skills/design-an-interface/SKILL.md +102 -0
- package/src/resources/skills/forensics/SKILL.md +153 -0
- package/src/resources/skills/grill-me/SKILL.md +93 -0
- package/src/resources/skills/handoff/SKILL.md +121 -0
- package/src/resources/skills/observability/SKILL.md +174 -0
- package/src/resources/skills/security-review/SKILL.md +181 -0
- package/src/resources/skills/spike-wrap-up/SKILL.md +138 -0
- package/src/resources/skills/tdd/SKILL.md +112 -0
- package/src/resources/skills/verify-before-complete/SKILL.md +98 -0
- package/src/resources/skills/write-docs/SKILL.md +82 -0
- package/src/resources/skills/write-milestone-brief/SKILL.md +135 -0
- package/dist/web/standalone/.next/static/chunks/2826.e59e8578e2e28639.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.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/{ssX7BLv3Dw9Fb4CtrCGeR → H51SzzS_EEgdBsDVhrLBv}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{ssX7BLv3Dw9Fb4CtrCGeR → H51SzzS_EEgdBsDVhrLBv}/_ssgManifest.js +0 -0
|
@@ -1,379 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Google Search Extension
|
|
3
|
-
*
|
|
4
|
-
* Provides a `google_search` tool that performs web searches via Gemini's
|
|
5
|
-
* Google Search grounding feature. Uses the user's existing GEMINI_API_KEY
|
|
6
|
-
* and Google Cloud GenAI credits.
|
|
7
|
-
*
|
|
8
|
-
* The tool sends queries to Gemini Flash with `googleSearch: {}` enabled.
|
|
9
|
-
* Gemini internally performs Google searches, synthesizes an answer, and
|
|
10
|
-
* returns it with source URLs from grounding metadata.
|
|
11
|
-
*/
|
|
12
|
-
import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateHead, } from "@gsd/pi-coding-agent";
|
|
13
|
-
import { Text } from "@gsd/pi-tui";
|
|
14
|
-
import { Type } from "@sinclair/typebox";
|
|
15
|
-
let client = null;
|
|
16
|
-
async function getClient() {
|
|
17
|
-
if (!client) {
|
|
18
|
-
const { GoogleGenAI } = await import("@google/genai");
|
|
19
|
-
client = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
|
|
20
|
-
}
|
|
21
|
-
return client;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Perform a search using OAuth credentials via the Cloud Code Assist API.
|
|
25
|
-
* This is used as a fallback when GEMINI_API_KEY is not set.
|
|
26
|
-
*/
|
|
27
|
-
async function searchWithOAuth(query, accessToken, projectId, signal) {
|
|
28
|
-
const model = process.env.GEMINI_SEARCH_MODEL || "gemini-2.5-flash";
|
|
29
|
-
const url = `https://cloudcode-pa.googleapis.com/v1internal:streamGenerateContent?alt=sse`;
|
|
30
|
-
const GEMINI_CLI_HEADERS = {
|
|
31
|
-
ideType: "IDE_UNSPECIFIED",
|
|
32
|
-
platform: "PLATFORM_UNSPECIFIED",
|
|
33
|
-
pluginType: "GEMINI",
|
|
34
|
-
};
|
|
35
|
-
const executeFetch = async (retries = 3) => {
|
|
36
|
-
const response = await fetch(url, {
|
|
37
|
-
method: "POST",
|
|
38
|
-
headers: {
|
|
39
|
-
Authorization: `Bearer ${accessToken}`,
|
|
40
|
-
"Content-Type": "application/json",
|
|
41
|
-
"User-Agent": "google-cloud-sdk vscode_cloudshelleditor/0.1",
|
|
42
|
-
"X-Goog-Api-Client": "gl-node/22.17.0",
|
|
43
|
-
"Client-Metadata": JSON.stringify(GEMINI_CLI_HEADERS),
|
|
44
|
-
},
|
|
45
|
-
body: JSON.stringify({
|
|
46
|
-
project: projectId,
|
|
47
|
-
model,
|
|
48
|
-
request: {
|
|
49
|
-
contents: [{ parts: [{ text: query }] }],
|
|
50
|
-
tools: [{ googleSearch: {} }],
|
|
51
|
-
},
|
|
52
|
-
userAgent: "pi-coding-agent",
|
|
53
|
-
}),
|
|
54
|
-
signal,
|
|
55
|
-
});
|
|
56
|
-
if (!response.ok && retries > 0 && (response.status === 429 || response.status >= 500)) {
|
|
57
|
-
await new Promise((resolve) => setTimeout(resolve, 1000 * (4 - retries)));
|
|
58
|
-
return executeFetch(retries - 1);
|
|
59
|
-
}
|
|
60
|
-
return response;
|
|
61
|
-
};
|
|
62
|
-
const response = await executeFetch();
|
|
63
|
-
if (!response.ok) {
|
|
64
|
-
const errorText = await response.text();
|
|
65
|
-
throw new Error(`Cloud Code Assist API error (${response.status}): ${errorText}`);
|
|
66
|
-
}
|
|
67
|
-
// Note: streamGenerateContent returns SSE; for now, we consume all chunks.
|
|
68
|
-
// For simplicity and to match the previous structure, we'll read to end.
|
|
69
|
-
const text = await response.text();
|
|
70
|
-
const jsonLines = text.split("\n")
|
|
71
|
-
.filter(l => l.startsWith("data:"))
|
|
72
|
-
.map(l => l.slice(5).trim())
|
|
73
|
-
.filter(l => l.length > 0);
|
|
74
|
-
let data;
|
|
75
|
-
if (jsonLines.length > 0) {
|
|
76
|
-
// Aggregate chunks if needed, but for now we take the last chunk or assume it's one
|
|
77
|
-
data = JSON.parse(jsonLines[jsonLines.length - 1]);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
data = JSON.parse(text);
|
|
81
|
-
}
|
|
82
|
-
const candidate = data.response?.candidates?.[0];
|
|
83
|
-
const answer = candidate?.content?.parts?.find((p) => p.text)?.text ?? "";
|
|
84
|
-
const grounding = candidate?.groundingMetadata;
|
|
85
|
-
const sources = [];
|
|
86
|
-
const seenTitles = new Set();
|
|
87
|
-
if (grounding?.groundingChunks) {
|
|
88
|
-
for (const chunk of grounding.groundingChunks) {
|
|
89
|
-
if (chunk.web) {
|
|
90
|
-
const title = chunk.web.title ?? "Untitled";
|
|
91
|
-
if (seenTitles.has(title))
|
|
92
|
-
continue;
|
|
93
|
-
seenTitles.add(title);
|
|
94
|
-
const domain = chunk.web.domain ?? title;
|
|
95
|
-
sources.push({
|
|
96
|
-
title,
|
|
97
|
-
uri: chunk.web.uri ?? "",
|
|
98
|
-
domain,
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
const searchQueries = grounding?.webSearchQueries ?? [];
|
|
104
|
-
return { answer, sources, searchQueries, cached: false };
|
|
105
|
-
}
|
|
106
|
-
// ── In-session cache ─────────────────────────────────────────────────────────
|
|
107
|
-
const resultCache = new Map();
|
|
108
|
-
function cacheKey(query) {
|
|
109
|
-
return query.toLowerCase().trim();
|
|
110
|
-
}
|
|
111
|
-
// ── Extension ────────────────────────────────────────────────────────────────
|
|
112
1
|
export default function (pi) {
|
|
113
|
-
pi.registerTool({
|
|
114
|
-
name: "google_search",
|
|
115
|
-
label: "Google Search",
|
|
116
|
-
description: "Search the web using Google Search via Gemini. " +
|
|
117
|
-
"Returns an AI-synthesized answer grounded in Google Search results, plus source URLs. " +
|
|
118
|
-
"Use this when you need current information from the web: recent events, documentation, " +
|
|
119
|
-
"product details, technical references, news, etc. " +
|
|
120
|
-
"Requires GEMINI_API_KEY or Google login. Alternative to Brave-based search tools.",
|
|
121
|
-
promptSnippet: "Search the web via Google Search to get current information with sources",
|
|
122
|
-
promptGuidelines: [
|
|
123
|
-
"Use google_search when you need up-to-date web information that isn't in your training data.",
|
|
124
|
-
"Be specific with queries for better results, e.g. 'Next.js 15 app router migration guide' not just 'Next.js'.",
|
|
125
|
-
"The tool returns both an answer and source URLs. Cite sources when sharing results with the user.",
|
|
126
|
-
"Results are cached per-session, so repeated identical queries are free.",
|
|
127
|
-
"You can still use fetch_page to read a specific URL if needed after getting results from google_search.",
|
|
128
|
-
],
|
|
129
|
-
parameters: Type.Object({
|
|
130
|
-
query: Type.String({
|
|
131
|
-
description: "The search query, e.g. 'latest Node.js LTS version' or 'how to configure Tailwind v4'",
|
|
132
|
-
}),
|
|
133
|
-
maxSources: Type.Optional(Type.Number({
|
|
134
|
-
description: "Maximum number of source URLs to include (default 5, max 10).",
|
|
135
|
-
minimum: 1,
|
|
136
|
-
maximum: 10,
|
|
137
|
-
})),
|
|
138
|
-
}),
|
|
139
|
-
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
140
|
-
const startTime = Date.now();
|
|
141
|
-
const maxSources = Math.min(Math.max(params.maxSources ?? 5, 1), 10);
|
|
142
|
-
// Check for credentials
|
|
143
|
-
let oauthToken;
|
|
144
|
-
let projectId;
|
|
145
|
-
if (!process.env.GEMINI_API_KEY) {
|
|
146
|
-
const oauthRaw = await ctx.modelRegistry.getApiKeyForProvider("google-gemini-cli");
|
|
147
|
-
if (oauthRaw) {
|
|
148
|
-
try {
|
|
149
|
-
const parsed = JSON.parse(oauthRaw);
|
|
150
|
-
oauthToken = parsed.token;
|
|
151
|
-
projectId = parsed.projectId;
|
|
152
|
-
}
|
|
153
|
-
catch {
|
|
154
|
-
// Fall through to error
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
if (!process.env.GEMINI_API_KEY && (!oauthToken || !projectId)) {
|
|
159
|
-
return {
|
|
160
|
-
content: [
|
|
161
|
-
{
|
|
162
|
-
type: "text",
|
|
163
|
-
text: "Error: No authentication found for Google Search. Please set GEMINI_API_KEY or log in via Google.\n\nExample: export GEMINI_API_KEY=your_key or use /login google",
|
|
164
|
-
},
|
|
165
|
-
],
|
|
166
|
-
isError: true,
|
|
167
|
-
details: {
|
|
168
|
-
query: params.query,
|
|
169
|
-
sourceCount: 0,
|
|
170
|
-
cached: false,
|
|
171
|
-
durationMs: Date.now() - startTime,
|
|
172
|
-
error: "auth_error: No credentials set",
|
|
173
|
-
},
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
// Check cache
|
|
177
|
-
const key = cacheKey(params.query);
|
|
178
|
-
if (resultCache.has(key)) {
|
|
179
|
-
const cached = resultCache.get(key);
|
|
180
|
-
const output = formatOutput(cached, maxSources);
|
|
181
|
-
return {
|
|
182
|
-
content: [{ type: "text", text: output }],
|
|
183
|
-
details: {
|
|
184
|
-
query: params.query,
|
|
185
|
-
sourceCount: cached.sources.length,
|
|
186
|
-
cached: true,
|
|
187
|
-
durationMs: Date.now() - startTime,
|
|
188
|
-
},
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
// Call Gemini with Google Search grounding
|
|
192
|
-
let result;
|
|
193
|
-
try {
|
|
194
|
-
if (process.env.GEMINI_API_KEY) {
|
|
195
|
-
const ai = await getClient();
|
|
196
|
-
// Add a 30-second timeout to prevent hanging (#1100)
|
|
197
|
-
const timeoutController = new AbortController();
|
|
198
|
-
const timeoutId = setTimeout(() => timeoutController.abort(), 30_000);
|
|
199
|
-
const combinedSignal = signal
|
|
200
|
-
? AbortSignal.any([signal, timeoutController.signal])
|
|
201
|
-
: timeoutController.signal;
|
|
202
|
-
let response;
|
|
203
|
-
try {
|
|
204
|
-
response = await ai.models.generateContent({
|
|
205
|
-
model: process.env.GEMINI_SEARCH_MODEL || "gemini-2.5-flash",
|
|
206
|
-
contents: params.query,
|
|
207
|
-
config: {
|
|
208
|
-
tools: [{ googleSearch: {} }],
|
|
209
|
-
abortSignal: combinedSignal,
|
|
210
|
-
},
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
finally {
|
|
214
|
-
clearTimeout(timeoutId);
|
|
215
|
-
}
|
|
216
|
-
// Extract answer text
|
|
217
|
-
const answer = response.text ?? "";
|
|
218
|
-
// Extract grounding metadata
|
|
219
|
-
const candidate = response.candidates?.[0];
|
|
220
|
-
const grounding = candidate?.groundingMetadata;
|
|
221
|
-
// Parse sources from grounding chunks
|
|
222
|
-
const sources = [];
|
|
223
|
-
const seenTitles = new Set();
|
|
224
|
-
if (grounding?.groundingChunks) {
|
|
225
|
-
for (const chunk of grounding.groundingChunks) {
|
|
226
|
-
if (chunk.web) {
|
|
227
|
-
const title = chunk.web.title ?? "Untitled";
|
|
228
|
-
// Dedupe by title since URIs are redirect URLs that differ per call
|
|
229
|
-
if (seenTitles.has(title))
|
|
230
|
-
continue;
|
|
231
|
-
seenTitles.add(title);
|
|
232
|
-
// domain field is not available via Gemini API, use title as fallback
|
|
233
|
-
// (title is typically the domain name, e.g. "wikipedia.org")
|
|
234
|
-
const domain = chunk.web.domain ?? title;
|
|
235
|
-
sources.push({
|
|
236
|
-
title,
|
|
237
|
-
uri: chunk.web.uri ?? "",
|
|
238
|
-
domain,
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
// Extract search queries Gemini actually performed
|
|
244
|
-
const searchQueries = grounding?.webSearchQueries ?? [];
|
|
245
|
-
result = { answer, sources, searchQueries, cached: false };
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
result = await searchWithOAuth(params.query, oauthToken, projectId, signal);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
catch (err) {
|
|
252
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
253
|
-
let errorType = "api_error";
|
|
254
|
-
if (msg.includes("401") || msg.includes("UNAUTHENTICATED")) {
|
|
255
|
-
errorType = "auth_error";
|
|
256
|
-
}
|
|
257
|
-
else if (msg.includes("429") || msg.includes("RESOURCE_EXHAUSTED") || msg.includes("quota")) {
|
|
258
|
-
errorType = "rate_limit";
|
|
259
|
-
}
|
|
260
|
-
return {
|
|
261
|
-
content: [
|
|
262
|
-
{
|
|
263
|
-
type: "text",
|
|
264
|
-
text: `Google Search failed (${errorType}): ${msg}`,
|
|
265
|
-
},
|
|
266
|
-
],
|
|
267
|
-
isError: true,
|
|
268
|
-
details: {
|
|
269
|
-
query: params.query,
|
|
270
|
-
sourceCount: 0,
|
|
271
|
-
cached: false,
|
|
272
|
-
durationMs: Date.now() - startTime,
|
|
273
|
-
error: `${errorType}: ${msg}`,
|
|
274
|
-
},
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
// Cache the result
|
|
278
|
-
resultCache.set(key, result);
|
|
279
|
-
// Format and truncate output
|
|
280
|
-
const rawOutput = formatOutput(result, maxSources);
|
|
281
|
-
const truncation = truncateHead(rawOutput, {
|
|
282
|
-
maxLines: DEFAULT_MAX_LINES,
|
|
283
|
-
maxBytes: DEFAULT_MAX_BYTES,
|
|
284
|
-
});
|
|
285
|
-
let finalText = truncation.content;
|
|
286
|
-
if (truncation.truncated) {
|
|
287
|
-
finalText +=
|
|
288
|
-
`\n\n[Truncated: showing ${truncation.outputLines}/${truncation.totalLines} lines` +
|
|
289
|
-
` (${formatSize(truncation.outputBytes)} of ${formatSize(truncation.totalBytes)})]`;
|
|
290
|
-
}
|
|
291
|
-
return {
|
|
292
|
-
content: [{ type: "text", text: finalText }],
|
|
293
|
-
details: {
|
|
294
|
-
query: params.query,
|
|
295
|
-
sourceCount: result.sources.length,
|
|
296
|
-
cached: false,
|
|
297
|
-
durationMs: Date.now() - startTime,
|
|
298
|
-
},
|
|
299
|
-
};
|
|
300
|
-
},
|
|
301
|
-
renderCall(args, theme) {
|
|
302
|
-
let text = theme.fg("toolTitle", theme.bold("google_search "));
|
|
303
|
-
text += theme.fg("accent", `"${args.query}"`);
|
|
304
|
-
return new Text(text, 0, 0);
|
|
305
|
-
},
|
|
306
|
-
renderResult(result, { isPartial, expanded }, theme) {
|
|
307
|
-
const d = result.details;
|
|
308
|
-
if (isPartial)
|
|
309
|
-
return new Text(theme.fg("warning", "Searching Google..."), 0, 0);
|
|
310
|
-
if (result.isError || d?.error) {
|
|
311
|
-
return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
|
|
312
|
-
}
|
|
313
|
-
let text = theme.fg("success", `${d?.sourceCount ?? 0} sources`);
|
|
314
|
-
text += theme.fg("dim", ` (${d?.durationMs ?? 0}ms)`);
|
|
315
|
-
if (d?.cached)
|
|
316
|
-
text += theme.fg("dim", " · cached");
|
|
317
|
-
if (expanded) {
|
|
318
|
-
const content = result.content[0];
|
|
319
|
-
if (content?.type === "text") {
|
|
320
|
-
const preview = content.text.split("\n").slice(0, 8).join("\n");
|
|
321
|
-
text += "\n\n" + theme.fg("dim", preview);
|
|
322
|
-
if (content.text.split("\n").length > 8) {
|
|
323
|
-
text += "\n" + theme.fg("muted", "...");
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
return new Text(text, 0, 0);
|
|
328
|
-
},
|
|
329
|
-
});
|
|
330
|
-
// ── Session cleanup ─────────────────────────────────────────────────────
|
|
331
|
-
pi.on("session_shutdown", async () => {
|
|
332
|
-
resultCache.clear();
|
|
333
|
-
client = null;
|
|
334
|
-
});
|
|
335
|
-
// ── Startup notification ─────────────────────────────────────────────────
|
|
336
2
|
pi.on("session_start", async (_event, ctx) => {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
const hasOAuth = await ctx.modelRegistry.authStorage.hasAuth("google-gemini-cli");
|
|
340
|
-
if (!hasOAuth) {
|
|
341
|
-
ctx.ui.notify("Google Search: No authentication set. Log in via Google or set GEMINI_API_KEY to use google_search.", "warning");
|
|
342
|
-
}
|
|
3
|
+
ctx.ui.notify("google_search has moved to @gsd-extensions/google-search. " +
|
|
4
|
+
"Install: gsd extensions install @gsd-extensions/google-search", "warning");
|
|
343
5
|
});
|
|
344
6
|
}
|
|
345
|
-
// ── Output formatting ────────────────────────────────────────────────────────
|
|
346
|
-
function formatOutput(result, maxSources) {
|
|
347
|
-
const lines = [];
|
|
348
|
-
// Answer
|
|
349
|
-
if (result.answer) {
|
|
350
|
-
lines.push(result.answer);
|
|
351
|
-
}
|
|
352
|
-
else {
|
|
353
|
-
lines.push("(No answer text returned from search)");
|
|
354
|
-
}
|
|
355
|
-
// Sources
|
|
356
|
-
if (result.sources.length > 0) {
|
|
357
|
-
lines.push("");
|
|
358
|
-
lines.push("Sources:");
|
|
359
|
-
const sourcesToShow = result.sources.slice(0, maxSources);
|
|
360
|
-
for (let i = 0; i < sourcesToShow.length; i++) {
|
|
361
|
-
const s = sourcesToShow[i];
|
|
362
|
-
lines.push(`[${i + 1}] ${s.title} - ${s.domain}`);
|
|
363
|
-
lines.push(` ${s.uri}`);
|
|
364
|
-
}
|
|
365
|
-
if (result.sources.length > maxSources) {
|
|
366
|
-
lines.push(`(${result.sources.length - maxSources} more sources omitted)`);
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
else {
|
|
370
|
-
lines.push("");
|
|
371
|
-
lines.push("(No source URLs found in grounding metadata)");
|
|
372
|
-
}
|
|
373
|
-
// Search queries
|
|
374
|
-
if (result.searchQueries.length > 0) {
|
|
375
|
-
lines.push("");
|
|
376
|
-
lines.push(`Searches performed: ${result.searchQueries.map((q) => `"${q}"`).join(", ")}`);
|
|
377
|
-
}
|
|
378
|
-
return lines.join("\n");
|
|
379
|
-
}
|
|
@@ -30,6 +30,13 @@ function stuckStatePath(basePath) {
|
|
|
30
30
|
function loadStuckState(basePath) {
|
|
31
31
|
try {
|
|
32
32
|
const data = JSON.parse(readFileSync(stuckStatePath(basePath), "utf-8"));
|
|
33
|
+
// Only load state written by a DIFFERENT process (real session restart).
|
|
34
|
+
// If the PID matches the current process, this state was written by an earlier
|
|
35
|
+
// autoLoop call in the same process (e.g., a test that completed before this
|
|
36
|
+
// one), not by a crashed session — skip it to prevent test state pollution.
|
|
37
|
+
if (data.pid === process.pid) {
|
|
38
|
+
return { recentUnits: [], stuckRecoveryAttempts: 0 };
|
|
39
|
+
}
|
|
33
40
|
return {
|
|
34
41
|
recentUnits: Array.isArray(data.recentUnits) ? data.recentUnits : [],
|
|
35
42
|
stuckRecoveryAttempts: typeof data.stuckRecoveryAttempts === "number" ? data.stuckRecoveryAttempts : 0,
|
|
@@ -45,6 +52,7 @@ function saveStuckState(basePath, state) {
|
|
|
45
52
|
const filePath = stuckStatePath(basePath);
|
|
46
53
|
mkdirSync(join(gsdRoot(basePath), "runtime"), { recursive: true });
|
|
47
54
|
writeFileSync(filePath, JSON.stringify({
|
|
55
|
+
pid: process.pid,
|
|
48
56
|
recentUnits: state.recentUnits.slice(-20), // keep last 20 entries
|
|
49
57
|
stuckRecoveryAttempts: state.stuckRecoveryAttempts,
|
|
50
58
|
updatedAt: new Date().toISOString(),
|
|
@@ -497,6 +505,7 @@ export async function autoLoop(ctx, pi, s, deps, options) {
|
|
|
497
505
|
consecutiveCooldowns = 0;
|
|
498
506
|
recentErrorMessages.length = 0;
|
|
499
507
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId, seq: nextSeq(), eventType: "iteration-end", data: { iteration } });
|
|
508
|
+
saveStuckState(s.basePath, loopState); // persist across session restarts (#4382)
|
|
500
509
|
debugLog("autoLoop", { phase: "iteration-complete", iteration });
|
|
501
510
|
finishTurn("completed");
|
|
502
511
|
}
|
|
@@ -30,7 +30,8 @@ import { isDbAvailable, getMilestoneSlices } from "../gsd-db.js";
|
|
|
30
30
|
import { ensurePlanV2Graph } from "../uok/plan-v2.js";
|
|
31
31
|
import { resolveUokFlags } from "../uok/flags.js";
|
|
32
32
|
import { UokGateRunner } from "../uok/gate-runner.js";
|
|
33
|
-
import { resetEvidence } from "../safety/evidence-collector.js";
|
|
33
|
+
import { resetEvidence, loadEvidenceFromDisk } from "../safety/evidence-collector.js";
|
|
34
|
+
import { parseUnitId } from "../unit-id.js";
|
|
34
35
|
import { createCheckpoint, cleanupCheckpoint, rollbackToCheckpoint } from "../safety/git-checkpoint.js";
|
|
35
36
|
import { resolveSafetyHarnessConfig } from "../safety/safety-harness.js";
|
|
36
37
|
import { getWorkflowTransportSupportError, getRequiredWorkflowToolsForAutoUnit, supportsStructuredQuestions, } from "../workflow-mcp.js";
|
|
@@ -47,7 +48,11 @@ export function resetSessionTimeoutState() {
|
|
|
47
48
|
* Exported for testing as _resolveReportBasePath.
|
|
48
49
|
*/
|
|
49
50
|
export function _resolveReportBasePath(s) {
|
|
50
|
-
|
|
51
|
+
// Strip /.gsd/worktrees/ suffix when basePath is itself a worktree path and
|
|
52
|
+
// originalBasePath is falsy — prevents reports landing in the worktree (#3729).
|
|
53
|
+
const resolved = s.originalBasePath || s.basePath;
|
|
54
|
+
const markerIdx = resolved.indexOf("/.gsd/worktrees/");
|
|
55
|
+
return markerIdx !== -1 ? resolved.slice(0, markerIdx) : resolved;
|
|
51
56
|
}
|
|
52
57
|
/**
|
|
53
58
|
* Resolve the authoritative project base for dispatch guards.
|
|
@@ -55,7 +60,12 @@ export function _resolveReportBasePath(s) {
|
|
|
55
60
|
* unit is running inside an auto worktree.
|
|
56
61
|
*/
|
|
57
62
|
export function _resolveDispatchGuardBasePath(s) {
|
|
58
|
-
|
|
63
|
+
// Strip /.gsd/worktrees/ suffix when basePath is itself a worktree path and
|
|
64
|
+
// originalBasePath is falsy — prevents guard checks running against the
|
|
65
|
+
// worktree instead of the project root (#3729).
|
|
66
|
+
const resolved = s.originalBasePath || s.basePath;
|
|
67
|
+
const markerIdx = resolved.indexOf("/.gsd/worktrees/");
|
|
68
|
+
return markerIdx !== -1 ? resolved.slice(0, markerIdx) : resolved;
|
|
59
69
|
}
|
|
60
70
|
const PLAN_V2_GATE_PHASES = new Set([
|
|
61
71
|
"executing",
|
|
@@ -295,7 +305,7 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
295
305
|
findings: reason,
|
|
296
306
|
milestoneId: state.activeMilestone?.id ?? undefined,
|
|
297
307
|
});
|
|
298
|
-
ctx.ui.notify(`Plan gate failed-closed: ${reason}`, "error");
|
|
308
|
+
ctx.ui.notify(`Plan gate failed-closed: ${reason}\n\nIf this keeps happening, try: /gsd doctor heal`, "error");
|
|
299
309
|
await deps.pauseAuto(ctx, pi);
|
|
300
310
|
return { action: "break", reason: "plan-v2-gate-failed" };
|
|
301
311
|
}
|
|
@@ -389,6 +399,8 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
389
399
|
loopState.recentUnits.length = 0;
|
|
390
400
|
loopState.stuckRecoveryAttempts = 0;
|
|
391
401
|
// Worktree lifecycle on milestone transition — merge current, enter next
|
|
402
|
+
// #2909: preflight — warn + stash dirty working tree before merge
|
|
403
|
+
const preflightTransition = deps.preflightCleanRoot(s.originalBasePath || s.basePath, s.currentMilestoneId, ctx.ui.notify.bind(ctx.ui));
|
|
392
404
|
try {
|
|
393
405
|
deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
|
|
394
406
|
}
|
|
@@ -405,6 +417,10 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
405
417
|
await deps.stopAuto(ctx, pi, `Merge error on milestone ${s.currentMilestoneId}: ${String(mergeErr)}`);
|
|
406
418
|
return { action: "break", reason: "merge-failed" };
|
|
407
419
|
}
|
|
420
|
+
// #2909: postflight — restore stashed changes after successful merge
|
|
421
|
+
if (preflightTransition.stashPushed) {
|
|
422
|
+
deps.postflightPopStash(s.originalBasePath || s.basePath, s.currentMilestoneId, ctx.ui.notify.bind(ctx.ui));
|
|
423
|
+
}
|
|
408
424
|
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
409
425
|
deps.invalidateAllCaches();
|
|
410
426
|
state = await deps.deriveState(s.basePath);
|
|
@@ -459,6 +475,8 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
459
475
|
if (incomplete.length === 0 && state.registry.length > 0) {
|
|
460
476
|
// All milestones complete — merge milestone branch before stopping
|
|
461
477
|
if (s.currentMilestoneId) {
|
|
478
|
+
// #2909: preflight — warn + stash dirty working tree before merge
|
|
479
|
+
const preflightAllComplete = deps.preflightCleanRoot(s.originalBasePath || s.basePath, s.currentMilestoneId, ctx.ui.notify.bind(ctx.ui));
|
|
462
480
|
try {
|
|
463
481
|
deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
|
|
464
482
|
// Prevent stopAuto from attempting the same merge (#2645)
|
|
@@ -475,6 +493,10 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
475
493
|
await deps.stopAuto(ctx, pi, `Merge error on milestone ${s.currentMilestoneId}: ${String(mergeErr)}`);
|
|
476
494
|
return { action: "break", reason: "merge-failed" };
|
|
477
495
|
}
|
|
496
|
+
// #2909: postflight — restore stashed changes after successful merge
|
|
497
|
+
if (preflightAllComplete.stashPushed) {
|
|
498
|
+
deps.postflightPopStash(s.originalBasePath || s.basePath, s.currentMilestoneId, ctx.ui.notify.bind(ctx.ui));
|
|
499
|
+
}
|
|
478
500
|
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
479
501
|
}
|
|
480
502
|
deps.sendDesktopNotification("GSD", "All milestones complete!", "success", "milestone", basename(s.originalBasePath || s.basePath));
|
|
@@ -539,6 +561,8 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
539
561
|
if (state.phase === "complete") {
|
|
540
562
|
// Milestone merge on complete (before closeout so branch state is clean)
|
|
541
563
|
if (s.currentMilestoneId) {
|
|
564
|
+
// #2909: preflight — warn + stash dirty working tree before merge
|
|
565
|
+
const preflightComplete = deps.preflightCleanRoot(s.originalBasePath || s.basePath, s.currentMilestoneId, ctx.ui.notify.bind(ctx.ui));
|
|
542
566
|
try {
|
|
543
567
|
deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
|
|
544
568
|
// Prevent stopAuto from attempting the same merge (#2645)
|
|
@@ -555,6 +579,10 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
555
579
|
await deps.stopAuto(ctx, pi, `Merge error on milestone ${s.currentMilestoneId}: ${String(mergeErr)}`);
|
|
556
580
|
return { action: "break", reason: "merge-failed" };
|
|
557
581
|
}
|
|
582
|
+
// #2909: postflight — restore stashed changes after successful merge
|
|
583
|
+
if (preflightComplete.stashPushed) {
|
|
584
|
+
deps.postflightPopStash(s.originalBasePath || s.basePath, s.currentMilestoneId, ctx.ui.notify.bind(ctx.ui));
|
|
585
|
+
}
|
|
558
586
|
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
559
587
|
}
|
|
560
588
|
deps.sendDesktopNotification("GSD", `Milestone ${mid} complete!`, "success", "milestone", basename(s.originalBasePath || s.basePath));
|
|
@@ -823,16 +851,44 @@ export async function runGuards(ic, mid) {
|
|
|
823
851
|
if (threshold) {
|
|
824
852
|
s.lastBudgetAlertLevel =
|
|
825
853
|
newBudgetAlertLevel;
|
|
826
|
-
|
|
854
|
+
// Emit Layer 2 budget_threshold event (post-plan hook recommendation).
|
|
855
|
+
// Extensions / Layer 0 shell hooks may return an action override.
|
|
856
|
+
let hookAction;
|
|
857
|
+
try {
|
|
858
|
+
const { emitBudgetThreshold } = await import("../hook-emitter.js");
|
|
859
|
+
const hookResult = await emitBudgetThreshold({
|
|
860
|
+
fraction: budgetPct,
|
|
861
|
+
spent: totalCost,
|
|
862
|
+
limit: budgetCeiling,
|
|
863
|
+
});
|
|
864
|
+
if (hookResult?.action)
|
|
865
|
+
hookAction = hookResult.action;
|
|
866
|
+
}
|
|
867
|
+
catch (hookErr) {
|
|
868
|
+
logWarning("engine", `budget_threshold hook emission failed: ${hookErr.message}`);
|
|
869
|
+
}
|
|
870
|
+
// Apply hook override to enforcement action. "continue" → "none" (no enforcement),
|
|
871
|
+
// "pause" and "downgrade" map to the matching enforcement path below.
|
|
872
|
+
let effectiveAction = budgetEnforcementAction;
|
|
873
|
+
if (hookAction === "continue") {
|
|
874
|
+
effectiveAction = "none";
|
|
875
|
+
}
|
|
876
|
+
else if (hookAction === "pause") {
|
|
877
|
+
effectiveAction = "pause";
|
|
878
|
+
}
|
|
879
|
+
else if (hookAction === "downgrade") {
|
|
880
|
+
effectiveAction = "warn";
|
|
881
|
+
}
|
|
882
|
+
if (threshold.pct === 100 && effectiveAction !== "none") {
|
|
827
883
|
// 100% — special enforcement logic (halt/pause/warn)
|
|
828
884
|
const msg = `Budget ceiling ${deps.formatCost(budgetCeiling)} reached (spent ${deps.formatCost(totalCost)}).`;
|
|
829
|
-
if (
|
|
885
|
+
if (effectiveAction === "halt") {
|
|
830
886
|
deps.sendDesktopNotification("GSD", msg, "error", "budget", basename(s.originalBasePath || s.basePath));
|
|
831
887
|
await deps.stopAuto(ctx, pi, "Budget ceiling reached");
|
|
832
888
|
debugLog("autoLoop", { phase: "exit", reason: "budget-halt" });
|
|
833
889
|
return { action: "break", reason: "budget-halt" };
|
|
834
890
|
}
|
|
835
|
-
if (
|
|
891
|
+
if (effectiveAction === "pause") {
|
|
836
892
|
ctx.ui.notify(`${msg} Pausing auto-mode — /gsd auto to override and continue.`, "warning");
|
|
837
893
|
deps.sendDesktopNotification("GSD", msg, "warning", "budget", basename(s.originalBasePath || s.basePath));
|
|
838
894
|
deps.logCmuxEvent(prefs, msg, "warning");
|
|
@@ -1000,6 +1056,14 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1000
1056
|
const safetyConfig = resolveSafetyHarnessConfig(prefs?.safety_harness);
|
|
1001
1057
|
if (safetyConfig.enabled && safetyConfig.evidence_collection) {
|
|
1002
1058
|
resetEvidence();
|
|
1059
|
+
// Restore persisted evidence so session-restart resumes don't produce
|
|
1060
|
+
// false-positive "no bash calls" warnings (Bug #4385).
|
|
1061
|
+
if (s.basePath && unitType === "execute-task") {
|
|
1062
|
+
const { milestone: eMid, slice: eSid, task: eTid } = parseUnitId(unitId);
|
|
1063
|
+
if (eMid && eSid && eTid) {
|
|
1064
|
+
loadEvidenceFromDisk(s.basePath, eMid, eSid, eTid);
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1003
1067
|
}
|
|
1004
1068
|
// Only checkpoint code-executing units (not lifecycle/planning units)
|
|
1005
1069
|
if (safetyConfig.enabled && safetyConfig.checkpoints && unitType === "execute-task") {
|
|
@@ -1066,7 +1130,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1066
1130
|
logWarning("engine", "Prompt reorder failed", { error: msg });
|
|
1067
1131
|
}
|
|
1068
1132
|
// Select and apply model (with tier escalation on retry — normal units only)
|
|
1069
|
-
const modelResult = await deps.selectAndApplyModel(ctx, pi, unitType, unitId, s.basePath, prefs, s.verbose, s.autoModeStartModel, sidecarItem ? undefined : { isRetry, previousTier }, undefined, s.manualSessionModelOverride);
|
|
1133
|
+
const modelResult = await deps.selectAndApplyModel(ctx, pi, unitType, unitId, s.basePath, prefs, s.verbose, s.autoModeStartModel, sidecarItem ? undefined : { isRetry, previousTier }, undefined, s.manualSessionModelOverride, s.autoModeStartThinkingLevel);
|
|
1070
1134
|
s.currentUnitRouting =
|
|
1071
1135
|
modelResult.routing;
|
|
1072
1136
|
s.currentUnitModel =
|
|
@@ -1079,6 +1143,9 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1079
1143
|
if (match) {
|
|
1080
1144
|
const ok = await pi.setModel(match, { persist: false });
|
|
1081
1145
|
if (ok) {
|
|
1146
|
+
if (s.autoModeStartThinkingLevel) {
|
|
1147
|
+
pi.setThinkingLevel(s.autoModeStartThinkingLevel);
|
|
1148
|
+
}
|
|
1082
1149
|
s.currentUnitModel = match;
|
|
1083
1150
|
ctx.ui.notify(`Hook model override: ${match.provider}/${match.id}`, "info");
|
|
1084
1151
|
}
|
|
@@ -1173,20 +1240,23 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1173
1240
|
}
|
|
1174
1241
|
}
|
|
1175
1242
|
if (unitResult.status === "cancelled") {
|
|
1243
|
+
const errorCategory = unitResult.errorContext?.category;
|
|
1176
1244
|
// Provider-error pause: pauseAuto already handled cleanup and scheduled
|
|
1177
1245
|
// recovery. Don't hard-stop — just break out of the loop (#2762).
|
|
1178
|
-
if (
|
|
1246
|
+
if (errorCategory === "provider") {
|
|
1179
1247
|
await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
|
|
1180
|
-
debugLog("autoLoop", { phase: "exit", reason: "provider-pause", isTransient: unitResult.errorContext
|
|
1248
|
+
debugLog("autoLoop", { phase: "exit", reason: "provider-pause", isTransient: unitResult.errorContext?.isTransient });
|
|
1181
1249
|
return { action: "break", reason: "provider-pause" };
|
|
1182
1250
|
}
|
|
1183
1251
|
// Timeout category covers two distinct scenarios:
|
|
1184
1252
|
// 1. Session creation timeout (120s) — transient, auto-resume with backoff
|
|
1185
1253
|
// 2. Unit hard timeout (30min+) — stuck agent, pause for manual review
|
|
1254
|
+
// Transient session-failed covers recoverable newSession failures and should
|
|
1255
|
+
// pause instead of hard-stopping.
|
|
1186
1256
|
// Structural errors (TypeError, is not a function) are NOT transient
|
|
1187
1257
|
// and must hard-stop to avoid infinite retry loops.
|
|
1188
1258
|
if (unitResult.errorContext?.isTransient &&
|
|
1189
|
-
|
|
1259
|
+
errorCategory === "timeout") {
|
|
1190
1260
|
const isSessionCreationTimeout = unitResult.errorContext.message?.includes("Session creation timed out");
|
|
1191
1261
|
if (isSessionCreationTimeout) {
|
|
1192
1262
|
consecutiveSessionTimeouts += 1;
|
|
@@ -1229,6 +1299,15 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1229
1299
|
await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
|
|
1230
1300
|
return { action: "break", reason: "unit-hard-timeout" };
|
|
1231
1301
|
}
|
|
1302
|
+
if (unitResult.errorContext?.isTransient &&
|
|
1303
|
+
errorCategory === "session-failed") {
|
|
1304
|
+
ctx.ui.notify(`Session creation failed transiently for ${unitType} ${unitId}: ${unitResult.errorContext?.message ?? "unknown"}. Pausing auto-mode (recoverable).`, "warning");
|
|
1305
|
+
debugLog("autoLoop", { phase: "session-start-transient-pause", unitType, unitId, category: errorCategory });
|
|
1306
|
+
await deps.pauseAuto(ctx, pi);
|
|
1307
|
+
await deps.autoCommitUnit?.(s.basePath, unitType, unitId, ctx);
|
|
1308
|
+
await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
|
|
1309
|
+
return { action: "break", reason: "session-timeout" };
|
|
1310
|
+
}
|
|
1232
1311
|
// All other cancelled states (structural errors, non-transient failures): hard stop
|
|
1233
1312
|
if (s.currentUnit) {
|
|
1234
1313
|
await deps.closeoutUnit(ctx, s.basePath, unitType, unitId, s.currentUnit.startedAt, deps.buildSnapshotOpts(unitType, unitId));
|
|
@@ -1387,6 +1466,20 @@ export async function runFinalize(ic, iterData, loopState, sidecarItem) {
|
|
|
1387
1466
|
}
|
|
1388
1467
|
else {
|
|
1389
1468
|
// s.pendingVerificationRetry was set by postUnitPreVerification.
|
|
1469
|
+
// Emit a dedicated journal event so forensics can distinguish bounded
|
|
1470
|
+
// verification retries from genuine stuck-loop dispatch repetitions (#4540).
|
|
1471
|
+
const retryInfo = s.pendingVerificationRetry;
|
|
1472
|
+
deps.emitJournalEvent({
|
|
1473
|
+
ts: new Date().toISOString(),
|
|
1474
|
+
flowId: ic.flowId,
|
|
1475
|
+
seq: ic.nextSeq(),
|
|
1476
|
+
eventType: "artifact-verification-retry",
|
|
1477
|
+
data: {
|
|
1478
|
+
unitType: preUnitSnapshot?.type,
|
|
1479
|
+
unitId: retryInfo?.unitId,
|
|
1480
|
+
attempt: retryInfo?.attempt,
|
|
1481
|
+
},
|
|
1482
|
+
});
|
|
1390
1483
|
// Continue the loop — next iteration will inject the retry context into the prompt.
|
|
1391
1484
|
debugLog("autoLoop", { phase: "artifact-verification-retry", iteration: ic.iteration });
|
|
1392
1485
|
return { action: "continue" };
|