@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
|
@@ -37,6 +37,8 @@ import { runGSDDoctor, rebuildState } from "./doctor.js";
|
|
|
37
37
|
import { preDispatchHealthGate, recordHealthSnapshot, resetProactiveHealing, setLevelChangeCallback, } from "./doctor-proactive.js";
|
|
38
38
|
import { clearSkillSnapshot } from "./skill-discovery.js";
|
|
39
39
|
import { captureAvailableSkills, resetSkillTelemetry, } from "./skill-telemetry.js";
|
|
40
|
+
import { getInstalledSkillNames } from "./skills.js";
|
|
41
|
+
import { effectiveSkillNamesForUnit } from "./skill-scope.js";
|
|
40
42
|
import { getRtkSessionSavings } from "../shared/rtk-session-stats.js";
|
|
41
43
|
import { deactivateGSD } from "../shared/gsd-phase-state.js";
|
|
42
44
|
import { initMetrics, resetMetrics, getLedger, getProjectTotals, filterUnitsForMilestone, formatCost, formatTokenCount, } from "./metrics.js";
|
|
@@ -64,7 +66,7 @@ import { isClosedStatus } from "./status-guards.js";
|
|
|
64
66
|
import { MILESTONE_ID_RE } from "./milestone-ids.js";
|
|
65
67
|
import { updateProgressWidget as _updateProgressWidget, setCompletionProgressWidget, setAutoOutcomeWidget, updateSliceProgressCache, clearSliceProgressCache, unitVerb, } from "./auto-dashboard.js";
|
|
66
68
|
import { registerSigtermHandler as _registerSigtermHandler, deregisterSigtermHandler as _deregisterSigtermHandler, } from "./auto-supervisor.js";
|
|
67
|
-
import { isDbAvailable, getMilestone, getMilestoneSlices } from "./gsd-db.js";
|
|
69
|
+
import { isDbAvailable, getMilestone, getMilestoneSlices, getSlice, getTask, refreshOpenDatabaseFromDisk, } from "./gsd-db.js";
|
|
68
70
|
import { markLatestActiveForWorkerCanceled } from "./db/unit-dispatches.js";
|
|
69
71
|
import { writeUnitRuntimeRecord } from "./unit-runtime.js";
|
|
70
72
|
import { countPendingCaptures } from "./captures.js";
|
|
@@ -1576,6 +1578,25 @@ function buildLifecycle() {
|
|
|
1576
1578
|
* `sessionProvider`, and `modelRegistry` the same way phases.ts:runDispatch does.
|
|
1577
1579
|
*/
|
|
1578
1580
|
export function createWiredDispatchAdapter(ctx, pi, dispatchBasePath, session) {
|
|
1581
|
+
function getAlreadyClosedDispatchReason(unitType, unitId) {
|
|
1582
|
+
if (!isDbAvailable())
|
|
1583
|
+
return null;
|
|
1584
|
+
refreshOpenDatabaseFromDisk();
|
|
1585
|
+
const { milestone, slice, task } = parseUnitId(unitId);
|
|
1586
|
+
if (unitType === "execute-task" && milestone && slice && task) {
|
|
1587
|
+
const row = getTask(milestone, slice, task);
|
|
1588
|
+
return row && isClosedStatus(row.status)
|
|
1589
|
+
? `execute-task ${unitId} is already ${row.status}`
|
|
1590
|
+
: null;
|
|
1591
|
+
}
|
|
1592
|
+
if (unitType === "complete-slice" && milestone && slice) {
|
|
1593
|
+
const row = getSlice(milestone, slice);
|
|
1594
|
+
return row && isClosedStatus(row.status)
|
|
1595
|
+
? `complete-slice ${unitId} is already ${row.status}`
|
|
1596
|
+
: null;
|
|
1597
|
+
}
|
|
1598
|
+
return null;
|
|
1599
|
+
}
|
|
1579
1600
|
return {
|
|
1580
1601
|
async decideNextUnit(input) {
|
|
1581
1602
|
const state = input.stateSnapshot;
|
|
@@ -1611,6 +1632,12 @@ export function createWiredDispatchAdapter(ctx, pi, dispatchBasePath, session) {
|
|
|
1611
1632
|
const pendingRetry = session?.pendingVerificationRetryDispatch;
|
|
1612
1633
|
if (session && pendingRetry) {
|
|
1613
1634
|
session.pendingVerificationRetryDispatch = null;
|
|
1635
|
+
const alreadyClosedReason = getAlreadyClosedDispatchReason(pendingRetry.unitType, pendingRetry.unitId);
|
|
1636
|
+
if (alreadyClosedReason) {
|
|
1637
|
+
session.pendingOrchestrationDispatch = null;
|
|
1638
|
+
session.pendingVerificationRetry = null;
|
|
1639
|
+
return { kind: "skipped", reason: alreadyClosedReason };
|
|
1640
|
+
}
|
|
1614
1641
|
session.pendingOrchestrationDispatch = pendingRetry;
|
|
1615
1642
|
return {
|
|
1616
1643
|
unitType: pendingRetry.unitType,
|
|
@@ -1648,6 +1675,14 @@ export function createWiredDispatchAdapter(ctx, pi, dispatchBasePath, session) {
|
|
|
1648
1675
|
reason: action.matchedRule ?? "dispatch-skip",
|
|
1649
1676
|
};
|
|
1650
1677
|
}
|
|
1678
|
+
const alreadyClosedReason = getAlreadyClosedDispatchReason(action.unitType, action.unitId);
|
|
1679
|
+
if (alreadyClosedReason) {
|
|
1680
|
+
if (session) {
|
|
1681
|
+
session.pendingOrchestrationDispatch = null;
|
|
1682
|
+
session.pendingVerificationRetry = null;
|
|
1683
|
+
}
|
|
1684
|
+
return { kind: "skipped", reason: alreadyClosedReason };
|
|
1685
|
+
}
|
|
1651
1686
|
if (session) {
|
|
1652
1687
|
const pending = {
|
|
1653
1688
|
unitType: action.unitType,
|
|
@@ -2040,7 +2075,10 @@ function buildLoopDeps(pi) {
|
|
|
2040
2075
|
autoCommitUnit,
|
|
2041
2076
|
recordOutcome,
|
|
2042
2077
|
writeLock,
|
|
2043
|
-
captureAvailableSkills
|
|
2078
|
+
captureAvailableSkills: () => {
|
|
2079
|
+
const unitType = s.currentUnit?.type;
|
|
2080
|
+
captureAvailableSkills(effectiveSkillNamesForUnit(unitType, getInstalledSkillNames()));
|
|
2081
|
+
},
|
|
2044
2082
|
ensurePreconditions,
|
|
2045
2083
|
updateSliceProgressCache,
|
|
2046
2084
|
// Model selection + supervision
|
|
@@ -678,8 +678,9 @@ export function registerDbTools(pi) {
|
|
|
678
678
|
promptSnippet: "Complete a GSD task (DB write + summary render + checkbox toggle)",
|
|
679
679
|
promptGuidelines: [
|
|
680
680
|
"Use gsd_task_complete (or gsd_complete_task) when a task is finished and needs to be recorded.",
|
|
681
|
-
"
|
|
682
|
-
"
|
|
681
|
+
"Include verification whenever possible. If verification is omitted, the executor derives it from verificationEvidence when possible.",
|
|
682
|
+
"verificationEvidence is an array of objects with command, exitCode, verdict, durationMs.",
|
|
683
|
+
"The tool validates required fields and returns an error message if verification cannot be derived.",
|
|
683
684
|
"On success, returns the summaryPath where the SUMMARY.md was written.",
|
|
684
685
|
"Idempotent — calling with the same params twice will upsert (INSERT OR REPLACE) without error.",
|
|
685
686
|
],
|
|
@@ -690,7 +691,7 @@ export function registerDbTools(pi) {
|
|
|
690
691
|
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
691
692
|
oneLiner: Type.String({ description: "One-line summary of what was accomplished" }),
|
|
692
693
|
narrative: Type.String({ description: "Detailed narrative of what happened during the task" }),
|
|
693
|
-
verification: Type.String({ description: "What was verified and how — commands run, tests passed, behavior confirmed" }),
|
|
694
|
+
verification: Type.Optional(Type.String({ description: "What was verified and how — commands run, tests passed, behavior confirmed. If omitted, derived from verificationEvidence when possible." })),
|
|
694
695
|
// ── Enrichment metadata (optional — defaults to empty) ────────────
|
|
695
696
|
deviations: Type.Optional(Type.String({ description: "Deviations from the task plan, or 'None.'" })),
|
|
696
697
|
knownIssues: Type.Optional(Type.String({ description: "Known issues discovered but not fixed, or 'None.'" })),
|
|
@@ -36,8 +36,13 @@ export function registerExecTools(pi) {
|
|
|
36
36
|
"Need persisted output? Read the stdout_path returned in details (file on local disk).",
|
|
37
37
|
],
|
|
38
38
|
parameters: Type.Object({
|
|
39
|
-
runtime: Type.
|
|
40
|
-
|
|
39
|
+
runtime: Type.Optional(Type.String({
|
|
40
|
+
description: "Optional interpreter. Defaults to bash. Supported: bash, node, python; sh/shell, js/nodejs, and py/python3 aliases are accepted.",
|
|
41
|
+
})),
|
|
42
|
+
script: Type.Optional(Type.String({ description: "Script body. Keep output small (log the finding, not the data)." })),
|
|
43
|
+
command: Type.Optional(Type.String({ description: "Alias for script; defaults to bash when runtime is omitted." })),
|
|
44
|
+
cmd: Type.Optional(Type.String({ description: "Short alias for script." })),
|
|
45
|
+
code: Type.Optional(Type.String({ description: "Alias for script, useful for node/python snippets." })),
|
|
41
46
|
purpose: Type.Optional(Type.String({ description: "Short label recorded in meta.json for later review." })),
|
|
42
47
|
timeout_ms: Type.Optional(Type.Number({
|
|
43
48
|
description: "Per-invocation timeout (ms). Capped at 600000. Default from preferences.",
|
|
@@ -21,6 +21,31 @@ import { logWarning } from "../workflow-logger.js";
|
|
|
21
21
|
// EventEmitter does not buffer events for late subscribers.
|
|
22
22
|
import { initCmuxEventListeners } from "../../cmux/index.js";
|
|
23
23
|
export { writeCrashLog } from "./crash-log.js";
|
|
24
|
+
// Pipe-closed storm guard. #99/#101 stopped EPIPE from flooding ~/.gsd/crash,
|
|
25
|
+
// but a persistently-broken output pipe whose `destroyed`/`writableEnded` flags
|
|
26
|
+
// never flip is still swallowed on every write — a tight, progress-free CPU
|
|
27
|
+
// spin. If the pipe-closed error fires in a tight loop the pipe is gone for
|
|
28
|
+
// good; exit cleanly instead.
|
|
29
|
+
const EPIPE_STORM_THRESHOLD = 100;
|
|
30
|
+
const EPIPE_STORM_WINDOW_MS = 10_000;
|
|
31
|
+
let epipeCount = 0;
|
|
32
|
+
let epipeWindowStart = 0;
|
|
33
|
+
/** Write to stderr without ever re-throwing — stderr can EPIPE too, which would
|
|
34
|
+
* re-enter this handler and re-loop. */
|
|
35
|
+
function safeStderr(msg) {
|
|
36
|
+
try {
|
|
37
|
+
process.stderr.write(msg);
|
|
38
|
+
}
|
|
39
|
+
catch { /* stderr is also broken; nothing we can do */ }
|
|
40
|
+
}
|
|
41
|
+
/** A peer closing the read end of a pipe mid-write surfaces differently per
|
|
42
|
+
* platform: POSIX throws `EPIPE`; Windows throws `Error: write EOF` (or
|
|
43
|
+
* `read EOF`) with no `code` set, from node:internal/stream_base_commons.
|
|
44
|
+
* Both are the same logical condition and must be treated as recoverable —
|
|
45
|
+
* otherwise the Windows EOF variant escapes to the uncaught-exception path
|
|
46
|
+
* and crashes auto-mode workers mid-iteration (#181). ECONNRESET is NOT
|
|
47
|
+
* included here: it commonly comes from network sockets (#182 follow-up) and
|
|
48
|
+
* is a real error that should surface rather than be silently swallowed. */
|
|
24
49
|
function isPipeClosedError(err) {
|
|
25
50
|
const errno = err.code;
|
|
26
51
|
if (errno === "EPIPE")
|
|
@@ -30,7 +55,7 @@ function isPipeClosedError(err) {
|
|
|
30
55
|
}
|
|
31
56
|
export function handleRecoverableExtensionProcessError(err) {
|
|
32
57
|
if (err.message.includes("ProcessTransport is not ready for writing")) {
|
|
33
|
-
|
|
58
|
+
safeStderr(`[gsd] swallowed dead transport control write: ${err.message}\n`);
|
|
34
59
|
return true;
|
|
35
60
|
}
|
|
36
61
|
if (isPipeClosedError(err)) {
|
|
@@ -40,24 +65,33 @@ export function handleRecoverableExtensionProcessError(err) {
|
|
|
40
65
|
if (stdoutGone) {
|
|
41
66
|
process.exit(0);
|
|
42
67
|
}
|
|
43
|
-
|
|
68
|
+
const now = Date.now();
|
|
69
|
+
if (now - epipeWindowStart > EPIPE_STORM_WINDOW_MS) {
|
|
70
|
+
epipeWindowStart = now;
|
|
71
|
+
epipeCount = 0;
|
|
72
|
+
}
|
|
73
|
+
if (++epipeCount > EPIPE_STORM_THRESHOLD) {
|
|
74
|
+
safeStderr(`[gsd] ${tag} storm (${epipeCount} within ${EPIPE_STORM_WINDOW_MS}ms) — output pipe is gone; exiting.\n`);
|
|
75
|
+
process.exit(0);
|
|
76
|
+
}
|
|
77
|
+
safeStderr(`[gsd] swallowed ${tag} (syscall=${err.syscall ?? "?"})\n`);
|
|
44
78
|
return true;
|
|
45
79
|
}
|
|
46
80
|
if (err.code === "EIO") {
|
|
47
81
|
const syscall = err.syscall;
|
|
48
82
|
if (syscall === "read") {
|
|
49
|
-
|
|
83
|
+
safeStderr(`[gsd] EIO: ${err.message}\n`);
|
|
50
84
|
return true;
|
|
51
85
|
}
|
|
52
86
|
}
|
|
53
87
|
if (err.code === "ENOENT") {
|
|
54
88
|
const syscall = err.syscall;
|
|
55
89
|
if (syscall?.startsWith("spawn")) {
|
|
56
|
-
|
|
90
|
+
safeStderr(`[gsd] spawn ENOENT: ${err.path ?? "unknown"} — command not found\n`);
|
|
57
91
|
return true;
|
|
58
92
|
}
|
|
59
93
|
if (syscall === "uv_cwd") {
|
|
60
|
-
|
|
94
|
+
safeStderr(`[gsd] ENOENT (${syscall}): ${err.message}\n`);
|
|
61
95
|
return true;
|
|
62
96
|
}
|
|
63
97
|
}
|
|
@@ -25,7 +25,7 @@ import { initNotificationWidget } from "../notification-widget.js";
|
|
|
25
25
|
import { resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
26
26
|
import { extractSubagentAgentClasses } from "./subagent-input.js";
|
|
27
27
|
import { approvalGateIdForUnit, isExplicitApprovalResponse, shouldPauseForUserApprovalQuestion } from "../user-input-boundary.js";
|
|
28
|
-
import {
|
|
28
|
+
import { applyUnitSkillVisibility, unitHasSkillManifest } from "../skill-scope.js";
|
|
29
29
|
import { getGuidedUnitContext } from "../guided-unit-context.js";
|
|
30
30
|
import { registerPlanMilestoneSchemaRecovery } from "./plan-milestone-schema-recovery.js";
|
|
31
31
|
let approvalQuestionAbortInFlight = false;
|
|
@@ -125,6 +125,45 @@ export const MINIMAL_AUTO_BASE_TOOL_NAMES = [
|
|
|
125
125
|
function withPreservedShimTools(toolNames) {
|
|
126
126
|
return [...new Set([...toolNames, ...ALWAYS_PRESERVED_SHIM_TOOL_NAMES])];
|
|
127
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Backwards-compatibility workflow tool aliases (each forwards to a canonical
|
|
130
|
+
* twin). Mirrors WORKFLOW_TOOL_CONTRACTS[].aliases in @opengsd/contracts. These
|
|
131
|
+
* stay registered/callable but are dropped from the model-advertised tool set
|
|
132
|
+
* (~5.6K tokens/turn of duplicate schemas) — the canonical name is always
|
|
133
|
+
* advertised, and prompts/scoped tool sets already use canonical names.
|
|
134
|
+
*/
|
|
135
|
+
const WORKFLOW_ALIAS_TOOL_NAMES = new Set([
|
|
136
|
+
"gsd_save_decision",
|
|
137
|
+
"gsd_update_requirement",
|
|
138
|
+
"gsd_save_requirement",
|
|
139
|
+
"gsd_generate_milestone_id",
|
|
140
|
+
"gsd_task_plan",
|
|
141
|
+
"gsd_slice_replan",
|
|
142
|
+
"gsd_complete_slice",
|
|
143
|
+
"gsd_milestone_complete",
|
|
144
|
+
"gsd_milestone_validate",
|
|
145
|
+
"gsd_roadmap_reassess",
|
|
146
|
+
"gsd_complete_task",
|
|
147
|
+
"gsd_reopen_task",
|
|
148
|
+
"gsd_reopen_slice",
|
|
149
|
+
"gsd_reopen_milestone",
|
|
150
|
+
]);
|
|
151
|
+
/** True when a (possibly mcp-scoped) tool name is a workflow alias. */
|
|
152
|
+
function isWorkflowAliasTool(toolName) {
|
|
153
|
+
return WORKFLOW_ALIAS_TOOL_NAMES.has(canonicalToolName(toolName));
|
|
154
|
+
}
|
|
155
|
+
/** True for the ~58 Playwright browser tools (browser_navigate, browser_click, …). */
|
|
156
|
+
function isBrowserTool(toolName) {
|
|
157
|
+
return canonicalToolName(toolName).startsWith("browser_");
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* True when any message in the request is driven by a GSD workflow command
|
|
161
|
+
* (customType starting "gsd-"). Plain interactive chat has none, and is scoped
|
|
162
|
+
* to the minimal GSD tool surface by default.
|
|
163
|
+
*/
|
|
164
|
+
export function requestHasGsdCustomType(requestCustomMessages) {
|
|
165
|
+
return (requestCustomMessages ?? []).some((message) => typeof message.customType === "string" && message.customType.startsWith("gsd-"));
|
|
166
|
+
}
|
|
128
167
|
const RUN_UAT_BROWSER_TOOL_NAMES = [
|
|
129
168
|
"browser_navigate",
|
|
130
169
|
"browser_click",
|
|
@@ -156,6 +195,7 @@ const AUTO_UNIT_SCOPED_TOOLS = {
|
|
|
156
195
|
"gsd_plan_milestone",
|
|
157
196
|
"gsd_milestone_generate_id",
|
|
158
197
|
],
|
|
198
|
+
"discuss-slice": ["gsd_summary_save", "gsd_decision_save"],
|
|
159
199
|
"validate-milestone": ["gsd_validate_milestone", "gsd_reassess_roadmap", "subagent"],
|
|
160
200
|
"complete-milestone": ["gsd_complete_milestone", "subagent"],
|
|
161
201
|
"research-slice": ["gsd_summary_save", "gsd_decision_save"],
|
|
@@ -188,7 +228,7 @@ function isGsdManagedTool(name) {
|
|
|
188
228
|
*
|
|
189
229
|
* MCP-scoped names follow `mcp__<namespace>__<toolname>`.
|
|
190
230
|
* Example: if `requestedToolNames` contains `gsd_exec` and `activeToolNames` contains
|
|
191
|
-
* `
|
|
231
|
+
* `mcp__custom-workflow__gsd_exec`, the MCP-scoped active name is included in the result.
|
|
192
232
|
*
|
|
193
233
|
* Returns deduplicated active tool names that satisfy the requested base names.
|
|
194
234
|
*/
|
|
@@ -258,6 +298,15 @@ export function isFullGsdToolSurfaceRequested() {
|
|
|
258
298
|
function isGeneralGsdToolScopingRequested() {
|
|
259
299
|
return process.env.PI_GSD_MINIMAL_TOOLS === "1";
|
|
260
300
|
}
|
|
301
|
+
/**
|
|
302
|
+
* Whether the ~58-tool Playwright browser surface (~7K tokens) should be
|
|
303
|
+
* advertised in interactive sessions. Off by default — browser tools stay
|
|
304
|
+
* registered/callable (so auto run-uat, which scopes them in explicitly, is
|
|
305
|
+
* unaffected) but are dropped from the model-facing surface until opted in.
|
|
306
|
+
*/
|
|
307
|
+
function isBrowserToolSurfaceRequested() {
|
|
308
|
+
return process.env.PI_GSD_BROWSER_TOOLS === "1";
|
|
309
|
+
}
|
|
261
310
|
function resolveRegisteredToolNames(pi, fallback) {
|
|
262
311
|
if (typeof pi.getAllTools === "function") {
|
|
263
312
|
return pi.getAllTools().map((tool) => tool.name);
|
|
@@ -285,8 +334,7 @@ export function scopeGsdWorkflowToolsForDispatch(pi, unitType) {
|
|
|
285
334
|
? buildMinimalAutoGsdToolSet(current, unitType, registeredToolNames)
|
|
286
335
|
: buildMinimalGsdWorkflowToolSet(current, registeredToolNames);
|
|
287
336
|
const toolsChanged = !(scoped.length === current.length && scoped.every((name, index) => name === current[index]));
|
|
288
|
-
const
|
|
289
|
-
const canScopeSkills = skillManifest !== null && pi.getVisibleSkills && pi.setVisibleSkills;
|
|
337
|
+
const canScopeSkills = unitHasSkillManifest(unitType) && pi.getVisibleSkills && pi.setVisibleSkills;
|
|
290
338
|
if (!toolsChanged && !canScopeSkills) {
|
|
291
339
|
return null;
|
|
292
340
|
}
|
|
@@ -294,8 +342,8 @@ export function scopeGsdWorkflowToolsForDispatch(pi, unitType) {
|
|
|
294
342
|
pi.setActiveTools(scoped);
|
|
295
343
|
}
|
|
296
344
|
const visibleSkills = canScopeSkills ? pi.getVisibleSkills() : undefined;
|
|
297
|
-
if (canScopeSkills) {
|
|
298
|
-
pi.setVisibleSkills
|
|
345
|
+
if (canScopeSkills && pi.setVisibleSkills) {
|
|
346
|
+
applyUnitSkillVisibility({ setVisibleSkills: pi.setVisibleSkills }, unitType);
|
|
299
347
|
}
|
|
300
348
|
return {
|
|
301
349
|
tools: toolsChanged ? current : null,
|
|
@@ -418,6 +466,17 @@ function initSessionNotifications(ctx) {
|
|
|
418
466
|
installNotifyInterceptor(ctx);
|
|
419
467
|
initNotificationWidget(ctx);
|
|
420
468
|
}
|
|
469
|
+
async function prepareWorkflowMcpForHookContext(ctx, basePath) {
|
|
470
|
+
// Skip MCP auto-prep when running inside an auto-worktree. The worktree
|
|
471
|
+
// already has .mcp.json from createAutoWorktree, and re-running the writer
|
|
472
|
+
// post-chdir rewrites the file mid-run (non-idempotent due to cwd-relative
|
|
473
|
+
// CLI path resolution), dirtying the tree and breaking the milestone merge.
|
|
474
|
+
const { isInAutoWorktree } = await import("../auto-worktree.js");
|
|
475
|
+
if (isInAutoWorktree(basePath))
|
|
476
|
+
return;
|
|
477
|
+
const { prepareWorkflowMcpForProject } = await import("../workflow-mcp-auto-prep.js");
|
|
478
|
+
prepareWorkflowMcpForProject(ctx, basePath);
|
|
479
|
+
}
|
|
421
480
|
export function registerHooks(pi, ecosystemHandlers) {
|
|
422
481
|
// ADR-005 Phase 3b: surface pi-ai ProviderSwitchReport via audit, notification, and counter.
|
|
423
482
|
// Idempotent — only the first registerHooks call installs.
|
|
@@ -438,12 +497,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
438
497
|
await syncServiceTierStatus(ctx);
|
|
439
498
|
await applyDisabledModelProviderPolicy(ctx);
|
|
440
499
|
await applyCompactionThresholdOverride(ctx);
|
|
441
|
-
|
|
442
|
-
const { isInAutoWorktree } = await import("../auto-worktree.js");
|
|
443
|
-
if (!isInAutoWorktree(basePath)) {
|
|
444
|
-
const { prepareWorkflowMcpForProject } = await import("../workflow-mcp-auto-prep.js");
|
|
445
|
-
prepareWorkflowMcpForProject(ctx, basePath);
|
|
446
|
-
}
|
|
500
|
+
await prepareWorkflowMcpForHookContext(ctx, basePath);
|
|
447
501
|
// Apply show_token_cost preference (#1515)
|
|
448
502
|
try {
|
|
449
503
|
const { loadEffectiveGSDPreferences } = await import("../preferences.js");
|
|
@@ -468,15 +522,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
468
522
|
await syncServiceTierStatus(ctx);
|
|
469
523
|
await applyDisabledModelProviderPolicy(ctx);
|
|
470
524
|
await applyCompactionThresholdOverride(ctx);
|
|
471
|
-
|
|
472
|
-
// already has .mcp.json from createAutoWorktree, and re-running the writer
|
|
473
|
-
// post-chdir rewrites the file mid-run (non-idempotent due to cwd-relative
|
|
474
|
-
// CLI path resolution), dirtying the tree and breaking the milestone merge.
|
|
475
|
-
const { isInAutoWorktree } = await import("../auto-worktree.js");
|
|
476
|
-
if (!isInAutoWorktree(basePath)) {
|
|
477
|
-
const { prepareWorkflowMcpForProject } = await import("../workflow-mcp-auto-prep.js");
|
|
478
|
-
prepareWorkflowMcpForProject(ctx, basePath);
|
|
479
|
-
}
|
|
525
|
+
await prepareWorkflowMcpForHookContext(ctx, basePath);
|
|
480
526
|
await loadToolApiKeysForSession();
|
|
481
527
|
if (!isAutoActive()) {
|
|
482
528
|
ctx.ui.setWidget("gsd-progress", undefined);
|
|
@@ -511,9 +557,24 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
511
557
|
}
|
|
512
558
|
}
|
|
513
559
|
clearDeferredApprovalGate(beforeAgentBasePath);
|
|
560
|
+
// session_start can fire before the active provider has settled. By
|
|
561
|
+
// before_agent_start, Claude Code CLI sessions should get the same
|
|
562
|
+
// project MCP config that /gsd mcp init would write.
|
|
563
|
+
await prepareWorkflowMcpForHookContext(ctx, beforeAgentBasePath);
|
|
564
|
+
let systemPrompt = event.systemPrompt;
|
|
565
|
+
const { appendDiscoveredSkillsFallback, hasSkillSnapshot, refreshCatalogForNewSkills } = await import("../skill-discovery.js");
|
|
566
|
+
if (hasSkillSnapshot()) {
|
|
567
|
+
const loadedSkills = await refreshCatalogForNewSkills({
|
|
568
|
+
reload: () => ctx.reload(),
|
|
569
|
+
notify: (message, level) => ctx.ui.notify(message, level),
|
|
570
|
+
});
|
|
571
|
+
if (loadedSkills.length > 0) {
|
|
572
|
+
systemPrompt = appendDiscoveredSkillsFallback(ctx.getSystemPrompt(), loadedSkills);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
514
575
|
// GSD's own context injection (existing behavior — unchanged).
|
|
515
576
|
const { buildBeforeAgentStartResult } = await import("./system-context.js");
|
|
516
|
-
const gsdResult = await buildBeforeAgentStartResult(event, ctx);
|
|
577
|
+
const gsdResult = await buildBeforeAgentStartResult({ ...event, systemPrompt }, ctx);
|
|
517
578
|
// Refresh the snapshot used by ecosystem getPhase()/getActiveUnit().
|
|
518
579
|
// deriveState has its own ~100ms cache so this is cheap on repeat calls.
|
|
519
580
|
try {
|
|
@@ -525,7 +586,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
525
586
|
}
|
|
526
587
|
// Chain ecosystem handlers using pi's runner.ts chaining protocol:
|
|
527
588
|
// each handler sees the systemPrompt mutated by prior handlers.
|
|
528
|
-
let currentSystemPrompt = gsdResult?.systemPrompt ??
|
|
589
|
+
let currentSystemPrompt = gsdResult?.systemPrompt ?? systemPrompt;
|
|
529
590
|
// `any` because pi's BeforeAgentStartEventResult.message uses an internal
|
|
530
591
|
// CustomMessage type that's not re-exported (see ecosystem/gsd-extension-api.ts).
|
|
531
592
|
let lastMessage = gsdResult?.message;
|
|
@@ -1124,10 +1185,21 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1124
1185
|
// Extensions can override tool set after model selection by returning { toolNames: [...] }
|
|
1125
1186
|
// Return undefined to let the built-in provider compatibility filtering proceed.
|
|
1126
1187
|
pi.on("adjust_tool_set", async (event) => {
|
|
1127
|
-
if (isFullGsdToolSurfaceRequested())
|
|
1128
|
-
return undefined;
|
|
1129
1188
|
const removed = new Set(event.filteredTools);
|
|
1130
|
-
const
|
|
1189
|
+
const compatible = event.activeToolNames.filter((name) => !removed.has(name));
|
|
1190
|
+
// Always drop backwards-compatibility workflow aliases from the advertised
|
|
1191
|
+
// surface; they remain registered/callable but never cost schema tokens.
|
|
1192
|
+
// Drop the heavy browser surface too unless explicitly opted in — it stays
|
|
1193
|
+
// registered, so auto run-uat (which scopes browser tools in from the full
|
|
1194
|
+
// registry) still works. Both filters are skipped under full-tools mode.
|
|
1195
|
+
const fullToolsRequested = isFullGsdToolSurfaceRequested();
|
|
1196
|
+
const dropAliases = !fullToolsRequested;
|
|
1197
|
+
const dropBrowser = !fullToolsRequested && !isBrowserToolSurfaceRequested();
|
|
1198
|
+
const providerCompatible = compatible.filter((name) => !(dropAliases && isWorkflowAliasTool(name)) && !(dropBrowser && isBrowserTool(name)));
|
|
1199
|
+
const surfaceReduced = providerCompatible.length !== compatible.length;
|
|
1200
|
+
if (fullToolsRequested) {
|
|
1201
|
+
return surfaceReduced ? { toolNames: providerCompatible } : undefined;
|
|
1202
|
+
}
|
|
1131
1203
|
const registeredToolNames = resolveRegisteredToolNames(pi, event.activeToolNames);
|
|
1132
1204
|
const guidedUnit = getGuidedUnitContext();
|
|
1133
1205
|
const requestScoped = buildRequestScopedGsdToolSet(providerCompatible, event.requestCustomMessages, registeredToolNames, guidedUnit?.unitType);
|
|
@@ -1143,6 +1215,14 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1143
1215
|
if (isGeneralGsdToolScopingRequested()) {
|
|
1144
1216
|
return { toolNames: buildMinimalGsdToolSet(providerCompatible) };
|
|
1145
1217
|
}
|
|
1146
|
-
|
|
1218
|
+
// Plain interactive chat (no GSD workflow command driving this request)
|
|
1219
|
+
// never needs the full ~50-tool workflow surface — scope it to the minimal
|
|
1220
|
+
// GSD set by default (all non-GSD tools are preserved). Requests carrying a
|
|
1221
|
+
// gsd-* customType keep their existing surface, so no command is stranded.
|
|
1222
|
+
// Set PI_GSD_FULL_TOOLS=1 (handled above) to restore the full surface.
|
|
1223
|
+
if (!requestHasGsdCustomType(event.requestCustomMessages)) {
|
|
1224
|
+
return { toolNames: buildMinimalGsdToolSet(providerCompatible) };
|
|
1225
|
+
}
|
|
1226
|
+
return surfaceReduced ? { toolNames: providerCompatible } : undefined;
|
|
1147
1227
|
});
|
|
1148
1228
|
}
|
|
@@ -8,11 +8,9 @@ import { loadPrompt, getTemplatesDir } from "../prompt-loader.js";
|
|
|
8
8
|
import { readForensicsMarker } from "../forensics.js";
|
|
9
9
|
import { resolveAllSkillReferences, renderPreferencesForSystemPrompt, loadEffectiveGSDPreferences } from "../preferences.js";
|
|
10
10
|
import { resolveModelWithFallbacksForUnit } from "../preferences-models.js";
|
|
11
|
-
import { resolveSkillReference } from "../preferences-skills.js";
|
|
12
11
|
import { resolveGsdRootFile, resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTaskFiles, resolveTasksDir, relSliceFile, relSlicePath, relTaskFile } from "../paths.js";
|
|
13
12
|
import { extractIntroAndRules } from "../knowledge-parser.js";
|
|
14
13
|
import { ensureCodebaseMapFresh, readCodebaseMap } from "../codebase-generator.js";
|
|
15
|
-
import { hasSkillSnapshot, detectNewSkills, formatSkillsXml } from "../skill-discovery.js";
|
|
16
14
|
import { getActiveAutoWorktreeContext } from "../auto-worktree.js";
|
|
17
15
|
import { getActiveWorktreeName, getWorktreeOriginalCwd } from "../worktree-session-state.js";
|
|
18
16
|
import { deriveState } from "../state.js";
|
|
@@ -66,20 +64,6 @@ export const BUNDLED_SKILL_TRIGGERS = [
|
|
|
66
64
|
{ trigger: "Author a YAML workflow definition — steps, triggers, and templates", skill: "create-workflow" },
|
|
67
65
|
{ trigger: "Deep code optimization audit — perf anti-patterns, memory leaks, algorithmic complexity, bundle size, I/O, caching, dead code (parallel pattern-based hunt)", skill: "code-optimizer" },
|
|
68
66
|
];
|
|
69
|
-
function buildBundledSkillsTable() {
|
|
70
|
-
const cwd = process.cwd();
|
|
71
|
-
const rows = [];
|
|
72
|
-
for (const { trigger, skill } of BUNDLED_SKILL_TRIGGERS) {
|
|
73
|
-
const resolution = resolveSkillReference(skill, cwd);
|
|
74
|
-
if (resolution.method === "unresolved")
|
|
75
|
-
continue; // skill not installed — omit from prompt
|
|
76
|
-
rows.push(`| ${trigger} | \`${resolution.resolvedPath}\` |`);
|
|
77
|
-
}
|
|
78
|
-
if (rows.length === 0) {
|
|
79
|
-
return "*No bundled skills found. Install or sync skills to `~/.gsd/agent/skills/`, `~/.agents/skills/`, or `~/.claude/skills/`.*";
|
|
80
|
-
}
|
|
81
|
-
return `| Trigger | Skill to load |\n|---|---|\n${rows.join("\n")}`;
|
|
82
|
-
}
|
|
83
67
|
function warnDeprecatedAgentInstructions() {
|
|
84
68
|
const paths = [
|
|
85
69
|
join(gsdHome(), "agent-instructions.md"),
|
|
@@ -98,7 +82,6 @@ export async function buildBeforeAgentStartResult(event, ctx) {
|
|
|
98
82
|
return undefined;
|
|
99
83
|
const stopContextTimer = debugTime("context-inject");
|
|
100
84
|
const systemContent = loadPrompt("system", {
|
|
101
|
-
bundledSkillsTable: buildBundledSkillsTable(),
|
|
102
85
|
templatesDir: getTemplatesDir(),
|
|
103
86
|
shortcutDashboard: formatShortcut("Ctrl+Alt+G"),
|
|
104
87
|
shortcutShell: formatShortcut("Ctrl+Alt+B"),
|
|
@@ -125,7 +108,7 @@ export async function buildBeforeAgentStartResult(event, ctx) {
|
|
|
125
108
|
if (loadedPreferences) {
|
|
126
109
|
const cwd = basePath;
|
|
127
110
|
const report = resolveAllSkillReferences(loadedPreferences.preferences, cwd);
|
|
128
|
-
preferenceBlock = `\n\n${renderPreferencesForSystemPrompt(loadedPreferences.preferences, report.resolutions)}`;
|
|
111
|
+
preferenceBlock = `\n\n${renderPreferencesForSystemPrompt(loadedPreferences.preferences, report.resolutions, { includeResolvedPaths: false })}`;
|
|
129
112
|
if (report.warnings.length > 0) {
|
|
130
113
|
ctx.ui.notify(`GSD skill preferences: ${report.warnings.length} unresolved skill${report.warnings.length === 1 ? "" : "s"}: ${report.warnings.join(", ")}`, "warning");
|
|
131
114
|
}
|
|
@@ -178,13 +161,6 @@ export async function buildBeforeAgentStartResult(event, ctx) {
|
|
|
178
161
|
if (globalSizeKb > 4) {
|
|
179
162
|
ctx.ui.notify(`GSD: ~/.gsd/agent/KNOWLEDGE.md is ${globalSizeKb.toFixed(1)}KB — consider trimming to keep system prompt lean.`, "warning");
|
|
180
163
|
}
|
|
181
|
-
let newSkillsBlock = "";
|
|
182
|
-
if (hasSkillSnapshot()) {
|
|
183
|
-
const newSkills = detectNewSkills();
|
|
184
|
-
if (newSkills.length > 0) {
|
|
185
|
-
newSkillsBlock = formatSkillsXml(newSkills);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
164
|
let codebaseBlock = "";
|
|
189
165
|
try {
|
|
190
166
|
const codebaseOptions = loadedPreferences?.preferences?.codebase
|
|
@@ -235,12 +211,12 @@ export async function buildBeforeAgentStartResult(event, ctx) {
|
|
|
235
211
|
// Keeping it out of `fullSystem` preserves provider prompt-cache stability
|
|
236
212
|
// for the static system/tool prefix. The dynamic memory block rides the
|
|
237
213
|
// volatile context message instead. (#5019)
|
|
238
|
-
const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT — GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${codebaseBlock}${
|
|
214
|
+
const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT — GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${codebaseBlock}${worktreeBlock}${subagentModelBlock}`;
|
|
239
215
|
stopContextTimer({
|
|
240
216
|
systemPromptSize: fullSystem.length,
|
|
241
217
|
injectionSize: injection?.length ?? forensicsInjection?.length ?? 0,
|
|
242
218
|
hasPreferences: preferenceBlock.length > 0,
|
|
243
|
-
hasNewSkills:
|
|
219
|
+
hasNewSkills: false,
|
|
244
220
|
});
|
|
245
221
|
const contextMessage = buildContextMessage({ memoryBlock, injection, forensicsInjection });
|
|
246
222
|
return {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// GSD does not implement Anthropic deferred-tool ToolSearch. Models trained on
|
|
2
|
-
// that API sometimes try `select:
|
|
2
|
+
// that API sometimes try `select:mcp__<server>__<tool>` and get a hard
|
|
3
3
|
// "Tool ToolSearch not found" failure. This shim returns explicit call guidance.
|
|
4
4
|
import { createToolSearchShimResult, Type } from "@gsd/pi-ai";
|
|
5
5
|
export { parseToolSearchSelectQuery } from "@gsd/pi-ai";
|
|
@@ -8,14 +8,14 @@ export function registerToolSearchShim(pi) {
|
|
|
8
8
|
pi.registerTool({
|
|
9
9
|
name: "ToolSearch",
|
|
10
10
|
label: "Tool Search (guidance)",
|
|
11
|
-
description: "Not supported in GSD.
|
|
12
|
-
"(e.g. gsd_save_gate_result or
|
|
11
|
+
description: "Not supported in GSD. If the needed workflow tool is active, invoke the exact listed tool name " +
|
|
12
|
+
"(e.g. gsd_save_gate_result, or the active MCP-scoped workflow name in Claude Code). Do not use ToolSearch.",
|
|
13
13
|
parameters: Type.Object({
|
|
14
14
|
query: Type.String({ description: "Ignored — use a direct tool call instead" }),
|
|
15
15
|
max_results: Type.Optional(Type.Number()),
|
|
16
16
|
}),
|
|
17
17
|
async execute(_toolCallId, params) {
|
|
18
|
-
return createToolSearchShimResult(params);
|
|
18
|
+
return createToolSearchShimResult(params, { activeToolNames: pi.getActiveTools() });
|
|
19
19
|
},
|
|
20
20
|
renderCall(args, theme) {
|
|
21
21
|
const q = args.query ?? "";
|
|
@@ -672,7 +672,7 @@ export function shouldBlockPlanningUnit(toolName, pathOrCommand, basePath, unitT
|
|
|
672
672
|
return { block: false };
|
|
673
673
|
if (policy.mode === "all")
|
|
674
674
|
return { block: false };
|
|
675
|
-
const tool = toolName;
|
|
675
|
+
const tool = canonicalToolName(toolName);
|
|
676
676
|
// Read-only mode: only Read-class tools are permitted.
|
|
677
677
|
if (policy.mode === "read-only") {
|
|
678
678
|
if (PLANNING_SAFE_TOOLS.has(tool))
|
|
@@ -167,7 +167,13 @@ export function getCloseoutManualResolveBlocker(basePath) {
|
|
|
167
167
|
if (conflictProbe.status === "dirty" && conflictProbe.unmerged.length > 0) {
|
|
168
168
|
return `Unmerged paths remain in ${basePath}: ${conflictProbe.unmerged.slice(0, 5).join(", ")}`;
|
|
169
169
|
}
|
|
170
|
-
|
|
170
|
+
let status;
|
|
171
|
+
try {
|
|
172
|
+
status = runGit(basePath, ["status", "--porcelain"]);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
return `Could not inspect git status in ${basePath}.`;
|
|
176
|
+
}
|
|
171
177
|
if (status) {
|
|
172
178
|
return `Working tree still has uncommitted changes in ${basePath}. Commit, stash, or run /gsd closeout retry first.`;
|
|
173
179
|
}
|
|
@@ -197,7 +197,15 @@ export async function handleAutoCommand(trimmed, ctx, pi) {
|
|
|
197
197
|
if (trimmed === "") {
|
|
198
198
|
if (!(await guardRemoteSession(ctx, pi)))
|
|
199
199
|
return true;
|
|
200
|
-
|
|
200
|
+
const basePath = projectRoot();
|
|
201
|
+
const { hasGsdBootstrapArtifacts } = await import("../../detection.js");
|
|
202
|
+
const { gsdRoot } = await import("../../paths.js");
|
|
203
|
+
if (!hasGsdBootstrapArtifacts(gsdRoot(basePath))) {
|
|
204
|
+
const { showSmartEntry } = await import("../../guided-flow.js");
|
|
205
|
+
await showSmartEntry(ctx, pi, basePath, { step: true });
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
if (await hasUnresolvedCloseoutBlocker(ctx, basePath))
|
|
201
209
|
return true;
|
|
202
210
|
const { showGsdHome } = await import("../../gsd-command-home.js");
|
|
203
211
|
await showGsdHome(ctx, pi, projectRoot());
|
|
@@ -17,6 +17,7 @@ import { isAutoActive, checkRemoteAutoSession } from "./auto.js";
|
|
|
17
17
|
import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
18
18
|
import { currentDirectoryRoot, projectRoot } from "./commands/context.js";
|
|
19
19
|
import { loadPrompt } from "./prompt-loader.js";
|
|
20
|
+
import { isPnpmInstall } from "../../shared/package-manager-detection.js";
|
|
20
21
|
import { buildDoctorHealIssuePayload, buildDoctorHealSummary, buildWorkflowDispatchContent, } from "./workflow-protocol.js";
|
|
21
22
|
import { restoreGsdWorkflowTools, scopeGsdWorkflowToolsForDispatch, } from "./bootstrap/register-hooks.js";
|
|
22
23
|
const UPDATE_REGISTRY_URL = "https://registry.npmjs.org/@opengsd%2fgsd-pi/latest";
|
|
@@ -42,6 +43,8 @@ function isBunInstall(argv1 = process.argv[1]) {
|
|
|
42
43
|
function resolveInstallCommand(pkg) {
|
|
43
44
|
if (isBunInstall())
|
|
44
45
|
return `bun add -g ${pkg}`;
|
|
46
|
+
if (isPnpmInstall())
|
|
47
|
+
return `pnpm add -g ${pkg}`;
|
|
45
48
|
return `npm install -g ${pkg}`;
|
|
46
49
|
}
|
|
47
50
|
async function fetchLatestVersionForCommand() {
|