@opengsd/gsd-pi 1.0.2-dev.e9a1b49 → 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 +36 -55
- 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-post-create-hook.js +117 -0
- 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/dist/worktree-cli.d.ts +0 -2
- package/dist/worktree-cli.js +21 -9
- package/package.json +5 -2
- package/packages/cloud-mcp-gateway/bin/gsd-cloud-mcp-gateway.js +14 -0
- package/packages/cloud-mcp-gateway/package.json +4 -3
- 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/bin/gsd-mcp-server.js +14 -0
- 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 +5 -4
- 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/bin/pi-ai.js +14 -0
- 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 +73 -226
- 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 +3 -2
- 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/deps.js +10 -0
- 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 +47 -57
- 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-post-create-hook.test.ts +141 -1
- 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-post-create-hook.ts +127 -0
- 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/tsconfig.extensions.tsbuildinfo +0 -1
- /package/dist/web/standalone/.next/static/{BEjZM0MLHLibeMFbjtMol → tH1tnDYt1E0hK9Ien73Z0}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{BEjZM0MLHLibeMFbjtMol → tH1tnDYt1E0hK9Ien73Z0}/_ssgManifest.js +0 -0
|
@@ -5,11 +5,20 @@
|
|
|
5
5
|
import { createRequire } from 'module'
|
|
6
6
|
import { dirname, join } from 'path'
|
|
7
7
|
import { fileURLToPath } from 'url'
|
|
8
|
+
import { detectPackageManager } from './npm-global.js'
|
|
8
9
|
|
|
9
10
|
const require = createRequire(import.meta.url)
|
|
10
11
|
const { GSD_PI_BRAND } = require(join(dirname(fileURLToPath(import.meta.url)), '..', 'lib', 'logo.cjs'))
|
|
11
12
|
|
|
12
13
|
export function parseInstalledVersion(npmListJson) {
|
|
14
|
+
if (Array.isArray(npmListJson)) {
|
|
15
|
+
for (const entry of npmListJson) {
|
|
16
|
+
const found = parseInstalledVersion(entry)
|
|
17
|
+
if (found) return found
|
|
18
|
+
}
|
|
19
|
+
return null
|
|
20
|
+
}
|
|
21
|
+
|
|
13
22
|
if (!npmListJson || typeof npmListJson !== 'object') return null
|
|
14
23
|
|
|
15
24
|
const direct = npmListJson.dependencies?.['@opengsd/gsd-pi']?.version
|
|
@@ -30,6 +39,10 @@ export function parseInstalledVersion(npmListJson) {
|
|
|
30
39
|
return walk(npmListJson)
|
|
31
40
|
}
|
|
32
41
|
|
|
42
|
+
function getPackageManagerBin(packageManager) {
|
|
43
|
+
return process.platform === 'win32' ? `${packageManager}.cmd` : packageManager
|
|
44
|
+
}
|
|
45
|
+
|
|
33
46
|
/**
|
|
34
47
|
* Decide install action for non-interactive or pre-prompt routing.
|
|
35
48
|
*/
|
|
@@ -39,11 +52,12 @@ export function compareActions({ installed, yesMode }) {
|
|
|
39
52
|
return 'prompt'
|
|
40
53
|
}
|
|
41
54
|
|
|
42
|
-
export async function detectInstalledVersion() {
|
|
55
|
+
export async function detectInstalledVersion(options = {}) {
|
|
43
56
|
const { execFileSync } = await import('child_process')
|
|
44
|
-
const
|
|
57
|
+
const packageManager = options.packageManager ?? detectPackageManager()
|
|
58
|
+
const bin = getPackageManagerBin(packageManager)
|
|
45
59
|
try {
|
|
46
|
-
const raw = execFileSync(
|
|
60
|
+
const raw = execFileSync(bin, ['list', '-g', '@opengsd/gsd-pi', '--json'], {
|
|
47
61
|
encoding: 'utf-8',
|
|
48
62
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
49
63
|
timeout: 30_000,
|
|
@@ -1,14 +1,61 @@
|
|
|
1
1
|
import { execFileSync, spawn } from 'child_process'
|
|
2
|
-
import {
|
|
2
|
+
import { homedir } from 'os'
|
|
3
|
+
import { join, resolve as resolvePath, sep } from 'path'
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
const PACKAGE_MANAGERS = new Set(['npm', 'pnpm'])
|
|
6
|
+
|
|
7
|
+
function normalizePackageManager(value) {
|
|
8
|
+
return PACKAGE_MANAGERS.has(value) ? value : 'npm'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function hasPnpmPath(value = '') {
|
|
12
|
+
const normalized = value.replace(/\\/g, '/').toLowerCase()
|
|
13
|
+
return (
|
|
14
|
+
normalized.includes('/.pnpm/') ||
|
|
15
|
+
normalized.endsWith('/pnpm') ||
|
|
16
|
+
normalized.endsWith('/pnpm.cjs') ||
|
|
17
|
+
normalized.endsWith('/pnpm.js')
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function pathStartsWith(pathValue = '', dir) {
|
|
22
|
+
if (!pathValue) return false
|
|
23
|
+
const resolvedPath = resolvePath(pathValue)
|
|
24
|
+
const resolvedDir = resolvePath(dir)
|
|
25
|
+
return resolvedPath === resolvedDir || resolvedPath.startsWith(resolvedDir + sep)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function hasPnpmBinPath(env, argv1) {
|
|
29
|
+
const pnpmBinDirs = []
|
|
30
|
+
if (env.PNPM_HOME) pnpmBinDirs.push(env.PNPM_HOME)
|
|
31
|
+
pnpmBinDirs.push(join(homedir(), 'Library', 'pnpm'))
|
|
32
|
+
pnpmBinDirs.push(join(homedir(), '.local', 'share', 'pnpm'))
|
|
33
|
+
|
|
34
|
+
return pnpmBinDirs.some((dir) => pathStartsWith(argv1, dir) || pathStartsWith(env.npm_execpath, dir))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function detectPackageManager(env = process.env, argv1 = process.argv[1]) {
|
|
38
|
+
const userAgent = env.npm_config_user_agent || ''
|
|
39
|
+
if (userAgent.startsWith('pnpm/')) return 'pnpm'
|
|
40
|
+
// Installer runs under npm during npm install; keep that context authoritative.
|
|
41
|
+
if (userAgent.startsWith('npm/')) return 'npm'
|
|
42
|
+
|
|
43
|
+
if (hasPnpmPath(env.npm_execpath || '')) return 'pnpm'
|
|
44
|
+
if (hasPnpmPath(argv1 || '')) return 'pnpm'
|
|
45
|
+
if (hasPnpmBinPath(env, argv1)) return 'pnpm'
|
|
46
|
+
|
|
47
|
+
return 'npm'
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function getPackageManagerBin(packageManager) {
|
|
51
|
+
const bin = normalizePackageManager(packageManager)
|
|
52
|
+
return process.platform === 'win32' ? `${bin}.cmd` : bin
|
|
6
53
|
}
|
|
7
54
|
|
|
8
|
-
const
|
|
55
|
+
const PM_OUTPUT_LIMIT = 64 * 1024
|
|
9
56
|
|
|
10
|
-
function
|
|
11
|
-
return execFileSync(
|
|
57
|
+
function runPackageManager(packageManager, args) {
|
|
58
|
+
return execFileSync(getPackageManagerBin(packageManager), args, {
|
|
12
59
|
encoding: 'utf-8',
|
|
13
60
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
14
61
|
timeout: 120_000,
|
|
@@ -16,30 +63,30 @@ function runNpm(args) {
|
|
|
16
63
|
}).trim()
|
|
17
64
|
}
|
|
18
65
|
|
|
19
|
-
function
|
|
66
|
+
function formatPackageManagerFailure(packageManager, result) {
|
|
20
67
|
const output = `${result.stderr}\n${result.stdout}`.trim()
|
|
21
68
|
const meaningful = output
|
|
22
69
|
.split('\n')
|
|
23
|
-
.filter((line) =>
|
|
70
|
+
.filter((line) => line.trim() && !/^(?:npm\s+warn|warn)\b/i.test(line.trim()))
|
|
24
71
|
.slice(-3)
|
|
25
72
|
.join('; ')
|
|
26
|
-
return meaningful || result.error?.message ||
|
|
73
|
+
return meaningful || result.error?.message || `${packageManager} install failed`
|
|
27
74
|
}
|
|
28
75
|
|
|
29
76
|
function appendLimited(value, chunk) {
|
|
30
|
-
if (value.length >=
|
|
31
|
-
return value + chunk.slice(0,
|
|
77
|
+
if (value.length >= PM_OUTPUT_LIMIT) return value
|
|
78
|
+
return value + chunk.slice(0, PM_OUTPUT_LIMIT - value.length)
|
|
32
79
|
}
|
|
33
80
|
|
|
34
|
-
function
|
|
81
|
+
function runPackageManagerAsync(packageManager, args, {
|
|
35
82
|
captureStdout = false,
|
|
36
83
|
cwd,
|
|
37
84
|
timeout = 300_000,
|
|
38
85
|
} = {}) {
|
|
39
|
-
const
|
|
86
|
+
const bin = getPackageManagerBin(packageManager)
|
|
40
87
|
|
|
41
88
|
return new Promise((resolve) => {
|
|
42
|
-
const child = spawn(
|
|
89
|
+
const child = spawn(bin, args, {
|
|
43
90
|
cwd,
|
|
44
91
|
shell: process.platform === 'win32',
|
|
45
92
|
stdio: ['ignore', captureStdout ? 'pipe' : 'ignore', 'pipe'],
|
|
@@ -85,7 +132,7 @@ function runNpmAsync(args, {
|
|
|
85
132
|
ok: false,
|
|
86
133
|
stdout,
|
|
87
134
|
stderr,
|
|
88
|
-
error: new Error(
|
|
135
|
+
error: new Error(`${packageManager} ${args.join(' ')} timed out after ${timeout}ms`),
|
|
89
136
|
})
|
|
90
137
|
return
|
|
91
138
|
}
|
|
@@ -100,20 +147,35 @@ function runNpmAsync(args, {
|
|
|
100
147
|
ok: false,
|
|
101
148
|
stdout,
|
|
102
149
|
stderr,
|
|
103
|
-
error: new Error(
|
|
150
|
+
error: new Error(`${packageManager} ${args.join(' ')} failed with ${reason}`),
|
|
104
151
|
})
|
|
105
152
|
})
|
|
106
153
|
})
|
|
107
154
|
}
|
|
108
155
|
|
|
109
|
-
export function getGlobalPaths() {
|
|
110
|
-
const
|
|
111
|
-
|
|
156
|
+
export function getGlobalPaths(options = {}) {
|
|
157
|
+
const packageManager = normalizePackageManager(options.packageManager ?? detectPackageManager())
|
|
158
|
+
|
|
159
|
+
if (packageManager === 'pnpm') {
|
|
160
|
+
const binDir = runPackageManager(packageManager, ['bin', '-g'])
|
|
161
|
+
const root = runPackageManager(packageManager, ['root', '-g'])
|
|
162
|
+
return {
|
|
163
|
+
prefix: binDir,
|
|
164
|
+
root,
|
|
165
|
+
binDir,
|
|
166
|
+
packageRoot: join(root, '@opengsd', 'gsd-pi'),
|
|
167
|
+
packageManager,
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const prefix = runPackageManager(packageManager, ['prefix', '-g'])
|
|
172
|
+
const root = runPackageManager(packageManager, ['root', '-g'])
|
|
112
173
|
return {
|
|
113
174
|
prefix,
|
|
114
175
|
root,
|
|
115
176
|
binDir: process.platform === 'win32' ? prefix : join(prefix, 'bin'),
|
|
116
177
|
packageRoot: join(root, '@opengsd', 'gsd-pi'),
|
|
178
|
+
packageManager,
|
|
117
179
|
}
|
|
118
180
|
}
|
|
119
181
|
|
|
@@ -121,33 +183,41 @@ export function getLocalPackageRoot(cwd = process.cwd()) {
|
|
|
121
183
|
return join(cwd, 'node_modules', '@opengsd', 'gsd-pi')
|
|
122
184
|
}
|
|
123
185
|
|
|
124
|
-
export async function installGlobalPackage(version) {
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
'--ignore-scripts',
|
|
129
|
-
|
|
130
|
-
|
|
186
|
+
export async function installGlobalPackage(version, options = {}) {
|
|
187
|
+
const packageManager = normalizePackageManager(options.packageManager ?? detectPackageManager())
|
|
188
|
+
const packageSpec = `@opengsd/gsd-pi@${version}`
|
|
189
|
+
const installArgs = packageManager === 'pnpm'
|
|
190
|
+
? ['add', '-g', '--ignore-scripts', packageSpec]
|
|
191
|
+
: ['install', '-g', '--ignore-scripts', packageSpec]
|
|
192
|
+
|
|
193
|
+
const result = await runPackageManagerAsync(packageManager, installArgs)
|
|
131
194
|
if (!result.ok) {
|
|
132
|
-
throw new Error(
|
|
195
|
+
throw new Error(formatPackageManagerFailure(packageManager, result))
|
|
133
196
|
}
|
|
134
|
-
const rootResult = await
|
|
197
|
+
const rootResult = await runPackageManagerAsync(packageManager, ['root', '-g'], {
|
|
135
198
|
captureStdout: true,
|
|
136
199
|
timeout: 120_000,
|
|
137
200
|
})
|
|
138
201
|
if (!rootResult.ok) {
|
|
139
|
-
throw new Error(
|
|
202
|
+
throw new Error(formatPackageManagerFailure(packageManager, rootResult))
|
|
140
203
|
}
|
|
141
204
|
return join(rootResult.stdout.trim(), '@opengsd', 'gsd-pi')
|
|
142
205
|
}
|
|
143
206
|
|
|
144
|
-
export async function installLocalPackage(version, cwd = process.cwd()) {
|
|
145
|
-
const
|
|
146
|
-
|
|
207
|
+
export async function installLocalPackage(version, cwd = process.cwd(), options = {}) {
|
|
208
|
+
const packageManager = normalizePackageManager(options.packageManager ?? detectPackageManager())
|
|
209
|
+
const packageSpec = `@opengsd/gsd-pi@${version}`
|
|
210
|
+
const installArgs = packageManager === 'pnpm'
|
|
211
|
+
? ['add', '--ignore-scripts', packageSpec]
|
|
212
|
+
: ['install', '--ignore-scripts', packageSpec]
|
|
213
|
+
|
|
214
|
+
const result = await runPackageManagerAsync(
|
|
215
|
+
packageManager,
|
|
216
|
+
installArgs,
|
|
147
217
|
{ cwd },
|
|
148
218
|
)
|
|
149
219
|
if (!result.ok) {
|
|
150
|
-
throw new Error(
|
|
220
|
+
throw new Error(formatPackageManagerFailure(packageManager, result))
|
|
151
221
|
}
|
|
152
222
|
return getLocalPackageRoot(cwd)
|
|
153
223
|
}
|
package/scripts/install.js
CHANGED
|
@@ -71,6 +71,7 @@ if (HAS_HELP) {
|
|
|
71
71
|
|
|
72
72
|
${colors.yellow}Usage:${colors.reset}
|
|
73
73
|
npx @opengsd/gsd-pi@latest Install GSD-Pi globally (recommended)
|
|
74
|
+
pnpm dlx @opengsd/gsd-pi@latest Install GSD-Pi globally with pnpm
|
|
74
75
|
npx @opengsd/gsd-pi@latest --local Install to current project (advanced)
|
|
75
76
|
|
|
76
77
|
${colors.yellow}Options:${colors.reset}
|
|
@@ -29,7 +29,7 @@ import { dirname, join } from "node:path";
|
|
|
29
29
|
import { PartialMessageBuilder, ZERO_USAGE, mapUsage } from "./partial-builder.js";
|
|
30
30
|
import { buildWorkflowMcpServers, resolveWorkflowMcpProjectRoot } from "../gsd/workflow-mcp.js";
|
|
31
31
|
import { loadProjectGSDPreferences } from "../gsd/preferences.js";
|
|
32
|
-
import { discoverMcpServerNames, computeMcpDisallowedTools } from "../gsd/mcp-filter.js";
|
|
32
|
+
import { discoverMcpServerNames, discoverWorkflowMcpServerName, computeMcpDisallowedTools } from "../gsd/mcp-filter.js";
|
|
33
33
|
import { showInterviewRound, type Question, type RoundResult } from "../shared/tui.js";
|
|
34
34
|
import type {
|
|
35
35
|
SDKAssistantMessage,
|
|
@@ -59,6 +59,10 @@ type ToolCallWithExternalResult = ToolCall & {
|
|
|
59
59
|
externalResult?: ExternalToolResultPayload;
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
+
interface PromptToolContextOptions {
|
|
63
|
+
workflowMcpServerName?: string | null;
|
|
64
|
+
}
|
|
65
|
+
|
|
62
66
|
/** `SimpleStreamOptions` extended with an optional extension UI context for elicitation dialogs. */
|
|
63
67
|
interface ClaudeCodeStreamOptions extends SimpleStreamOptions {
|
|
64
68
|
extensionUIContext?: ExtensionUIContext;
|
|
@@ -331,7 +335,7 @@ function extractMessageText(msg: { role: string; content: unknown }): string {
|
|
|
331
335
|
* user turns in its own output. XML tags read as document structure and
|
|
332
336
|
* don't get mirrored in free text.
|
|
333
337
|
*/
|
|
334
|
-
export function buildPromptFromContext(context: Context): string {
|
|
338
|
+
export function buildPromptFromContext(context: Context, toolContext: PromptToolContextOptions = {}): string {
|
|
335
339
|
const hasContent = Boolean(context.systemPrompt) || context.messages.some((m) => extractMessageText(m));
|
|
336
340
|
if (!hasContent) return "";
|
|
337
341
|
|
|
@@ -339,6 +343,14 @@ export function buildPromptFromContext(context: Context): string {
|
|
|
339
343
|
"Respond only to the final user message below. " +
|
|
340
344
|
"Do not emit <user_message>, <assistant_message>, or <prior_system_context> tags in your response.",
|
|
341
345
|
];
|
|
346
|
+
const workflowToolLine = toolContext.workflowMcpServerName
|
|
347
|
+
? "- GSD workflow tools (gsd_exec, gsd_slice_complete, gsd_task_complete, gsd_plan_slice, gsd_save_gate_result, etc.) " +
|
|
348
|
+
`are MCP tools — call them as mcp__${toolContext.workflowMcpServerName}__<tool_name> ` +
|
|
349
|
+
`(e.g. mcp__${toolContext.workflowMcpServerName}__gsd_exec, mcp__${toolContext.workflowMcpServerName}__gsd_save_gate_result)\n`
|
|
350
|
+
: "- GSD workflow MCP tools are unavailable in this Claude Code run.\n";
|
|
351
|
+
const toolSearchLine = toolContext.workflowMcpServerName
|
|
352
|
+
? "- ToolSearch is NOT available — never use it to discover tools; invoke the MCP tool directly\n"
|
|
353
|
+
: "- ToolSearch is NOT available — never use it to discover tools\n";
|
|
342
354
|
|
|
343
355
|
// The prior system context lists pi-native tool names (lowercase: bash, read, gsd_exec, etc.)
|
|
344
356
|
// but this process runs inside Claude Code where tool names differ. Inject a remapping note
|
|
@@ -349,10 +361,8 @@ export function buildPromptFromContext(context: Context): string {
|
|
|
349
361
|
"You are running inside Claude Code. Use these exact tool names — do not use lowercase or pi-native names:\n" +
|
|
350
362
|
"- Shell commands: 'Bash' (not 'bash')\n" +
|
|
351
363
|
"- File operations: 'Read', 'Write', 'Edit', 'Glob', 'Grep' (PascalCase, not lowercase)\n" +
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
"(e.g. mcp__gsd-workflow__gsd_exec, mcp__gsd-workflow__gsd_save_gate_result)\n" +
|
|
355
|
-
"- ToolSearch is NOT available — never use it to discover tools; invoke the MCP tool directly\n" +
|
|
364
|
+
workflowToolLine +
|
|
365
|
+
toolSearchLine +
|
|
356
366
|
"</tool_context>",
|
|
357
367
|
);
|
|
358
368
|
|
|
@@ -1441,6 +1451,16 @@ function mapThinkingLevelToAnthropicEffort(level: ThinkingLevel | undefined, mod
|
|
|
1441
1451
|
}
|
|
1442
1452
|
}
|
|
1443
1453
|
|
|
1454
|
+
function workflowMcpServerNameFromAllowedTools(allowedTools: unknown): string | undefined {
|
|
1455
|
+
if (!Array.isArray(allowedTools)) return undefined;
|
|
1456
|
+
for (const toolName of allowedTools) {
|
|
1457
|
+
if (typeof toolName !== "string") continue;
|
|
1458
|
+
const match = /^mcp__(.+)__\*$/.exec(toolName);
|
|
1459
|
+
if (match?.[1]) return match[1];
|
|
1460
|
+
}
|
|
1461
|
+
return undefined;
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1444
1464
|
/**
|
|
1445
1465
|
* Build the options object passed to the Claude Agent SDK's `query()` call.
|
|
1446
1466
|
*
|
|
@@ -1468,16 +1488,19 @@ export function buildSdkOptions(
|
|
|
1468
1488
|
|
|
1469
1489
|
const preferences = loadProjectGSDPreferences(projectRoot);
|
|
1470
1490
|
const mcpConfig = preferences?.preferences.claude_code_mcp;
|
|
1471
|
-
const workflowServerName = mcpServers ? Object.keys(mcpServers)[0] : undefined;
|
|
1472
1491
|
|
|
1473
1492
|
// Always discover project MCPs — needed for both duplicate detection and filtering.
|
|
1474
1493
|
const discovered = discoverMcpServerNames(projectRoot);
|
|
1494
|
+
const injectedWorkflowServerName = mcpServers ? Object.keys(mcpServers)[0] : undefined;
|
|
1495
|
+
const projectWorkflowServerName = discoverWorkflowMcpServerName(projectRoot);
|
|
1496
|
+
const workflowServerName = projectWorkflowServerName ?? injectedWorkflowServerName;
|
|
1475
1497
|
|
|
1476
1498
|
// If the workflow MCP is already declared in the project's .mcp.json or
|
|
1477
1499
|
// .claude/settings.json, do not inject it again via mcpServers. Passing the
|
|
1478
1500
|
// same server name from two sources causes a duplicate registration conflict
|
|
1479
1501
|
// that prevents the MCP server from loading (tools become unavailable).
|
|
1480
|
-
const workflowAlreadyInProject =
|
|
1502
|
+
const workflowAlreadyInProject = projectWorkflowServerName !== undefined
|
|
1503
|
+
|| (injectedWorkflowServerName !== undefined && discovered.includes(injectedWorkflowServerName));
|
|
1481
1504
|
let filteredMcpServers = workflowAlreadyInProject ? undefined : mcpServers;
|
|
1482
1505
|
let extraDisallowedTools: string[] = [];
|
|
1483
1506
|
let workflowExplicitlyBlocked = false;
|
|
@@ -1847,8 +1870,6 @@ async function pumpSdkMessages(
|
|
|
1847
1870
|
options.signal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
1848
1871
|
}
|
|
1849
1872
|
|
|
1850
|
-
const prompt = buildPromptFromContext(context);
|
|
1851
|
-
const queryPrompt = buildSdkQueryPrompt(context, prompt);
|
|
1852
1873
|
const permissionMode = await resolveClaudePermissionMode();
|
|
1853
1874
|
const uiContext = (options as ClaudeCodeStreamOptions | undefined)?.extensionUIContext;
|
|
1854
1875
|
const onExternalToolCall = (options as ClaudeCodeStreamOptions | undefined)?.onExternalToolCall;
|
|
@@ -1862,7 +1883,7 @@ async function pumpSdkMessages(
|
|
|
1862
1883
|
({ behavior: "allow", toolUseID: opts.toolUseID }));
|
|
1863
1884
|
const sdkOpts = buildSdkOptions(
|
|
1864
1885
|
modelId,
|
|
1865
|
-
|
|
1886
|
+
"",
|
|
1866
1887
|
{ permissionMode },
|
|
1867
1888
|
{
|
|
1868
1889
|
cwd,
|
|
@@ -1875,6 +1896,10 @@ async function pumpSdkMessages(
|
|
|
1875
1896
|
: {}),
|
|
1876
1897
|
},
|
|
1877
1898
|
);
|
|
1899
|
+
const prompt = buildPromptFromContext(context, {
|
|
1900
|
+
workflowMcpServerName: workflowMcpServerNameFromAllowedTools(sdkOpts.allowedTools),
|
|
1901
|
+
});
|
|
1902
|
+
const queryPrompt = buildSdkQueryPrompt(context, prompt);
|
|
1878
1903
|
|
|
1879
1904
|
const queryResult = sdk.query({
|
|
1880
1905
|
prompt: queryPrompt,
|
|
@@ -407,6 +407,30 @@ describe("stream-adapter — no transcript fabrication (#4102)", () => {
|
|
|
407
407
|
const prompt = buildPromptFromContext(context);
|
|
408
408
|
assert.equal(prompt, "", "empty context must not emit a bare directive");
|
|
409
409
|
});
|
|
410
|
+
|
|
411
|
+
test("buildPromptFromContext uses the active workflow MCP server name", () => {
|
|
412
|
+
const context: Context = {
|
|
413
|
+
messages: [{ role: "user", content: "Check status" } as Message],
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
const prompt = buildPromptFromContext(context, { workflowMcpServerName: "custom-workflow" });
|
|
417
|
+
|
|
418
|
+
assert.ok(prompt.includes("mcp__custom-workflow__<tool_name>"));
|
|
419
|
+
assert.ok(prompt.includes("mcp__custom-workflow__gsd_exec"));
|
|
420
|
+
assert.ok(!prompt.includes("mcp__gsd-workflow__<tool_name>"));
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
test("buildPromptFromContext does not advertise workflow MCP tools when unavailable", () => {
|
|
424
|
+
const context: Context = {
|
|
425
|
+
messages: [{ role: "user", content: "Check status" } as Message],
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
const prompt = buildPromptFromContext(context);
|
|
429
|
+
|
|
430
|
+
assert.ok(prompt.includes("GSD workflow MCP tools are unavailable"));
|
|
431
|
+
assert.ok(!prompt.includes("mcp__gsd-workflow__<tool_name>"));
|
|
432
|
+
assert.ok(!prompt.includes("mcp__gsd-workflow__gsd_exec"));
|
|
433
|
+
});
|
|
410
434
|
});
|
|
411
435
|
|
|
412
436
|
describe("stream-adapter — Claude Code external tool results", () => {
|
|
@@ -921,18 +945,21 @@ describe("stream-adapter — session persistence (#2859)", () => {
|
|
|
921
945
|
}
|
|
922
946
|
});
|
|
923
947
|
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
948
|
+
test("buildSdkOptions prefers custom workflow MCP question tools over native AskUserQuestion", () => {
|
|
949
|
+
const restore = setWorkflowMcpEnv({
|
|
950
|
+
GSD_WORKFLOW_MCP_COMMAND: "node",
|
|
927
951
|
GSD_WORKFLOW_MCP_NAME: "custom-workflow",
|
|
928
952
|
GSD_WORKFLOW_MCP_ARGS: JSON.stringify(["packages/mcp-server/dist/cli.js"]),
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
953
|
+
GSD_WORKFLOW_MCP_ENV: JSON.stringify({ GSD_CLI_PATH: "/tmp/gsd" }),
|
|
954
|
+
GSD_WORKFLOW_MCP_CWD: "/tmp/project",
|
|
955
|
+
});
|
|
956
|
+
const originalCwd = process.cwd();
|
|
957
|
+
const emptyDir = mkdtempSync(join(tmpdir(), "claude-mcp-custom-inject-"));
|
|
958
|
+
try {
|
|
959
|
+
process.chdir(emptyDir);
|
|
933
960
|
|
|
934
|
-
|
|
935
|
-
|
|
961
|
+
const options = buildSdkOptions("claude-sonnet-4-20250514", "test");
|
|
962
|
+
const mcpServers = options.mcpServers as Record<string, any>;
|
|
936
963
|
assert.ok(mcpServers?.["custom-workflow"], "expected custom workflow server config");
|
|
937
964
|
assert.deepEqual(options.disallowedTools, ["AskUserQuestion"]);
|
|
938
965
|
assert.deepEqual(options.allowedTools, [
|
|
@@ -945,12 +972,14 @@ describe("stream-adapter — session persistence (#2859)", () => {
|
|
|
945
972
|
"Agent",
|
|
946
973
|
"WebFetch",
|
|
947
974
|
"WebSearch",
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
975
|
+
"mcp__custom-workflow__*",
|
|
976
|
+
]);
|
|
977
|
+
} finally {
|
|
978
|
+
process.chdir(originalCwd);
|
|
979
|
+
rmSync(emptyDir, { recursive: true, force: true });
|
|
980
|
+
restore();
|
|
981
|
+
}
|
|
982
|
+
});
|
|
954
983
|
|
|
955
984
|
test("buildSdkOptions auto-discovers bundled MCP server even without env hints", () => {
|
|
956
985
|
// Use setWorkflowMcpEnv with no values to save current state;
|
|
@@ -1059,7 +1088,7 @@ describe("stream-adapter — session persistence (#2859)", () => {
|
|
|
1059
1088
|
}
|
|
1060
1089
|
});
|
|
1061
1090
|
|
|
1062
|
-
|
|
1091
|
+
test("buildSdkOptions does not inject workflow MCP when already declared in project .mcp.json (avoids duplicate registration)", () => {
|
|
1063
1092
|
const restore = setWorkflowMcpEnv({
|
|
1064
1093
|
GSD_WORKFLOW_MCP_COMMAND: "node",
|
|
1065
1094
|
GSD_WORKFLOW_MCP_NAME: "gsd-workflow",
|
|
@@ -1089,10 +1118,48 @@ describe("stream-adapter — session persistence (#2859)", () => {
|
|
|
1089
1118
|
process.chdir(originalCwd);
|
|
1090
1119
|
rmSync(projectDir, { recursive: true, force: true });
|
|
1091
1120
|
restore();
|
|
1092
|
-
|
|
1093
|
-
|
|
1121
|
+
}
|
|
1122
|
+
});
|
|
1123
|
+
|
|
1124
|
+
test("buildSdkOptions uses project-declared custom workflow MCP namespace", () => {
|
|
1125
|
+
const restore = setWorkflowMcpEnv({
|
|
1126
|
+
GSD_WORKFLOW_MCP_COMMAND: "node",
|
|
1127
|
+
GSD_WORKFLOW_MCP_NAME: "gsd-workflow",
|
|
1128
|
+
GSD_WORKFLOW_MCP_ARGS: JSON.stringify(["packages/mcp-server/dist/cli.js"]),
|
|
1129
|
+
GSD_WORKFLOW_MCP_ENV: JSON.stringify({ GSD_CLI_PATH: "/tmp/gsd" }),
|
|
1130
|
+
GSD_WORKFLOW_MCP_CWD: "/tmp/project",
|
|
1131
|
+
});
|
|
1132
|
+
const originalCwd = process.cwd();
|
|
1133
|
+
const projectDir = mkdtempSync(join(tmpdir(), "claude-mcp-custom-project-"));
|
|
1134
|
+
try {
|
|
1135
|
+
writeFileSync(
|
|
1136
|
+
join(projectDir, ".mcp.json"),
|
|
1137
|
+
JSON.stringify({
|
|
1138
|
+
mcpServers: {
|
|
1139
|
+
"custom-workflow": {
|
|
1140
|
+
command: "node",
|
|
1141
|
+
args: ["custom-cli.js"],
|
|
1142
|
+
env: { GSD_WORKFLOW_PROJECT_ROOT: projectDir },
|
|
1143
|
+
},
|
|
1144
|
+
},
|
|
1145
|
+
}),
|
|
1146
|
+
);
|
|
1147
|
+
process.chdir(projectDir);
|
|
1148
|
+
const options = buildSdkOptions("claude-sonnet-4-20250514", "test");
|
|
1149
|
+
assert.equal(options.mcpServers, undefined, "should not inject default workflow MCP when project declares a workflow server");
|
|
1150
|
+
const allowedTools = options.allowedTools as string[];
|
|
1151
|
+
assert.ok(allowedTools.includes("mcp__custom-workflow__*"), "allowedTools must use the project workflow namespace");
|
|
1152
|
+
assert.ok(!allowedTools.includes("mcp__gsd-workflow__*"), "allowedTools must not advertise the absent default namespace");
|
|
1153
|
+
const disallowedTools = options.disallowedTools as string[];
|
|
1154
|
+
assert.ok(disallowedTools.includes("AskUserQuestion"), "AskUserQuestion should be suppressed when workflow is available");
|
|
1155
|
+
} finally {
|
|
1156
|
+
process.chdir(originalCwd);
|
|
1157
|
+
rmSync(projectDir, { recursive: true, force: true });
|
|
1158
|
+
restore();
|
|
1159
|
+
}
|
|
1160
|
+
});
|
|
1094
1161
|
|
|
1095
|
-
|
|
1162
|
+
test("buildSdkOptions preserves runtime callbacks such as onElicitation", () => {
|
|
1096
1163
|
const restore = setWorkflowMcpEnv({});
|
|
1097
1164
|
const onElicitation = async () => ({ action: "decline" as const });
|
|
1098
1165
|
try {
|
|
@@ -132,6 +132,19 @@ function formatLibraryList(libs: C7Library[], query: string): string {
|
|
|
132
132
|
return lines.join("\n");
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
function getFirstTextContent(result: { content?: unknown }): string | undefined {
|
|
136
|
+
const content = result.content;
|
|
137
|
+
if (!Array.isArray(content)) return undefined;
|
|
138
|
+
const textBlock = content.find(
|
|
139
|
+
(block: unknown) =>
|
|
140
|
+
typeof block === "object" &&
|
|
141
|
+
block !== null &&
|
|
142
|
+
(block as { type?: unknown }).type === "text" &&
|
|
143
|
+
typeof (block as { text?: unknown }).text === "string",
|
|
144
|
+
) as { text: string } | undefined;
|
|
145
|
+
return textBlock?.text.trim() || undefined;
|
|
146
|
+
}
|
|
147
|
+
|
|
135
148
|
// ─── Tool details types ───────────────────────────────────────────────────────
|
|
136
149
|
|
|
137
150
|
interface ResolveDetails {
|
|
@@ -234,7 +247,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
234
247
|
const d = result.details as ResolveDetails | undefined;
|
|
235
248
|
if (isPartial) return new Text(theme.fg("warning", "Searching Context7..."), 0, 0);
|
|
236
249
|
if ((result as any).isError || d?.error) {
|
|
237
|
-
return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
|
|
250
|
+
return new Text(theme.fg("error", `Error: ${d?.error ?? getFirstTextContent(result) ?? "unknown"}`), 0, 0);
|
|
238
251
|
}
|
|
239
252
|
let text = theme.fg("success", `${d?.resultCount ?? 0} ${d?.resultCount === 1 ? "library" : "libraries"} found`);
|
|
240
253
|
if (d?.cached) text += theme.fg("dim", " (cached)");
|
|
@@ -389,7 +402,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
389
402
|
|
|
390
403
|
if (isPartial) return new Text(theme.fg("warning", "Fetching documentation..."), 0, 0);
|
|
391
404
|
if ((result as any).isError || d?.error) {
|
|
392
|
-
return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
|
|
405
|
+
return new Text(theme.fg("error", `Error: ${d?.error ?? getFirstTextContent(result) ?? "unknown"}`), 0, 0);
|
|
393
406
|
}
|
|
394
407
|
|
|
395
408
|
let text = theme.fg("success", `${(d?.charCount ?? 0).toLocaleString()} chars`);
|
|
@@ -13,6 +13,7 @@ import { resolve } from "node:path";
|
|
|
13
13
|
import type { ExtensionAPI, Theme } from "@gsd/pi-coding-agent";
|
|
14
14
|
import { Editor, type EditorTheme, Key, matchesKey, Text, truncateToWidth, wrapTextWithAnsi } from "@gsd/pi-tui";
|
|
15
15
|
import { Type } from "@sinclair/typebox";
|
|
16
|
+
import { renderSharedDialogFrame } from "./shared/dialog-frame.js";
|
|
16
17
|
import { makeUI } from "./shared/tui.js";
|
|
17
18
|
import { maskEditorLine, type ProgressStatus } from "./shared/mod.js";
|
|
18
19
|
import { parseSecretsManifest, formatSecretsManifest } from "./gsd/files.js";
|
|
@@ -43,6 +44,10 @@ function maskPreview(value: string): string {
|
|
|
43
44
|
return `${value.slice(0, 4)}${"*".repeat(Math.max(4, value.length - 8))}${value.slice(-4)}`;
|
|
44
45
|
}
|
|
45
46
|
|
|
47
|
+
function dialogContentWidth(width: number): number {
|
|
48
|
+
return width < 4 ? Math.max(1, width) : Math.max(1, width - 4);
|
|
49
|
+
}
|
|
50
|
+
|
|
46
51
|
function shellEscapeSingle(value: string): string {
|
|
47
52
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
48
53
|
}
|
|
@@ -168,10 +173,10 @@ async function collectOneSecret(
|
|
|
168
173
|
|
|
169
174
|
function render(width: number): string[] {
|
|
170
175
|
if (cachedLines) return cachedLines;
|
|
176
|
+
const contentWidth = dialogContentWidth(width);
|
|
171
177
|
const lines: string[] = [];
|
|
172
|
-
const add = (s: string) => lines.push(truncateToWidth(s,
|
|
178
|
+
const add = (s: string) => lines.push(truncateToWidth(s, contentWidth));
|
|
173
179
|
|
|
174
|
-
add(theme.fg("accent", "─".repeat(width)));
|
|
175
180
|
add(theme.fg("dim", ` Page ${pageIndex + 1}/${totalPages} · Secure Env Setup`));
|
|
176
181
|
lines.push("");
|
|
177
182
|
|
|
@@ -187,7 +192,7 @@ async function collectOneSecret(
|
|
|
187
192
|
for (let g = 0; g < guidance.length; g++) {
|
|
188
193
|
const prefix = ` ${g + 1}. `;
|
|
189
194
|
const step = guidance[g] as string;
|
|
190
|
-
const wrappedLines = wrapTextWithAnsi(step,
|
|
195
|
+
const wrappedLines = wrapTextWithAnsi(step, Math.max(1, contentWidth - 4));
|
|
191
196
|
for (let w = 0; w < wrappedLines.length; w++) {
|
|
192
197
|
const indent = w === 0 ? prefix : " ".repeat(prefix.length);
|
|
193
198
|
lines.push(theme.fg("dim", `${indent}${wrappedLines[w]}`));
|
|
@@ -205,16 +210,15 @@ async function collectOneSecret(
|
|
|
205
210
|
|
|
206
211
|
// Editor
|
|
207
212
|
add(theme.fg("muted", " Enter value:"));
|
|
208
|
-
for (const line of editor.render(
|
|
213
|
+
for (const line of editor.render(Math.max(1, contentWidth - 2))) {
|
|
209
214
|
add(theme.fg("text", maskEditorLine(line)));
|
|
210
215
|
}
|
|
211
216
|
|
|
212
217
|
lines.push("");
|
|
213
|
-
|
|
214
|
-
add(theme.fg("accent", "─".repeat(width)));
|
|
218
|
+
const footer = theme.fg("dim", " enter to confirm | ctrl+s or esc to skip | esc cancels");
|
|
215
219
|
|
|
216
|
-
cachedLines = lines;
|
|
217
|
-
return
|
|
220
|
+
cachedLines = renderSharedDialogFrame(theme, "Secure Env Setup", lines, width, { footer });
|
|
221
|
+
return cachedLines;
|
|
218
222
|
}
|
|
219
223
|
|
|
220
224
|
return {
|
|
@@ -286,13 +290,11 @@ export async function showSecretsSummary(
|
|
|
286
290
|
function render(width: number): string[] {
|
|
287
291
|
if (cachedLines) return cachedLines;
|
|
288
292
|
|
|
289
|
-
const
|
|
293
|
+
const contentWidth = dialogContentWidth(width);
|
|
294
|
+
const ui = makeUI(theme, contentWidth);
|
|
290
295
|
const lines: string[] = [];
|
|
291
296
|
const push = (...rows: string[][]) => { for (const r of rows) lines.push(...r); };
|
|
292
297
|
|
|
293
|
-
push(ui.bar());
|
|
294
|
-
push(ui.blank());
|
|
295
|
-
push(ui.header(" Secrets Summary"));
|
|
296
298
|
push(ui.blank());
|
|
297
299
|
|
|
298
300
|
for (const entry of entries) {
|
|
@@ -314,11 +316,10 @@ export async function showSecretsSummary(
|
|
|
314
316
|
}
|
|
315
317
|
|
|
316
318
|
push(ui.blank());
|
|
317
|
-
|
|
318
|
-
push(ui.bar());
|
|
319
|
+
const footer = ui.hints(["any key to continue"])[0] ?? "";
|
|
319
320
|
|
|
320
|
-
cachedLines = lines;
|
|
321
|
-
return
|
|
321
|
+
cachedLines = renderSharedDialogFrame(theme, "Secrets Summary", lines, width, { footer });
|
|
322
|
+
return cachedLines;
|
|
322
323
|
}
|
|
323
324
|
|
|
324
325
|
return {
|