@opengsd/gsd-pi 1.0.2-dev.e70300c → 1.0.2-dev.fb7ddf1
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 +63 -12
- package/dist/headless-answers.js +2 -1
- package/dist/headless-events.d.ts +1 -0
- package/dist/headless-events.js +8 -1
- package/dist/onboarding.js +22 -3
- package/dist/resource-loader.d.ts +7 -0
- package/dist/resource-loader.js +44 -9
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +34 -11
- package/dist/resources/extensions/context7/index.js +12 -2
- package/dist/resources/extensions/get-secrets-from-user.js +16 -16
- package/dist/resources/extensions/google-cli/index.js +30 -0
- package/dist/resources/extensions/google-cli/models.js +55 -0
- package/dist/resources/extensions/google-cli/package.json +11 -0
- package/dist/resources/extensions/google-cli/readiness.js +12 -0
- package/dist/resources/extensions/google-cli/stream-adapter.js +191 -0
- package/dist/resources/extensions/gsd/auto/loop.js +81 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -2
- package/dist/resources/extensions/gsd/auto/phases.js +38 -1
- package/dist/resources/extensions/gsd/auto/run-unit.js +8 -0
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +17 -7
- package/dist/resources/extensions/gsd/auto-post-unit.js +65 -16
- package/dist/resources/extensions/gsd/auto-prompts.js +5 -236
- package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
- package/dist/resources/extensions/gsd/auto-start.js +232 -49
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -1
- package/dist/resources/extensions/gsd/auto-verification.js +14 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +34 -1
- package/dist/resources/extensions/gsd/auto.js +40 -2
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +4 -3
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -2
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +39 -5
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +107 -27
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +3 -27
- package/dist/resources/extensions/gsd/bootstrap/tool-search-shim.js +4 -4
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +1 -1
- package/dist/resources/extensions/gsd/closeout-recovery.js +7 -1
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +9 -1
- package/dist/resources/extensions/gsd/commands-handlers.js +3 -0
- package/dist/resources/extensions/gsd/commands-usage.js +105 -1
- package/dist/resources/extensions/gsd/config-overlay.js +20 -14
- package/dist/resources/extensions/gsd/context-overlay.js +22 -16
- package/dist/resources/extensions/gsd/dashboard-overlay.js +10 -23
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +87 -0
- package/dist/resources/extensions/gsd/doctor-git-checks.js +70 -5
- package/dist/resources/extensions/gsd/doctor-providers.js +54 -24
- package/dist/resources/extensions/gsd/doctor.js +7 -2
- package/dist/resources/extensions/gsd/git-conflict-state.js +26 -1
- package/dist/resources/extensions/gsd/guided-flow.js +5 -6
- package/dist/resources/extensions/gsd/key-manager.js +45 -13
- package/dist/resources/extensions/gsd/mcp-filter.js +57 -18
- package/dist/resources/extensions/gsd/mcp-project-config.js +15 -9
- package/dist/resources/extensions/gsd/migration-auto-check.js +5 -1
- package/dist/resources/extensions/gsd/milestone-actions.js +3 -0
- package/dist/resources/extensions/gsd/milestone-reopen-events.js +28 -0
- package/dist/resources/extensions/gsd/notification-overlay.js +8 -9
- package/dist/resources/extensions/gsd/parallel-merge.js +6 -4
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +15 -13
- package/dist/resources/extensions/gsd/post-execution-checks.js +5 -4
- package/dist/resources/extensions/gsd/preferences-skills.js +11 -4
- package/dist/resources/extensions/gsd/preferences.js +14 -2
- package/dist/resources/extensions/gsd/prompt-loader.js +2 -0
- package/dist/resources/extensions/gsd/prompts/discuss.md +4 -2
- package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/system.md +3 -20
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +28 -18
- package/dist/resources/extensions/gsd/repo-identity.js +36 -6
- package/dist/resources/extensions/gsd/repository-registry.js +3 -1
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +13 -6
- package/dist/resources/extensions/gsd/skill-activation.js +233 -0
- package/dist/resources/extensions/gsd/skill-catalog.data.js +820 -0
- package/dist/resources/extensions/gsd/skill-catalog.install.js +179 -0
- package/dist/resources/extensions/gsd/skill-catalog.js +5 -1028
- package/dist/resources/extensions/gsd/skill-discovery.js +121 -79
- package/dist/resources/extensions/gsd/skill-scope.js +52 -0
- package/dist/resources/extensions/gsd/skill-telemetry.js +6 -39
- package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +1 -1
- package/dist/resources/extensions/gsd/skills.js +60 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +351 -0
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +41 -0
- package/dist/resources/extensions/gsd/state-reconciliation/registry.js +4 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +9 -0
- package/dist/resources/extensions/gsd/tools/exec-tool.js +42 -8
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +63 -2
- package/dist/resources/extensions/gsd/tui/render-kit.js +51 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +35 -26
- package/dist/resources/extensions/gsd/user-input-boundary.js +1 -1
- package/dist/resources/extensions/gsd/vision-ask.js +22 -0
- package/dist/resources/extensions/gsd/visualizer-overlay.js +8 -36
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -3
- package/dist/resources/extensions/gsd/worktree-state-projection.js +29 -0
- package/dist/resources/extensions/search-the-web/native-search.js +57 -8
- package/dist/resources/extensions/shared/confirm-ui.js +9 -6
- package/dist/resources/extensions/shared/dialog-frame.js +42 -0
- package/dist/resources/extensions/shared/interview-ui.js +42 -30
- package/dist/resources/extensions/shared/next-action-ui.js +6 -6
- package/dist/resources/extensions/subagent/index.js +8 -15
- package/dist/resources/shared/package-manager-detection.js +36 -0
- package/dist/resources/skills/agent-browser/SKILL.md +1 -1
- package/dist/resources/skills/api-design/SKILL.md +1 -1
- package/dist/resources/skills/code-optimizer/SKILL.md +6 -11
- package/dist/resources/skills/create-gsd-extension/SKILL.md +1 -1
- package/dist/resources/skills/create-mcp-server/SKILL.md +1 -1
- package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
- package/dist/resources/skills/create-skill/workflows/verify-skill.md +2 -10
- package/dist/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
- package/dist/resources/skills/decompose-into-slices/SKILL.md +3 -3
- package/dist/resources/skills/dependency-upgrade/SKILL.md +1 -1
- package/dist/resources/skills/forensics/SKILL.md +2 -2
- package/dist/resources/skills/grill-me/SKILL.md +1 -1
- package/dist/resources/skills/handoff/SKILL.md +1 -1
- package/dist/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
- package/dist/resources/skills/observability/SKILL.md +1 -1
- package/dist/resources/skills/security-review/SKILL.md +1 -1
- package/dist/resources/skills/spike-wrap-up/SKILL.md +1 -1
- package/dist/resources/skills/tdd/SKILL.md +1 -1
- package/dist/resources/skills/write-docs/SKILL.md +1 -1
- package/dist/resources/skills/write-milestone-brief/SKILL.md +1 -1
- package/dist/update-check.d.ts +6 -2
- package/dist/update-check.js +7 -3
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
- package/dist/web/standalone/.next/server/chunks/1834.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/package.json +5 -2
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/rpc.test.js +5 -0
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +15 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +16 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/dist/workflow.test.js +1 -0
- package/packages/contracts/dist/workflow.test.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +1 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +22 -8
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts +12 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js +45 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts +3 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js +11 -11
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts +3 -3
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js +13 -11
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts +3 -3
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js +12 -10
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js +2 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts +6 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js +9 -6
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +0 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +2 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts +3 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +144 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js +2 -14
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +7 -1
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +13 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +47 -8
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +16 -14
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/harness/skills.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/skills.js +6 -0
- package/packages/pi-agent-core/dist/harness/skills.js.map +1 -1
- package/packages/pi-agent-core/dist/harness/system-prompt.d.ts +7 -0
- package/packages/pi-agent-core/dist/harness/system-prompt.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/system-prompt.js +7 -0
- package/packages/pi-agent-core/dist/harness/system-prompt.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +48 -206
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +67 -220
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +50 -0
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses-shared.js +28 -4
- package/packages/pi-ai/dist/providers/openai-responses-shared.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +2 -0
- 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/tests/tool-search-shim.test.js +29 -1
- package/packages/pi-ai/dist/utils/tests/tool-search-shim.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/tool-search-shim.d.ts +4 -1
- package/packages/pi-ai/dist/utils/tool-search-shim.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/tool-search-shim.js +58 -10
- package/packages/pi-ai/dist/utils/tool-search-shim.js.map +1 -1
- package/packages/pi-ai/dist/utils/tool-shims.d.ts +1 -1
- package/packages/pi-ai/dist/utils/tool-shims.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/tool-shims.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/README.md +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +8 -2
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +3 -0
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js +5 -7
- package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js +5 -4
- package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js +0 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
- package/packages/pi-coding-agent/package.json +8 -8
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/scripts/install/detect-existing.js +17 -3
- package/scripts/install/npm-global.js +103 -33
- package/scripts/install.js +1 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +36 -11
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +86 -19
- package/src/resources/extensions/context7/index.ts +15 -2
- package/src/resources/extensions/get-secrets-from-user.ts +17 -16
- package/src/resources/extensions/google-cli/index.ts +34 -0
- package/src/resources/extensions/google-cli/models.ts +57 -0
- package/src/resources/extensions/google-cli/package.json +11 -0
- package/src/resources/extensions/google-cli/readiness.ts +15 -0
- package/src/resources/extensions/google-cli/stream-adapter.ts +245 -0
- package/src/resources/extensions/gsd/auto/loop.ts +96 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -2
- package/src/resources/extensions/gsd/auto/phases.ts +47 -1
- package/src/resources/extensions/gsd/auto/run-unit.ts +10 -0
- package/src/resources/extensions/gsd/auto/session.ts +3 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +31 -11
- package/src/resources/extensions/gsd/auto-post-unit.ts +101 -18
- package/src/resources/extensions/gsd/auto-prompts.ts +4 -284
- package/src/resources/extensions/gsd/auto-recovery.ts +10 -7
- package/src/resources/extensions/gsd/auto-start.ts +307 -56
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +3 -1
- package/src/resources/extensions/gsd/auto-verification.ts +18 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +45 -1
- package/src/resources/extensions/gsd/auto.ts +50 -2
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +4 -3
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +9 -4
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +42 -5
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +124 -25
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +3 -28
- package/src/resources/extensions/gsd/bootstrap/tool-search-shim.ts +4 -4
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +1 -1
- package/src/resources/extensions/gsd/closeout-recovery.ts +6 -1
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -1
- package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
- package/src/resources/extensions/gsd/commands-usage.ts +110 -5
- package/src/resources/extensions/gsd/config-overlay.ts +19 -16
- package/src/resources/extensions/gsd/context-overlay.ts +24 -19
- package/src/resources/extensions/gsd/dashboard-overlay.ts +14 -27
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +99 -0
- package/src/resources/extensions/gsd/doctor-git-checks.ts +72 -5
- package/src/resources/extensions/gsd/doctor-providers.ts +55 -27
- package/src/resources/extensions/gsd/doctor-types.ts +2 -0
- package/src/resources/extensions/gsd/doctor.ts +7 -2
- package/src/resources/extensions/gsd/git-conflict-state.ts +25 -1
- package/src/resources/extensions/gsd/guided-flow.ts +5 -6
- package/src/resources/extensions/gsd/key-manager.ts +57 -14
- package/src/resources/extensions/gsd/mcp-filter.ts +64 -17
- package/src/resources/extensions/gsd/mcp-project-config.ts +24 -9
- package/src/resources/extensions/gsd/migration-auto-check.ts +6 -0
- package/src/resources/extensions/gsd/milestone-actions.ts +2 -0
- package/src/resources/extensions/gsd/milestone-reopen-events.ts +28 -0
- package/src/resources/extensions/gsd/notification-overlay.ts +12 -11
- package/src/resources/extensions/gsd/parallel-merge.ts +6 -4
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +16 -12
- package/src/resources/extensions/gsd/post-execution-checks.ts +7 -4
- package/src/resources/extensions/gsd/preferences-skills.ts +11 -4
- package/src/resources/extensions/gsd/preferences.ts +17 -2
- package/src/resources/extensions/gsd/prompt-loader.ts +2 -0
- package/src/resources/extensions/gsd/prompts/discuss.md +4 -2
- package/src/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/system.md +3 -20
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +29 -20
- package/src/resources/extensions/gsd/repo-identity.ts +35 -7
- package/src/resources/extensions/gsd/repository-registry.ts +3 -1
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +13 -6
- package/src/resources/extensions/gsd/skill-activation.ts +292 -0
- package/src/resources/extensions/gsd/skill-catalog.data.ts +858 -0
- package/src/resources/extensions/gsd/skill-catalog.install.ts +205 -0
- package/src/resources/extensions/gsd/skill-catalog.ts +16 -1087
- package/src/resources/extensions/gsd/skill-discovery.ts +134 -78
- package/src/resources/extensions/gsd/skill-scope.ts +63 -0
- package/src/resources/extensions/gsd/skill-telemetry.ts +6 -40
- package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +1 -1
- package/src/resources/extensions/gsd/skills.ts +75 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +499 -0
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +40 -0
- package/src/resources/extensions/gsd/state-reconciliation/registry.ts +8 -0
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +30 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +328 -2
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +28 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +436 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/closeout-recovery.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/commands-context.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +15 -2
- package/src/resources/extensions/gsd/tests/commands-usage.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +40 -3
- package/src/resources/extensions/gsd/tests/context-chart.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/discuss-prompt.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +71 -1
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +101 -1
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +22 -3
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +43 -0
- package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +23 -4
- package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +19 -1
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +56 -1
- package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +70 -10
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +127 -10
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/register-extension-guard.test.ts +116 -11
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +30 -1
- package/src/resources/extensions/gsd/tests/show-config-command.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +111 -0
- package/src/resources/extensions/gsd/tests/skill-scope-auto.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/skills.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +13 -2
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +303 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +67 -1
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +24 -1
- package/src/resources/extensions/gsd/tests/tui-border-assertions.ts +28 -0
- package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/vision-ask.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +16 -1
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +45 -1
- package/src/resources/extensions/gsd/tools/complete-task.ts +9 -0
- package/src/resources/extensions/gsd/tools/exec-tool.ts +42 -10
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +82 -5
- package/src/resources/extensions/gsd/tui/render-kit.ts +82 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +37 -26
- package/src/resources/extensions/gsd/user-input-boundary.ts +1 -1
- package/src/resources/extensions/gsd/vision-ask.ts +28 -0
- package/src/resources/extensions/gsd/visualizer-overlay.ts +12 -40
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +37 -2
- package/src/resources/extensions/gsd/worktree-state-projection.ts +33 -0
- package/src/resources/extensions/search-the-web/native-search.ts +60 -8
- package/src/resources/extensions/shared/confirm-ui.ts +8 -12
- package/src/resources/extensions/shared/dialog-frame.ts +71 -0
- package/src/resources/extensions/shared/interview-ui.ts +43 -42
- package/src/resources/extensions/shared/next-action-ui.ts +6 -6
- package/src/resources/extensions/shared/tests/confirm-ui.test.ts +57 -0
- package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +163 -0
- package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +55 -0
- package/src/resources/extensions/subagent/index.ts +8 -15
- package/src/resources/shared/package-manager-detection.ts +39 -0
- package/src/resources/skills/agent-browser/SKILL.md +1 -1
- package/src/resources/skills/api-design/SKILL.md +1 -1
- package/src/resources/skills/code-optimizer/SKILL.md +6 -11
- package/src/resources/skills/create-gsd-extension/SKILL.md +1 -1
- package/src/resources/skills/create-mcp-server/SKILL.md +1 -1
- package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
- package/src/resources/skills/create-skill/workflows/verify-skill.md +2 -10
- package/src/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
- package/src/resources/skills/decompose-into-slices/SKILL.md +3 -3
- package/src/resources/skills/dependency-upgrade/SKILL.md +1 -1
- package/src/resources/skills/forensics/SKILL.md +2 -2
- package/src/resources/skills/grill-me/SKILL.md +1 -1
- package/src/resources/skills/handoff/SKILL.md +1 -1
- package/src/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
- package/src/resources/skills/observability/SKILL.md +1 -1
- package/src/resources/skills/security-review/SKILL.md +1 -1
- package/src/resources/skills/spike-wrap-up/SKILL.md +1 -1
- package/src/resources/skills/tdd/SKILL.md +1 -1
- package/src/resources/skills/write-docs/SKILL.md +1 -1
- package/src/resources/skills/write-milestone-brief/SKILL.md +1 -1
- /package/dist/web/standalone/.next/static/{szb-HAt0IoSx3docUZO-E → tH1tnDYt1E0hK9Ien73Z0}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{szb-HAt0IoSx3docUZO-E → tH1tnDYt1E0hK9Ien73Z0}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const ZERO_COST = {
|
|
2
|
+
input: 0,
|
|
3
|
+
output: 0,
|
|
4
|
+
cacheRead: 0,
|
|
5
|
+
cacheWrite: 0,
|
|
6
|
+
};
|
|
7
|
+
export const GOOGLE_GEMINI_CLI_MODELS = [
|
|
8
|
+
{
|
|
9
|
+
id: "gemini-2.5-flash",
|
|
10
|
+
name: "Gemini 2.5 Flash",
|
|
11
|
+
reasoning: true,
|
|
12
|
+
input: ["text"],
|
|
13
|
+
cost: ZERO_COST,
|
|
14
|
+
contextWindow: 1_000_000,
|
|
15
|
+
maxTokens: 65_536,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: "gemini-2.5-pro",
|
|
19
|
+
name: "Gemini 2.5 Pro",
|
|
20
|
+
reasoning: true,
|
|
21
|
+
input: ["text"],
|
|
22
|
+
cost: ZERO_COST,
|
|
23
|
+
contextWindow: 1_000_000,
|
|
24
|
+
maxTokens: 65_536,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: "gemini-3-flash-preview",
|
|
28
|
+
name: "Gemini 3 Flash Preview",
|
|
29
|
+
reasoning: true,
|
|
30
|
+
input: ["text"],
|
|
31
|
+
cost: ZERO_COST,
|
|
32
|
+
contextWindow: 1_000_000,
|
|
33
|
+
maxTokens: 65_536,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "gemini-3.1-pro-preview",
|
|
37
|
+
name: "Gemini 3.1 Pro Preview",
|
|
38
|
+
reasoning: true,
|
|
39
|
+
input: ["text"],
|
|
40
|
+
cost: ZERO_COST,
|
|
41
|
+
contextWindow: 1_000_000,
|
|
42
|
+
maxTokens: 65_536,
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
export const GOOGLE_ANTIGRAVITY_MODELS = [
|
|
46
|
+
{
|
|
47
|
+
id: "default",
|
|
48
|
+
name: "Antigravity Default",
|
|
49
|
+
reasoning: true,
|
|
50
|
+
input: ["text"],
|
|
51
|
+
cost: ZERO_COST,
|
|
52
|
+
contextWindow: 1_000_000,
|
|
53
|
+
maxTokens: 65_536,
|
|
54
|
+
},
|
|
55
|
+
];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
function isCommandInPath(command) {
|
|
3
|
+
const resolver = process.platform === "win32" ? "where" : "which";
|
|
4
|
+
const result = spawnSync(resolver, [command], { stdio: "ignore" });
|
|
5
|
+
return result.status === 0;
|
|
6
|
+
}
|
|
7
|
+
export function isGeminiCliReady() {
|
|
8
|
+
return isCommandInPath("gemini");
|
|
9
|
+
}
|
|
10
|
+
export function isAntigravityCliReady() {
|
|
11
|
+
return isCommandInPath("agy");
|
|
12
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { createAssistantMessageEventStream } from "@gsd/pi-ai";
|
|
3
|
+
const ZERO_USAGE = {
|
|
4
|
+
input: 0,
|
|
5
|
+
output: 0,
|
|
6
|
+
cacheRead: 0,
|
|
7
|
+
cacheWrite: 0,
|
|
8
|
+
totalTokens: 0,
|
|
9
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
10
|
+
};
|
|
11
|
+
function textBlocks(content) {
|
|
12
|
+
return content
|
|
13
|
+
.map((block) => block.type === "text" ? block.text : `[${block.type} omitted]`)
|
|
14
|
+
.join("\n");
|
|
15
|
+
}
|
|
16
|
+
function messageToText(message) {
|
|
17
|
+
if (message.role === "user") {
|
|
18
|
+
const content = typeof message.content === "string" ? message.content : textBlocks(message.content);
|
|
19
|
+
return `User:\n${content}`;
|
|
20
|
+
}
|
|
21
|
+
if (message.role === "assistant") {
|
|
22
|
+
const text = message.content
|
|
23
|
+
.map((block) => {
|
|
24
|
+
if (block.type === "text")
|
|
25
|
+
return block.text;
|
|
26
|
+
if (block.type === "thinking")
|
|
27
|
+
return `[thinking omitted]`;
|
|
28
|
+
if (block.type === "toolCall")
|
|
29
|
+
return `[tool call: ${block.name}]`;
|
|
30
|
+
if (block.type === "serverToolUse")
|
|
31
|
+
return `[server tool: ${block.name}]`;
|
|
32
|
+
if (block.type === "webSearchResult")
|
|
33
|
+
return `[web search result omitted]`;
|
|
34
|
+
return `[${block.type} omitted]`;
|
|
35
|
+
})
|
|
36
|
+
.join("\n");
|
|
37
|
+
return `Assistant:\n${text}`;
|
|
38
|
+
}
|
|
39
|
+
return `Tool result (${message.toolName}):\n${textBlocks(message.content)}`;
|
|
40
|
+
}
|
|
41
|
+
export function buildGoogleCliPrompt(context) {
|
|
42
|
+
const parts = [];
|
|
43
|
+
if (context.systemPrompt?.trim()) {
|
|
44
|
+
parts.push(`System instructions:\n${context.systemPrompt.trim()}`);
|
|
45
|
+
}
|
|
46
|
+
if (context.messages.length > 0) {
|
|
47
|
+
parts.push(context.messages.map(messageToText).join("\n\n"));
|
|
48
|
+
}
|
|
49
|
+
if (context.tools?.length) {
|
|
50
|
+
const names = context.tools.map((tool) => tool.name).join(", ");
|
|
51
|
+
parts.push(`Available local GSD tools were not forwarded to this external CLI bridge. ` +
|
|
52
|
+
`If you need to act, use the CLI's own tools or ask the user to switch to a provider with native tool-call support. ` +
|
|
53
|
+
`Requested GSD tools: ${names}`);
|
|
54
|
+
}
|
|
55
|
+
return parts.join("\n\n").trim();
|
|
56
|
+
}
|
|
57
|
+
function buildAssistantMessage(model, text, stopReason = "stop", errorMessage) {
|
|
58
|
+
return {
|
|
59
|
+
role: "assistant",
|
|
60
|
+
content: text ? [{ type: "text", text }] : [],
|
|
61
|
+
api: model.api,
|
|
62
|
+
provider: model.provider,
|
|
63
|
+
model: model.id,
|
|
64
|
+
usage: { ...ZERO_USAGE, cost: { ...ZERO_USAGE.cost } },
|
|
65
|
+
stopReason,
|
|
66
|
+
...(errorMessage ? { errorMessage } : {}),
|
|
67
|
+
timestamp: Date.now(),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function extractGeminiJsonResponse(raw) {
|
|
71
|
+
const trimmed = raw.trim();
|
|
72
|
+
if (!trimmed)
|
|
73
|
+
return "";
|
|
74
|
+
try {
|
|
75
|
+
const parsed = JSON.parse(trimmed);
|
|
76
|
+
for (const key of ["response", "text", "content", "message"]) {
|
|
77
|
+
const value = parsed[key];
|
|
78
|
+
if (typeof value === "string")
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
return JSON.stringify(parsed, null, 2);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return trimmed;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function commandForProvider(provider) {
|
|
88
|
+
return provider === "google-gemini-cli" ? "gemini" : "agy";
|
|
89
|
+
}
|
|
90
|
+
function argsForProvider(provider, model, prompt) {
|
|
91
|
+
if (provider === "google-gemini-cli") {
|
|
92
|
+
const args = ["-p", prompt, "--output-format", "json"];
|
|
93
|
+
if (model.id !== "default")
|
|
94
|
+
args.unshift("-m", model.id);
|
|
95
|
+
return args;
|
|
96
|
+
}
|
|
97
|
+
const args = ["-p", prompt];
|
|
98
|
+
if (model.id !== "default")
|
|
99
|
+
args.unshift("-m", model.id);
|
|
100
|
+
return args;
|
|
101
|
+
}
|
|
102
|
+
export function buildGoogleCliSpawnInvocation(command, args, platform = process.platform) {
|
|
103
|
+
if (platform === "win32") {
|
|
104
|
+
return { command: "cmd", args: ["/c", command, ...args] };
|
|
105
|
+
}
|
|
106
|
+
return { command, args };
|
|
107
|
+
}
|
|
108
|
+
function runCli(command, args, options) {
|
|
109
|
+
return new Promise((resolve, reject) => {
|
|
110
|
+
const invocation = buildGoogleCliSpawnInvocation(command, args);
|
|
111
|
+
const child = spawn(invocation.command, invocation.args, {
|
|
112
|
+
cwd: options?.cwd || process.cwd(),
|
|
113
|
+
env: process.env,
|
|
114
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
115
|
+
});
|
|
116
|
+
let stdout = "";
|
|
117
|
+
let stderr = "";
|
|
118
|
+
let settled = false;
|
|
119
|
+
const settle = (fn) => {
|
|
120
|
+
if (settled)
|
|
121
|
+
return;
|
|
122
|
+
settled = true;
|
|
123
|
+
options?.signal?.removeEventListener("abort", onAbort);
|
|
124
|
+
fn();
|
|
125
|
+
};
|
|
126
|
+
const onAbort = () => {
|
|
127
|
+
child.kill("SIGTERM");
|
|
128
|
+
settle(() => reject(new Error("Request was aborted")));
|
|
129
|
+
};
|
|
130
|
+
if (options?.signal?.aborted) {
|
|
131
|
+
onAbort();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
options?.signal?.addEventListener("abort", onAbort);
|
|
135
|
+
child.stdout.setEncoding("utf8");
|
|
136
|
+
child.stderr.setEncoding("utf8");
|
|
137
|
+
child.stdout.on("data", (chunk) => {
|
|
138
|
+
stdout += chunk;
|
|
139
|
+
});
|
|
140
|
+
child.stderr.on("data", (chunk) => {
|
|
141
|
+
stderr += chunk;
|
|
142
|
+
});
|
|
143
|
+
child.on("error", (error) => {
|
|
144
|
+
settle(() => reject(error));
|
|
145
|
+
});
|
|
146
|
+
child.on("close", (code, signal) => {
|
|
147
|
+
settle(() => resolve({ stdout, stderr, code, signal }));
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
function emitText(stream, message, text) {
|
|
152
|
+
stream.push({ type: "start", partial: { ...message, content: [] } });
|
|
153
|
+
if (text) {
|
|
154
|
+
stream.push({ type: "text_start", contentIndex: 0, partial: message });
|
|
155
|
+
stream.push({ type: "text_delta", contentIndex: 0, delta: text, partial: message });
|
|
156
|
+
stream.push({ type: "text_end", contentIndex: 0, content: text, partial: message });
|
|
157
|
+
}
|
|
158
|
+
stream.push({ type: "done", reason: "stop", message });
|
|
159
|
+
stream.end(message);
|
|
160
|
+
}
|
|
161
|
+
function emitError(stream, model, error) {
|
|
162
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
163
|
+
const output = buildAssistantMessage(model, "", "error", message);
|
|
164
|
+
stream.push({ type: "error", reason: "error", error: output });
|
|
165
|
+
stream.end(output);
|
|
166
|
+
}
|
|
167
|
+
export function streamViaGoogleCli(model, context, options) {
|
|
168
|
+
const stream = createAssistantMessageEventStream();
|
|
169
|
+
const provider = model.provider;
|
|
170
|
+
queueMicrotask(async () => {
|
|
171
|
+
try {
|
|
172
|
+
const prompt = buildGoogleCliPrompt(context);
|
|
173
|
+
const command = commandForProvider(provider);
|
|
174
|
+
const args = argsForProvider(provider, model, prompt);
|
|
175
|
+
const result = await runCli(command, args, options);
|
|
176
|
+
if (result.code !== 0) {
|
|
177
|
+
const detail = (result.stderr || result.stdout || `CLI exited with code ${result.code}`).trim();
|
|
178
|
+
throw new Error(detail);
|
|
179
|
+
}
|
|
180
|
+
const text = provider === "google-gemini-cli"
|
|
181
|
+
? extractGeminiJsonResponse(result.stdout)
|
|
182
|
+
: result.stdout.trim();
|
|
183
|
+
const message = buildAssistantMessage(model, text);
|
|
184
|
+
emitText(stream, message, text);
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
emitError(stream, model, error);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
return stream;
|
|
191
|
+
}
|
|
@@ -50,6 +50,7 @@ import { handleCustomEngineVerifyPause, handleCustomEngineVerifyRetryOutcome, }
|
|
|
50
50
|
import { handleCustomEngineReconcile } from "./workflow-custom-engine-reconcile.js";
|
|
51
51
|
import { handleCustomEngineReconcileOutcome } from "./workflow-custom-engine-reconcile-outcome.js";
|
|
52
52
|
import { formatLeaseConflictNotice } from "./lease-conflict-notice.js";
|
|
53
|
+
import { setAutoOutcomeWidget, unitVerb } from "../auto-dashboard.js";
|
|
53
54
|
/**
|
|
54
55
|
* Returns true if workerId is an active worker in this project whose OS
|
|
55
56
|
* process no longer exists. Used to detect dead lease holders before
|
|
@@ -690,6 +691,24 @@ export async function autoLoop(ctx, pi, s, deps, options) {
|
|
|
690
691
|
});
|
|
691
692
|
if (reconcileFlow.action === "break")
|
|
692
693
|
break;
|
|
694
|
+
if (s.stepMode) {
|
|
695
|
+
if (ctx.hasUI) {
|
|
696
|
+
ctx.ui.setWidget?.("gsd-progress", undefined);
|
|
697
|
+
setAutoOutcomeWidget(ctx, {
|
|
698
|
+
status: "step",
|
|
699
|
+
title: "Step complete",
|
|
700
|
+
detail: `Completed ${unitVerb(iterData.unitType)} ${iterData.unitId}.`,
|
|
701
|
+
unitLabel: `${unitVerb(iterData.unitType)} ${iterData.unitId}`,
|
|
702
|
+
nextAction: "Advance one step, or resume automatic mode.",
|
|
703
|
+
commands: ["/gsd next", "/gsd auto", "/gsd status for overview"],
|
|
704
|
+
startedAt: s.autoStartTime,
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
ctx.ui.setStatus("gsd-auto", "next");
|
|
708
|
+
ctx.ui.notify(`Step complete: ${unitVerb(iterData.unitType)} ${iterData.unitId}. Run /gsd next for the next step, or /gsd auto to continue automatically.`, "info");
|
|
709
|
+
s.preserveStepSurfaceAfterLoopExit = true;
|
|
710
|
+
break;
|
|
711
|
+
}
|
|
693
712
|
continue;
|
|
694
713
|
}
|
|
695
714
|
if (!sidecarItem) {
|
|
@@ -713,11 +732,36 @@ export async function autoLoop(ctx, pi, s, deps, options) {
|
|
|
713
732
|
message: orchestrationResult.reason,
|
|
714
733
|
category: "unknown",
|
|
715
734
|
});
|
|
735
|
+
finishTurn("paused", "manual-attention", "orchestration-blocked");
|
|
716
736
|
}
|
|
717
737
|
else {
|
|
718
738
|
await deps.stopAuto(ctx, pi, orchestrationResult.reason);
|
|
739
|
+
finishTurn("stopped", "manual-attention", "orchestration-blocked");
|
|
719
740
|
}
|
|
720
|
-
|
|
741
|
+
finishIncompleteIteration({
|
|
742
|
+
status: orchestrationResult.action === "pause" ? "paused" : "stopped",
|
|
743
|
+
reason: orchestrationResult.reason,
|
|
744
|
+
failureClass: "manual-attention",
|
|
745
|
+
});
|
|
746
|
+
break;
|
|
747
|
+
}
|
|
748
|
+
if (orchestrationResult.kind === "paused") {
|
|
749
|
+
s.pendingOrchestrationDispatch = null;
|
|
750
|
+
finishTurn("skipped");
|
|
751
|
+
continue;
|
|
752
|
+
}
|
|
753
|
+
if (orchestrationResult.kind === "error") {
|
|
754
|
+
s.pendingOrchestrationDispatch = null;
|
|
755
|
+
await deps.pauseAuto(ctx, pi, {
|
|
756
|
+
message: orchestrationResult.reason,
|
|
757
|
+
category: "unknown",
|
|
758
|
+
});
|
|
759
|
+
finishTurn("paused", "manual-attention", `orchestration-${orchestrationResult.kind}`);
|
|
760
|
+
finishIncompleteIteration({
|
|
761
|
+
status: "paused",
|
|
762
|
+
reason: orchestrationResult.reason,
|
|
763
|
+
failureClass: "manual-attention",
|
|
764
|
+
});
|
|
721
765
|
break;
|
|
722
766
|
}
|
|
723
767
|
if (orchestrationResult.kind === "stopped") {
|
|
@@ -750,6 +794,42 @@ export async function autoLoop(ctx, pi, s, deps, options) {
|
|
|
750
794
|
isRetry: false,
|
|
751
795
|
previousTier: undefined,
|
|
752
796
|
};
|
|
797
|
+
const preDispatchResult = deps.runPreDispatchHooks(iterData.unitType, iterData.unitId, iterData.prompt, s.basePath);
|
|
798
|
+
if (preDispatchResult.firedHooks.length > 0) {
|
|
799
|
+
ctx.ui.notify(`Pre-dispatch hook${preDispatchResult.firedHooks.length > 1 ? "s" : ""}: ${preDispatchResult.firedHooks.join(", ")}`, "info");
|
|
800
|
+
deps.emitJournalEvent({
|
|
801
|
+
ts: new Date().toISOString(),
|
|
802
|
+
flowId: ic.flowId,
|
|
803
|
+
seq: ic.nextSeq(),
|
|
804
|
+
eventType: "pre-dispatch-hook",
|
|
805
|
+
data: {
|
|
806
|
+
firedHooks: preDispatchResult.firedHooks,
|
|
807
|
+
action: preDispatchResult.action,
|
|
808
|
+
},
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
if (preDispatchResult.action === "skip") {
|
|
812
|
+
ctx.ui.notify(`Skipping ${iterData.unitType} ${iterData.unitId} (pre-dispatch hook).`, "info");
|
|
813
|
+
s.pendingOrchestrationDispatch = null;
|
|
814
|
+
emitIterationEnd({ skipped: true });
|
|
815
|
+
completeIteration();
|
|
816
|
+
finishTurn("skipped");
|
|
817
|
+
continue;
|
|
818
|
+
}
|
|
819
|
+
if (preDispatchResult.action === "replace") {
|
|
820
|
+
iterData.prompt = preDispatchResult.prompt ?? iterData.prompt;
|
|
821
|
+
iterData.finalPrompt = iterData.prompt;
|
|
822
|
+
if (preDispatchResult.unitType) {
|
|
823
|
+
iterData.unitType = preDispatchResult.unitType;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
else if (preDispatchResult.prompt) {
|
|
827
|
+
iterData.prompt = preDispatchResult.prompt;
|
|
828
|
+
iterData.finalPrompt = preDispatchResult.prompt;
|
|
829
|
+
}
|
|
830
|
+
if (preDispatchResult.model) {
|
|
831
|
+
iterData.hookModelOverride = preDispatchResult.model;
|
|
832
|
+
}
|
|
753
833
|
s.pendingOrchestrationDispatch = null;
|
|
754
834
|
phaseReporter.report("dispatch", "next", {
|
|
755
835
|
unitType: iterData.unitType,
|
|
@@ -369,9 +369,11 @@ export class AutoOrchestrator {
|
|
|
369
369
|
const activeUnitKey = this.status.activeUnit
|
|
370
370
|
? `${this.status.activeUnit.unitType}:${this.status.activeUnit.unitId}`
|
|
371
371
|
: null;
|
|
372
|
-
if (activeUnitKey !== unitKey)
|
|
372
|
+
if (activeUnitKey !== unitKey && this.lastFinalizedUnitKey !== unitKey)
|
|
373
373
|
return;
|
|
374
|
-
|
|
374
|
+
if (activeUnitKey === unitKey) {
|
|
375
|
+
this.status.activeUnit = undefined;
|
|
376
|
+
}
|
|
375
377
|
this.lastAdvanceKey = null;
|
|
376
378
|
this.lastFinalizedUnitKey = null;
|
|
377
379
|
this.bumpTransition();
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { importExtensionModule } from "@gsd/pi-coding-agent";
|
|
12
12
|
import { USER_DRIVEN_DEEP_UNITS, isAwaitingUserInput, } from "../auto-post-unit.js";
|
|
13
|
+
import { lastAssistantText } from "../user-input-boundary.js";
|
|
13
14
|
import { MAX_RECOVERY_CHARS, BUDGET_THRESHOLDS, MAX_FINALIZE_TIMEOUTS, } from "./types.js";
|
|
14
15
|
import { detectStuck } from "./detect-stuck.js";
|
|
15
16
|
import { runUnit } from "./run-unit.js";
|
|
@@ -52,8 +53,19 @@ import { decideVerificationRetry, verificationRetryKey } from "./verification-re
|
|
|
52
53
|
import { buildPhaseHandoffOutcome, setAutoOutcomeWidget } from "../auto-dashboard.js";
|
|
53
54
|
import { getConsecutiveDispatchBlocker } from "../dispatch-guard.js";
|
|
54
55
|
import { captureRootDirtySnapshot, detectRootWriteLeak, formatRootWriteLeakMessage, } from "../root-write-leak-guard.js";
|
|
56
|
+
import { classifyError, isTransient } from "../error-classifier.js";
|
|
55
57
|
export const STUCK_WINDOW_SIZE = 6;
|
|
56
58
|
const STUCK_RECOVERY_ATTEMPTS_KEY = "stuck_recovery_attempts";
|
|
59
|
+
const ZERO_TOOL_PROVIDER_ERROR_PREFIX_RE = /^(?:api error(?::|$|\s*\()|provider error(?::|$|\s*\()|request failed\b|(?:http\s*)?(?:429|500|502|503)\b|\b(?:econnreset|etimedout|econnrefused|epipe)\b|socket hang up\b|fetch failed\b|(?:network|connection|server) error(?::|$)|connection (?:reset|refused)(?::|$|\s+by\b)|dns\b.*(?:fail|error|timeout)|unexpected eof\b|stream idle timeout\b|partial response received\b|stream_exhausted\b|terminated(?::|$)|(?:connection|stream|request)\b.{0,40}\bterminated\b|other side closed\b|rate.?limit(?:ed| exceeded| reached| error)|too many requests\b|you(?:'ve| have) hit your limit\b|usage limit\b|out of extra usage\b|service.?unavailable\b|internal(?: server)? error(?::|$)|internal(?:[_-]server)?[_-]error\b|server[_-]error\b|(?:provider|server|api|model|codex|claude|openai|anthropic|gemini)\b.{0,80}\boverloaded\b|overloaded\b.{0,80}\b(?:provider|server|api|model)\b|context (?:window|length) exceed|context window exceed)/i;
|
|
60
|
+
const ZERO_TOOL_PROVIDER_ERROR_SIGNAL_RE = /(?:\b(?:http|status(?: code)?|code|error:)\s*(?:429|500|502|503)\b|\b(?:api|provider) error\s*[:(]?\s*(?:429|500|502|503)\b|\b(?:typeerror|error):\s*(?:fetch failed\b|socket hang up\b|terminated(?::|$)|connection (?:reset|refused)(?::|$|\s+by\b)|(?:network|connection|server) error(?::|$)|stream idle timeout\b|partial response received\b|unexpected eof\b)|\b(?:server_error|api_error|stream_exhausted(?:_without_result)?)\b|\b(?:econnreset|etimedout|econnrefused|epipe)\b|context (?:window|length) exceed|context window exceed)/i;
|
|
61
|
+
function classifyZeroToolProviderMessage(message) {
|
|
62
|
+
const firstLine = message.trim().split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
63
|
+
if (!firstLine ||
|
|
64
|
+
(!ZERO_TOOL_PROVIDER_ERROR_PREFIX_RE.test(firstLine) &&
|
|
65
|
+
!ZERO_TOOL_PROVIDER_ERROR_SIGNAL_RE.test(firstLine)))
|
|
66
|
+
return null;
|
|
67
|
+
return classifyError(firstLine);
|
|
68
|
+
}
|
|
57
69
|
export function resolveDispatchRecoveryAttempts(unitRecoveryCount, unitType, unitId) {
|
|
58
70
|
return (unitRecoveryCount.get(`${unitType}/${unitId}`) ?? 0) > 0
|
|
59
71
|
? 0
|
|
@@ -1568,7 +1580,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1568
1580
|
const dispatchKey = `${unitType}/${unitId}`;
|
|
1569
1581
|
const nextDispatchCount = (s.unitDispatchCount.get(dispatchKey) ?? 0) + 1;
|
|
1570
1582
|
// Status bar (widget + preconditions deferred until after model selection — see #2899)
|
|
1571
|
-
ctx.ui.setStatus("gsd-auto", "auto");
|
|
1583
|
+
ctx.ui.setStatus("gsd-auto", s.stepMode ? "next" : "auto");
|
|
1572
1584
|
if (mid)
|
|
1573
1585
|
deps.updateSliceProgressCache(s.basePath, mid, state.activeSlice?.id);
|
|
1574
1586
|
// ── Safety harness: reset evidence + create checkpoint ──
|
|
@@ -1999,6 +2011,31 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1999
2011
|
if (currentLedger?.units) {
|
|
2000
2012
|
const lastUnit = [...currentLedger.units].reverse().find((u) => u.type === unitType && u.id === unitId && u.startedAt === _resolveCurrentUnitStartedAtForTest(s.currentUnit));
|
|
2001
2013
|
if (lastUnit && lastUnit.toolCalls === 0) {
|
|
2014
|
+
const lastAssistantMessage = lastAssistantText(s.lastUnitAgentEndMessages);
|
|
2015
|
+
const providerMessageClass = classifyZeroToolProviderMessage(lastAssistantMessage);
|
|
2016
|
+
if (providerMessageClass && isTransient(providerMessageClass)) {
|
|
2017
|
+
const retryAfterMs = "retryAfterMs" in providerMessageClass ? providerMessageClass.retryAfterMs : 15_000;
|
|
2018
|
+
await pauseAutoForProviderError(ctx.ui, ` for ${unitType} ${unitId}`, () => deps.pauseAuto(ctx, pi), {
|
|
2019
|
+
isRateLimit: providerMessageClass.kind === "rate-limit",
|
|
2020
|
+
isTransient: true,
|
|
2021
|
+
retryAfterMs,
|
|
2022
|
+
resume: () => {
|
|
2023
|
+
void resumeAutoAfterProviderDelay(pi, ctx).catch((err) => {
|
|
2024
|
+
logWarning("engine", `Provider error auto-resume failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
2025
|
+
});
|
|
2026
|
+
},
|
|
2027
|
+
});
|
|
2028
|
+
await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, {
|
|
2029
|
+
message: lastAssistantMessage.slice(0, 200),
|
|
2030
|
+
category: "provider",
|
|
2031
|
+
isTransient: true,
|
|
2032
|
+
retryAfterMs,
|
|
2033
|
+
});
|
|
2034
|
+
return {
|
|
2035
|
+
action: "break",
|
|
2036
|
+
reason: providerMessageClass.kind === "rate-limit" ? "rate-limit" : "api-timeout",
|
|
2037
|
+
};
|
|
2038
|
+
}
|
|
2002
2039
|
if (USER_DRIVEN_DEEP_UNITS.has(unitType) && isAwaitingUserInput(s.lastUnitAgentEndMessages ?? undefined)) {
|
|
2003
2040
|
debugLog("runUnitPhase", {
|
|
2004
2041
|
phase: "zero-tool-calls-awaiting-user-input",
|
|
@@ -7,6 +7,7 @@ import { logWarning } from "../workflow-logger.js";
|
|
|
7
7
|
import { resolveAutoSupervisorConfig } from "../preferences.js";
|
|
8
8
|
import { readUnitRuntimeRecord } from "../unit-runtime.js";
|
|
9
9
|
import { consumeAutoWakeup } from "./schedule-wakeup.js";
|
|
10
|
+
import { applyUnitSkillVisibility } from "../skill-scope.js";
|
|
10
11
|
const UNIT_FAILSAFE_BUFFER_MS = 30_000;
|
|
11
12
|
const UNIT_FAILSAFE_RECHECK_MS = 30_000;
|
|
12
13
|
const WAKEUP_SLEEP_CHUNK_MS = 1_000;
|
|
@@ -123,6 +124,10 @@ export async function runUnit(ctx, pi, s, unitType, unitId, prompt) {
|
|
|
123
124
|
};
|
|
124
125
|
}
|
|
125
126
|
}
|
|
127
|
+
const setVisibleSkills = typeof pi.setVisibleSkills === "function" ? pi.setVisibleSkills.bind(pi) : undefined;
|
|
128
|
+
if (setVisibleSkills) {
|
|
129
|
+
applyUnitSkillVisibility({ setVisibleSkills }, unitType);
|
|
130
|
+
}
|
|
126
131
|
// ── Create the agent_end promise (per-unit one-shot) ──
|
|
127
132
|
// This happens after newSession completes so session-switch agent_end events
|
|
128
133
|
// from the previous session cannot resolve the new unit.
|
|
@@ -134,6 +139,7 @@ export async function runUnit(ctx, pi, s, unitType, unitId, prompt) {
|
|
|
134
139
|
const pendingSwitchCancellation = _consumePendingSwitchCancellation();
|
|
135
140
|
if (pendingSwitchCancellation) {
|
|
136
141
|
_clearCurrentResolve();
|
|
142
|
+
setVisibleSkills?.(undefined);
|
|
137
143
|
return {
|
|
138
144
|
status: "cancelled",
|
|
139
145
|
...(pendingSwitchCancellation.errorContext ? { errorContext: pendingSwitchCancellation.errorContext } : {}),
|
|
@@ -156,6 +162,7 @@ export async function runUnit(ctx, pi, s, unitType, unitId, prompt) {
|
|
|
156
162
|
}
|
|
157
163
|
if (!ready) {
|
|
158
164
|
_clearCurrentResolve();
|
|
165
|
+
setVisibleSkills?.(undefined);
|
|
159
166
|
return {
|
|
160
167
|
status: "cancelled",
|
|
161
168
|
errorContext: {
|
|
@@ -290,6 +297,7 @@ export async function runUnit(ctx, pi, s, unitType, unitId, prompt) {
|
|
|
290
297
|
if (unitTimeoutHandle)
|
|
291
298
|
clearTimeout(unitTimeoutHandle);
|
|
292
299
|
ctx.ui.setWorkingMessage?.(undefined);
|
|
300
|
+
setVisibleSkills?.(undefined);
|
|
293
301
|
}
|
|
294
302
|
debugLog("runUnit", {
|
|
295
303
|
phase: "agent-end-received",
|
|
@@ -132,6 +132,8 @@ export class AutoSession {
|
|
|
132
132
|
// ── Isolation degradation ────────────────────────────────────────────
|
|
133
133
|
/** Set to true when worktree creation fails; prevents merge of nonexistent branch. */
|
|
134
134
|
isolationDegraded = false;
|
|
135
|
+
/** Temporary recovery mode for stranded work adopted from physical git evidence. */
|
|
136
|
+
strandedRecoveryIsolationMode = null;
|
|
135
137
|
/** Project-root dirty snapshot captured before an isolated worktree unit runs. */
|
|
136
138
|
rootWriteBaseline = null;
|
|
137
139
|
// ── Merge guard ──────────────────────────────────────────────────────
|
|
@@ -285,6 +287,7 @@ export class AutoSession {
|
|
|
285
287
|
this.lastGitActionFailure = null;
|
|
286
288
|
this.lastGitActionStatus = null;
|
|
287
289
|
this.isolationDegraded = false;
|
|
290
|
+
this.strandedRecoveryIsolationMode = null;
|
|
288
291
|
this.rootWriteBaseline = null;
|
|
289
292
|
this.milestoneMergedInPhases = false;
|
|
290
293
|
this.milestoneStartShas = new Map();
|
|
@@ -33,6 +33,11 @@ import { resolveWorktreeProjectRoot } from "./worktree-root.js";
|
|
|
33
33
|
import { probeGitConflictState } from "./git-conflict-state.js";
|
|
34
34
|
import { runTurnGitAction } from "./git-service.js";
|
|
35
35
|
import { parseUnitId } from "./unit-id.js";
|
|
36
|
+
import { resolveExpectedArtifactPath } from "./auto-artifact-paths.js";
|
|
37
|
+
function resolveExistingExpectedArtifact(unitType, unitId, basePath) {
|
|
38
|
+
const artifactPath = resolveExpectedArtifactPath(unitType, unitId, basePath);
|
|
39
|
+
return artifactPath && existsSync(artifactPath) ? artifactPath : null;
|
|
40
|
+
}
|
|
36
41
|
let reassessmentChecker = checkNeedsReassessment;
|
|
37
42
|
let researchProjectPromptBuilder = buildResearchProjectPrompt;
|
|
38
43
|
function shouldBypassMilestoneDepthGateInAuto(prefs) {
|
|
@@ -808,13 +813,15 @@ export const DISPATCH_RULES = [
|
|
|
808
813
|
if (await getMilestonePipelineVariant(mid) === "trivial")
|
|
809
814
|
return null;
|
|
810
815
|
// Load roadmap to find all slices
|
|
811
|
-
const roadmapFile =
|
|
816
|
+
const roadmapFile = resolveExistingExpectedArtifact("plan-milestone", mid, basePath) ??
|
|
817
|
+
resolveMilestoneFile(basePath, mid, "ROADMAP");
|
|
812
818
|
const roadmapContent = roadmapFile ? await loadFile(roadmapFile) : null;
|
|
813
819
|
if (!roadmapContent)
|
|
814
820
|
return null;
|
|
815
821
|
const roadmap = parseRoadmap(roadmapContent);
|
|
816
822
|
// Find slices that need research (no RESEARCH file, dependencies done)
|
|
817
|
-
const milestoneResearchFile =
|
|
823
|
+
const milestoneResearchFile = resolveExistingExpectedArtifact("research-milestone", mid, basePath) ??
|
|
824
|
+
resolveMilestoneFile(basePath, mid, "RESEARCH");
|
|
818
825
|
const researchReadySlices = [];
|
|
819
826
|
for (const slice of roadmap.slices) {
|
|
820
827
|
if (slice.done)
|
|
@@ -823,10 +830,10 @@ export const DISPATCH_RULES = [
|
|
|
823
830
|
if (milestoneResearchFile && slice.id === "S01")
|
|
824
831
|
continue;
|
|
825
832
|
// Skip if already has research
|
|
826
|
-
if (
|
|
833
|
+
if (resolveExistingExpectedArtifact("research-slice", `${mid}/${slice.id}`, basePath))
|
|
827
834
|
continue;
|
|
828
835
|
// Skip if dependencies aren't done (check for SUMMARY files)
|
|
829
|
-
const depsComplete = (slice.depends ?? []).every((depId) => !!
|
|
836
|
+
const depsComplete = (slice.depends ?? []).every((depId) => !!resolveExistingExpectedArtifact("complete-slice", `${mid}/${depId}`, basePath));
|
|
830
837
|
if (!depsComplete)
|
|
831
838
|
continue;
|
|
832
839
|
researchReadySlices.push({ id: slice.id, title: slice.title });
|
|
@@ -837,7 +844,8 @@ export const DISPATCH_RULES = [
|
|
|
837
844
|
// #4414: If a previous parallel-research attempt escalated to a blocker
|
|
838
845
|
// placeholder, skip this rule and fall through to per-slice research
|
|
839
846
|
// (or other rules) rather than re-dispatching the same failing unit.
|
|
840
|
-
const parallelBlocker =
|
|
847
|
+
const parallelBlocker = resolveExistingExpectedArtifact("research-slice", `${mid}/parallel-research`, basePath) ??
|
|
848
|
+
resolveMilestoneFile(basePath, mid, "PARALLEL-BLOCKER");
|
|
841
849
|
if (parallelBlocker)
|
|
842
850
|
return null;
|
|
843
851
|
return {
|
|
@@ -863,12 +871,14 @@ export const DISPATCH_RULES = [
|
|
|
863
871
|
return missingSliceStop(mid, state.phase);
|
|
864
872
|
const sid = state.activeSlice.id;
|
|
865
873
|
const sTitle = state.activeSlice.title;
|
|
866
|
-
const researchFile =
|
|
874
|
+
const researchFile = resolveExistingExpectedArtifact("research-slice", `${mid}/${sid}`, basePath) ??
|
|
875
|
+
resolveSliceFile(basePath, mid, sid, "RESEARCH");
|
|
867
876
|
if (researchFile)
|
|
868
877
|
return null; // has research, fall through
|
|
869
878
|
// Skip slice research for S01 when milestone research already exists —
|
|
870
879
|
// the milestone research already covers the same ground for the first slice.
|
|
871
|
-
const milestoneResearchFile =
|
|
880
|
+
const milestoneResearchFile = resolveExistingExpectedArtifact("research-milestone", mid, basePath) ??
|
|
881
|
+
resolveMilestoneFile(basePath, mid, "RESEARCH");
|
|
872
882
|
if (milestoneResearchFile && sid === "S01")
|
|
873
883
|
return null; // fall through to plan-slice
|
|
874
884
|
return {
|