gsd-pi 2.76.0 → 2.77.0
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 +45 -25
- package/dist/claude-cli-check.js +32 -3
- package/dist/mcp-server.d.ts +7 -0
- package/dist/mcp-server.js +35 -1
- package/dist/onboarding.js +45 -0
- package/dist/resource-loader.d.ts +1 -1
- package/dist/resource-loader.js +2 -8
- package/dist/resources/agents/researcher.md +1 -1
- package/dist/resources/extensions/claude-code-cli/readiness.js +31 -8
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +77 -17
- package/dist/resources/extensions/gsd/auto/loop.js +9 -0
- package/dist/resources/extensions/gsd/auto/phases.js +104 -11
- package/dist/resources/extensions/gsd/auto/run-unit.js +38 -2
- package/dist/resources/extensions/gsd/auto/session.js +22 -1
- package/dist/resources/extensions/gsd/auto-dispatch.js +16 -3
- package/dist/resources/extensions/gsd/auto-model-selection.js +53 -16
- package/dist/resources/extensions/gsd/auto-post-unit.js +25 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +14 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +32 -1
- package/dist/resources/extensions/gsd/auto-start.js +58 -57
- package/dist/resources/extensions/gsd/auto-verification.js +33 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +51 -53
- package/dist/resources/extensions/gsd/auto.js +70 -28
- package/dist/resources/extensions/gsd/blocked-models.js +68 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +93 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +39 -9
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +93 -0
- package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +3 -0
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +12 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +52 -6
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +84 -23
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +34 -2
- package/dist/resources/extensions/gsd/clean-root-preflight.js +93 -0
- package/dist/resources/extensions/gsd/commands-extract-learnings.js +54 -89
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +968 -23
- package/dist/resources/extensions/gsd/compaction-snapshot.js +121 -0
- package/dist/resources/extensions/gsd/complexity-classifier.js +5 -3
- package/dist/resources/extensions/gsd/db-writer.js +88 -16
- package/dist/resources/extensions/gsd/doctor-git-checks.js +23 -29
- package/dist/resources/extensions/gsd/doctor-providers.js +51 -5
- package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +1 -0
- package/dist/resources/extensions/gsd/error-classifier.js +31 -3
- package/dist/resources/extensions/gsd/exec-history.js +120 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +258 -0
- package/dist/resources/extensions/gsd/gitignore.js +1 -0
- package/dist/resources/extensions/gsd/gsd-db.js +168 -23
- package/dist/resources/extensions/gsd/guided-flow.js +190 -1
- package/dist/resources/extensions/gsd/health-widget.js +4 -1
- package/dist/resources/extensions/gsd/hook-emitter.js +108 -0
- package/dist/resources/extensions/gsd/init-wizard.js +15 -1
- package/dist/resources/extensions/gsd/key-manager.js +28 -0
- package/dist/resources/extensions/gsd/memory-backfill.js +126 -0
- package/dist/resources/extensions/gsd/memory-store.js +19 -0
- package/dist/resources/extensions/gsd/model-router.js +36 -3
- package/dist/resources/extensions/gsd/pre-execution-checks.js +44 -9
- package/dist/resources/extensions/gsd/preferences-types.js +9 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +83 -0
- package/dist/resources/extensions/gsd/preferences.js +17 -17
- package/dist/resources/extensions/gsd/prompt-loader.js +22 -7
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
- package/dist/resources/extensions/gsd/prompts/discuss.md +29 -2
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +96 -0
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +13 -5
- package/dist/resources/extensions/gsd/safety/safety-harness.js +5 -1
- package/dist/resources/extensions/gsd/state.js +43 -4
- package/dist/resources/extensions/gsd/token-counter.js +22 -5
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +16 -10
- package/dist/resources/extensions/gsd/tools/exec-search-tool.js +59 -0
- package/dist/resources/extensions/gsd/tools/exec-tool.js +126 -0
- package/dist/resources/extensions/gsd/tools/memory-tools.js +26 -1
- package/dist/resources/extensions/gsd/tools/resume-tool.js +23 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +20 -3
- package/dist/resources/extensions/gsd/workflow-mcp.js +3 -0
- package/dist/resources/extensions/gsd/workflow-templates/spike.md +6 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +50 -10
- package/dist/resources/extensions/search-the-web/command-search-provider.js +5 -4
- package/dist/resources/extensions/search-the-web/native-search.js +45 -13
- package/dist/resources/skills/api-design/SKILL.md +190 -0
- package/dist/resources/skills/create-mcp-server/SKILL.md +121 -0
- package/dist/resources/skills/decompose-into-slices/SKILL.md +139 -0
- package/dist/resources/skills/dependency-upgrade/SKILL.md +158 -0
- package/dist/resources/skills/design-an-interface/SKILL.md +102 -0
- package/dist/resources/skills/forensics/SKILL.md +153 -0
- package/dist/resources/skills/grill-me/SKILL.md +93 -0
- package/dist/resources/skills/handoff/SKILL.md +121 -0
- package/dist/resources/skills/observability/SKILL.md +174 -0
- package/dist/resources/skills/security-review/SKILL.md +181 -0
- package/dist/resources/skills/spike-wrap-up/SKILL.md +138 -0
- package/dist/resources/skills/tdd/SKILL.md +112 -0
- package/dist/resources/skills/verify-before-complete/SKILL.md +98 -0
- package/dist/resources/skills/write-docs/SKILL.md +82 -0
- package/dist/resources/skills/write-milestone-brief/SKILL.md +135 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.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/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 +10 -10
- package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/server.js +1 -1
- package/dist/welcome-screen.js +6 -1
- package/dist/wizard.js +2 -0
- package/package.json +1 -1
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/dist/remote-questions.d.ts +45 -0
- package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -0
- package/packages/mcp-server/dist/remote-questions.js +732 -0
- package/packages/mcp-server/dist/remote-questions.js.map +1 -0
- package/packages/mcp-server/dist/server.d.ts +7 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +70 -8
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/session-manager.d.ts +14 -0
- package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
- package/packages/mcp-server/dist/session-manager.js +49 -1
- package/packages/mcp-server/dist/session-manager.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +163 -25
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +4 -3
- package/packages/mcp-server/src/mcp-server.test.ts +67 -0
- package/packages/mcp-server/src/remote-questions.test.ts +294 -0
- package/packages/mcp-server/src/remote-questions.ts +916 -0
- package/packages/mcp-server/src/server.ts +89 -14
- package/packages/mcp-server/src/session-manager.ts +43 -1
- package/packages/mcp-server/src/workflow-tools.test.ts +146 -1
- package/packages/mcp-server/src/workflow-tools.ts +215 -43
- package/packages/mcp-server/tsconfig.test.json +19 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +12 -0
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +30 -0
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/src/agent-loop.ts +14 -0
- package/packages/pi-agent-core/src/types.ts +34 -0
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/models/custom.d.ts +38 -0
- package/packages/pi-ai/dist/models/custom.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/custom.js +41 -0
- package/packages/pi-ai/dist/models/custom.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +13 -0
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +27 -4
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +13 -4
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +80 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +60 -15
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.d.ts +10 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +16 -1
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/providers/think-tag-parser.d.ts +17 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.js +75 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.js.map +1 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.js +41 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js +12 -2
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +164 -14
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +15 -3
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +67 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +16 -3
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +67 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +289 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +1 -0
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/models/custom.ts +42 -0
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +1 -1
- package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -0
- package/packages/pi-ai/src/providers/anthropic-shared.ts +26 -5
- package/packages/pi-ai/src/providers/anthropic.ts +15 -4
- package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +98 -0
- package/packages/pi-ai/src/providers/openai-completions.ts +57 -16
- package/packages/pi-ai/src/providers/simple-options.ts +17 -1
- package/packages/pi-ai/src/providers/think-tag-parser.test.ts +44 -0
- package/packages/pi-ai/src/providers/think-tag-parser.ts +94 -0
- package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +200 -23
- package/packages/pi-ai/src/utils/oauth/github-copilot.ts +12 -2
- package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +84 -0
- package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +15 -5
- package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +84 -0
- package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +16 -5
- package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +363 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +3 -2
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +32 -2
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +4 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +35 -2
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +233 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +205 -2
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts +53 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.js +337 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +234 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/index.js +1 -0
- package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.d.ts +3 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.js +92 -12
- package/packages/pi-coding-agent/dist/core/model-discovery.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.test.js +16 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js +40 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js +203 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-discovery.test.js +61 -1
- package/packages/pi-coding-agent/dist/core/model-registry-discovery.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +90 -10
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.js +49 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.js +67 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +10 -6
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js +45 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +55 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +5 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +13 -7
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts +7 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +29 -21
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +13 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +3 -2
- package/packages/pi-coding-agent/src/core/agent-session.ts +38 -2
- package/packages/pi-coding-agent/src/core/extensions/index.ts +16 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +351 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +258 -0
- package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +269 -0
- package/packages/pi-coding-agent/src/core/hooks-runner.ts +460 -0
- package/packages/pi-coding-agent/src/core/index.ts +10 -0
- package/packages/pi-coding-agent/src/core/model-discovery.test.ts +19 -0
- package/packages/pi-coding-agent/src/core/model-discovery.ts +99 -12
- package/packages/pi-coding-agent/src/core/model-registry-auth-header.test.ts +44 -0
- package/packages/pi-coding-agent/src/core/model-registry-custom-caps.test.ts +245 -0
- package/packages/pi-coding-agent/src/core/model-registry-discovery.test.ts +75 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +102 -10
- package/packages/pi-coding-agent/src/core/redact-secrets.test.ts +86 -0
- package/packages/pi-coding-agent/src/core/redact-secrets.ts +58 -0
- package/packages/pi-coding-agent/src/core/session-manager.test.ts +65 -1
- package/packages/pi-coding-agent/src/core/session-manager.ts +10 -6
- package/packages/pi-coding-agent/src/core/settings-manager.ts +57 -0
- package/packages/pi-coding-agent/src/index.ts +16 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +6 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +16 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +36 -22
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +13 -1
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/pkg/package.json +1 -1
- package/scripts/link-workspace-packages.cjs +1 -0
- package/src/resources/agents/researcher.md +1 -1
- package/src/resources/extensions/claude-code-cli/readiness.ts +32 -8
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +78 -17
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +149 -5
- package/src/resources/extensions/gsd/auto/loop-deps.ts +14 -0
- package/src/resources/extensions/gsd/auto/loop.ts +9 -0
- package/src/resources/extensions/gsd/auto/phases.ts +131 -10
- package/src/resources/extensions/gsd/auto/run-unit.ts +40 -2
- package/src/resources/extensions/gsd/auto/session.ts +35 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +16 -3
- package/src/resources/extensions/gsd/auto-model-selection.ts +71 -15
- package/src/resources/extensions/gsd/auto-post-unit.ts +29 -3
- package/src/resources/extensions/gsd/auto-prompts.ts +28 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +26 -1
- package/src/resources/extensions/gsd/auto-start.ts +60 -68
- package/src/resources/extensions/gsd/auto-verification.ts +33 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +62 -63
- package/src/resources/extensions/gsd/auto.ts +73 -28
- package/src/resources/extensions/gsd/blocked-models.ts +98 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +120 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +40 -9
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +109 -0
- package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +5 -0
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +15 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +54 -6
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +89 -26
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +35 -2
- package/src/resources/extensions/gsd/clean-root-preflight.ts +111 -0
- package/src/resources/extensions/gsd/commands-extract-learnings.ts +55 -90
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +898 -32
- package/src/resources/extensions/gsd/compaction-snapshot.ts +165 -0
- package/src/resources/extensions/gsd/complexity-classifier.ts +5 -3
- package/src/resources/extensions/gsd/db-writer.ts +88 -17
- package/src/resources/extensions/gsd/doctor-git-checks.ts +23 -27
- package/src/resources/extensions/gsd/doctor-providers.ts +59 -6
- package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +2 -0
- package/src/resources/extensions/gsd/error-classifier.ts +36 -3
- package/src/resources/extensions/gsd/exec-history.ts +153 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +326 -0
- package/src/resources/extensions/gsd/gitignore.ts +1 -1
- package/src/resources/extensions/gsd/gsd-db.ts +186 -23
- package/src/resources/extensions/gsd/guided-flow.ts +222 -1
- package/src/resources/extensions/gsd/health-widget.ts +3 -1
- package/src/resources/extensions/gsd/hook-emitter.ts +188 -0
- package/src/resources/extensions/gsd/init-wizard.ts +15 -1
- package/src/resources/extensions/gsd/journal.ts +2 -1
- package/src/resources/extensions/gsd/key-manager.ts +28 -0
- package/src/resources/extensions/gsd/memory-backfill.ts +140 -0
- package/src/resources/extensions/gsd/memory-store.ts +26 -0
- package/src/resources/extensions/gsd/model-router.ts +42 -1
- package/src/resources/extensions/gsd/pre-execution-checks.ts +46 -10
- package/src/resources/extensions/gsd/preferences-types.ts +46 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +79 -0
- package/src/resources/extensions/gsd/preferences.ts +17 -17
- package/src/resources/extensions/gsd/prompt-loader.ts +30 -7
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
- package/src/resources/extensions/gsd/prompts/discuss.md +29 -2
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +119 -0
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +17 -4
- package/src/resources/extensions/gsd/safety/safety-harness.ts +9 -0
- package/src/resources/extensions/gsd/state.ts +45 -4
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +188 -2
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +95 -1
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +141 -0
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +33 -3
- package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/blocked-models.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +68 -66
- package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +61 -1
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +148 -3
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +306 -1
- package/src/resources/extensions/gsd/tests/escalation.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/exec-history.test.ts +237 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +210 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +40 -9
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +447 -1
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-git-symlink-cwd.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/integration/gitignore-tracked-gsd.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/issue-4540-regressions.test.ts +288 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/load-memory-block.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/pre-exec-gate-loop.test.ts +272 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +356 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +103 -4
- package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +388 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +9 -3
- package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +230 -0
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +205 -0
- package/src/resources/extensions/gsd/tests/save-gate-result-render.test.ts +95 -0
- package/src/resources/extensions/gsd/tests/schema-v21-sequence.test.ts +413 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +32 -40
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/token-counter.test.ts +105 -1
- package/src/resources/extensions/gsd/tests/tool-compatibility.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +9 -3
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +65 -2
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -5
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +3 -1
- package/src/resources/extensions/gsd/token-counter.ts +22 -5
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +15 -9
- package/src/resources/extensions/gsd/tools/exec-search-tool.ts +81 -0
- package/src/resources/extensions/gsd/tools/exec-tool.ts +183 -0
- package/src/resources/extensions/gsd/tools/memory-tools.ts +31 -1
- package/src/resources/extensions/gsd/tools/resume-tool.ts +40 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +26 -3
- package/src/resources/extensions/gsd/workflow-logger.ts +4 -1
- package/src/resources/extensions/gsd/workflow-mcp.ts +3 -0
- package/src/resources/extensions/gsd/workflow-templates/spike.md +6 -0
- package/src/resources/extensions/gsd/worktree-resolver.ts +54 -9
- package/src/resources/extensions/search-the-web/command-search-provider.ts +5 -4
- package/src/resources/extensions/search-the-web/native-search.ts +48 -12
- package/src/resources/skills/api-design/SKILL.md +190 -0
- package/src/resources/skills/create-mcp-server/SKILL.md +121 -0
- package/src/resources/skills/decompose-into-slices/SKILL.md +139 -0
- package/src/resources/skills/dependency-upgrade/SKILL.md +158 -0
- package/src/resources/skills/design-an-interface/SKILL.md +102 -0
- package/src/resources/skills/forensics/SKILL.md +153 -0
- package/src/resources/skills/grill-me/SKILL.md +93 -0
- package/src/resources/skills/handoff/SKILL.md +121 -0
- package/src/resources/skills/observability/SKILL.md +174 -0
- package/src/resources/skills/security-review/SKILL.md +181 -0
- package/src/resources/skills/spike-wrap-up/SKILL.md +138 -0
- package/src/resources/skills/tdd/SKILL.md +112 -0
- package/src/resources/skills/verify-before-complete/SKILL.md +98 -0
- package/src/resources/skills/write-docs/SKILL.md +82 -0
- package/src/resources/skills/write-milestone-brief/SKILL.md +135 -0
- /package/dist/web/standalone/.next/static/{ssX7BLv3Dw9Fb4CtrCGeR → pV-mPo7rYGb5JBC09C8GG}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{ssX7BLv3Dw9Fb4CtrCGeR → pV-mPo7rYGb5JBC09C8GG}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -27,47 +27,67 @@ One command. Walk away. Come back to a built project with clean git history.
|
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
30
|
-
## What's New in v2.
|
|
30
|
+
## What's New in v2.76
|
|
31
31
|
|
|
32
|
-
###
|
|
32
|
+
### Memory System
|
|
33
33
|
|
|
34
|
-
- **
|
|
35
|
-
-
|
|
34
|
+
- **Persistent agent memory** — new `capture_thought`, `memory_query`, and `gsd_graph` tools let GSD store, retrieve, and relate thoughts across sessions (Phase 1).
|
|
35
|
+
- **Ingestion + scopes/tags** — memories can be scoped (project, milestone, slice) and tagged for filtering (Phase 2).
|
|
36
|
+
- **Hybrid retrieval** — keyword + semantic search over stored memory for higher-recall lookup (Phase 3).
|
|
37
|
+
- **Knowledge graph relationships** — memories link into a queryable graph, feeding planning and dispatch context (Phase 4).
|
|
38
|
+
- **Maintenance & observability** — cap cascade, decay metrics, and export/import for memory stores (Phase 5).
|
|
36
39
|
|
|
37
|
-
###
|
|
40
|
+
### Progressive Planning (ADR-011)
|
|
38
41
|
|
|
39
|
-
- **
|
|
42
|
+
- **Sketch-then-refine planning** — Phase 1 introduces progressive plan elaboration so GSD drafts a lightweight sketch before locking a full plan (#3789).
|
|
43
|
+
- **Mid-execution escalation** — Phase 2 lets tasks escalate complexity mid-run with compensating rollback on write failure (#3789).
|
|
40
44
|
|
|
41
|
-
###
|
|
45
|
+
### Workflow & Onboarding
|
|
42
46
|
|
|
43
|
-
- **
|
|
47
|
+
- **Unified workflow plugin system** — new plugin architecture with modes and remote install. Manage via `/gsd workflow list|run|install|info|validate`.
|
|
48
|
+
- **`/gsd onboarding` re-entry** — revisit setup without restarting the TUI; setup hub disambiguation prevents duplicate banners.
|
|
49
|
+
- **`/gsd scan`** — new lightweight command for rapid codebase assessment, writing to `.gsd/codebase/`.
|
|
44
50
|
|
|
45
|
-
###
|
|
51
|
+
### Remote Control & TUI
|
|
46
52
|
|
|
47
|
-
- **
|
|
53
|
+
- **Telegram command interface** — control auto-mode remotely via Telegram alongside existing Slack/Discord routes.
|
|
54
|
+
- **Chat, footer, and welcome refresh** — TUI visuals updated; onboarding no longer hangs on re-entry.
|
|
55
|
+
- **New themes** — `tui-classic` and web `classic`/`vivid` palettes added (#4301).
|
|
48
56
|
|
|
49
|
-
###
|
|
57
|
+
### Models & Providers
|
|
50
58
|
|
|
51
|
-
- **
|
|
52
|
-
- **
|
|
53
|
-
- **
|
|
59
|
+
- **Claude Opus 4.7** — added across Anthropic, Bedrock, Antigravity, and OpenRouter (#4348).
|
|
60
|
+
- **GPT-5.4-mini** — added to the OpenAI Codex model list (#1215).
|
|
61
|
+
- **Anthropic proxy support** — `ANTHROPIC_BASE_URL` env var honored for custom proxy endpoints (#4140).
|
|
62
|
+
- **Flat-rate provider opt-in** — `allow_flat_rate_providers` routing toggle (#4386).
|
|
63
|
+
- **Ask User Questions** — optional markdown preview panel with side-by-side layout.
|
|
54
64
|
|
|
55
65
|
### Auto-Mode & Reliability
|
|
56
66
|
|
|
57
|
-
- **
|
|
58
|
-
- **
|
|
59
|
-
- **
|
|
60
|
-
- **
|
|
67
|
+
- **Stuck-loop hardening** — repeated units detected across the stuck window; research-dispatch stuck loop fixed (#4414).
|
|
68
|
+
- **Branch isolation** — milestone branch is created on entry in `isolation: branch` mode with `main_branch` validation (#4389).
|
|
69
|
+
- **Model fallback on limits** — auto-mode limit errors now trigger model fallback (#4373).
|
|
70
|
+
- **Python/Windows verification** — python invocations normalized on Windows in the verification gate (#4416).
|
|
71
|
+
- **Self-healing `.gsd/`** — symlinked `.gsd` staging self-heals to prevent silent data loss (#4423); `.gsd.migrating` healed on resume.
|
|
72
|
+
- **Stale OAuth recovery** — stale Anthropic OAuth credentials self-heal (#4399).
|
|
61
73
|
|
|
62
|
-
|
|
74
|
+
See the full [Changelog](./CHANGELOG.md) for details on every release.
|
|
63
75
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
- **
|
|
68
|
-
-
|
|
76
|
+
<details>
|
|
77
|
+
<summary>v2.75 highlights</summary>
|
|
78
|
+
|
|
79
|
+
- **Knowledge graph system** — structured knowledge graph built from project artifacts
|
|
80
|
+
- **`/gsd extract-learnings`** — extracts decisions, lessons, patterns, and surprises into `LEARNINGS.md`
|
|
81
|
+
- **Unified Orchestration Kernel (UOK)** — now the default execution path with plan-v2 compile gates and reactive/parallel scheduling
|
|
82
|
+
- **GSD Extension API** — third-party extensions loadable from `.gsd/extensions/` (#3338)
|
|
83
|
+
- **v1 command parity** — 12 missing commands added, closing the migration gap
|
|
84
|
+
- **Chat frame redesign** — unified styling for compaction notices, tool cards, and chat frame with timestamps and model headers
|
|
85
|
+
- **Single-writer DB invariant** — engine database enforces single-writer to prevent corruption
|
|
86
|
+
- **MCP worktree routing** — tool writes routed to active worktree; worktree paths accepted in project root guard
|
|
87
|
+
- **Alibaba DashScope** — added as a standalone provider (#3891)
|
|
88
|
+
- **Persistent language preference** — `/gsd language`
|
|
69
89
|
|
|
70
|
-
|
|
90
|
+
</details>
|
|
71
91
|
|
|
72
92
|
<details>
|
|
73
93
|
<summary>v2.74 highlights</summary>
|
package/dist/claude-cli-check.js
CHANGED
|
@@ -12,12 +12,41 @@ import { execFileSync } from 'node:child_process';
|
|
|
12
12
|
* `src/resources/extensions/gsd/pre-execution-checks.ts`.
|
|
13
13
|
*/
|
|
14
14
|
export const CLAUDE_COMMAND = process.platform === 'win32' ? 'claude.cmd' : 'claude';
|
|
15
|
+
/**
|
|
16
|
+
* Ordered list of binary names to probe for the Claude Code CLI.
|
|
17
|
+
*
|
|
18
|
+
* Windows installs vary: npm-global installs produce a `claude.cmd` shim,
|
|
19
|
+
* direct binary installs produce `claude.exe`, and Git Bash wrappers may
|
|
20
|
+
* expose a bare `claude` shim. Try all three so no valid install is missed.
|
|
21
|
+
*/
|
|
22
|
+
const CLAUDE_COMMAND_CANDIDATES = process.platform === 'win32' ? [CLAUDE_COMMAND, 'claude.exe', 'claude'] : [CLAUDE_COMMAND];
|
|
23
|
+
/**
|
|
24
|
+
* Try to run `args` against each candidate binary.
|
|
25
|
+
* Returns the output buffer on first success, throws the last error if all fail.
|
|
26
|
+
*/
|
|
27
|
+
function execClaudeCheck(args) {
|
|
28
|
+
let lastError;
|
|
29
|
+
for (const command of CLAUDE_COMMAND_CANDIDATES) {
|
|
30
|
+
try {
|
|
31
|
+
return execFileSync(command, args, { timeout: 5_000, stdio: 'pipe' });
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
lastError = error;
|
|
35
|
+
const code = error?.code;
|
|
36
|
+
// EINVAL can surface on Windows Git Bash for .cmd spawn failures.
|
|
37
|
+
if (code === 'ENOENT' || code === 'EINVAL')
|
|
38
|
+
continue;
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
throw lastError ?? new Error(`Claude CLI not found (tried: ${CLAUDE_COMMAND_CANDIDATES.join(', ')})`);
|
|
43
|
+
}
|
|
15
44
|
/**
|
|
16
45
|
* Check if the `claude` binary is installed (regardless of auth state).
|
|
17
46
|
*/
|
|
18
47
|
export function isClaudeBinaryInstalled() {
|
|
19
48
|
try {
|
|
20
|
-
|
|
49
|
+
execClaudeCheck(['--version']);
|
|
21
50
|
return true;
|
|
22
51
|
}
|
|
23
52
|
catch {
|
|
@@ -29,13 +58,13 @@ export function isClaudeBinaryInstalled() {
|
|
|
29
58
|
*/
|
|
30
59
|
export function isClaudeCliReady() {
|
|
31
60
|
try {
|
|
32
|
-
|
|
61
|
+
execClaudeCheck(['--version']);
|
|
33
62
|
}
|
|
34
63
|
catch {
|
|
35
64
|
return false;
|
|
36
65
|
}
|
|
37
66
|
try {
|
|
38
|
-
const output =
|
|
67
|
+
const output = execClaudeCheck(['auth', 'status'])
|
|
39
68
|
.toString()
|
|
40
69
|
.toLowerCase();
|
|
41
70
|
return !(/not logged in|no credentials|unauthenticated|not authenticated/i.test(output));
|
package/dist/mcp-server.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Minimal tool interface matching GSD's AgentTool shape.
|
|
3
3
|
* Avoids a direct dependency on @gsd/pi-agent-core from this compiled module.
|
|
4
|
+
*
|
|
5
|
+
* `details` and `isError` are optional fields that runtime tool implementations
|
|
6
|
+
* may populate. The MCP transport drops non-standard fields, so the wrapper at
|
|
7
|
+
* the call site mirrors `details` into `structuredContent` and forwards
|
|
8
|
+
* `isError` directly. See #4472.
|
|
4
9
|
*/
|
|
5
10
|
export interface McpToolDef {
|
|
6
11
|
name: string;
|
|
@@ -13,6 +18,8 @@ export interface McpToolDef {
|
|
|
13
18
|
data?: string;
|
|
14
19
|
mimeType?: string;
|
|
15
20
|
}>;
|
|
21
|
+
details?: Record<string, unknown>;
|
|
22
|
+
isError?: boolean;
|
|
16
23
|
}>;
|
|
17
24
|
}
|
|
18
25
|
/**
|
package/dist/mcp-server.js
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strict plain-object guard. True only for object literals and
|
|
3
|
+
* `Object.create(null)` — not for `Date`, `URL`, `Map`, `Set`, class instances,
|
|
4
|
+
* or arrays. Used to gate `structuredContent` forwarding so the MCP transport
|
|
5
|
+
* receives only true JSON objects (the protocol contract). See #4477 review.
|
|
6
|
+
*
|
|
7
|
+
* Mirrored in `packages/mcp-server/src/workflow-tools.ts` for the
|
|
8
|
+
* `adaptExecutorResult` adapter on the workflow path. Keep both copies in
|
|
9
|
+
* sync if the contract definition needs to evolve.
|
|
10
|
+
*/
|
|
11
|
+
function isPlainObject(value) {
|
|
12
|
+
if (value === null || typeof value !== 'object')
|
|
13
|
+
return false;
|
|
14
|
+
if (Array.isArray(value))
|
|
15
|
+
return false;
|
|
16
|
+
const proto = Object.getPrototypeOf(value);
|
|
17
|
+
return proto === null || proto === Object.prototype;
|
|
18
|
+
}
|
|
1
19
|
// MCP SDK subpath imports use wildcard exports (./*) in @modelcontextprotocol/sdk's
|
|
2
20
|
// package.json export map. The wildcard maps "./foo" → "./dist/cjs/foo" (no .js
|
|
3
21
|
// suffix), so bare subpath specifiers like `${MCP_PKG}/server/stdio` resolve to
|
|
@@ -83,7 +101,23 @@ export async function startMcpServer(options) {
|
|
|
83
101
|
// by stringifying into a text block so clients see the payload.
|
|
84
102
|
return { type: 'text', text: JSON.stringify(block) };
|
|
85
103
|
});
|
|
86
|
-
|
|
104
|
+
// Forward a tool's runtime `details` field to MCP's `structuredContent`
|
|
105
|
+
// channel. The protocol drops non-standard fields on the wire, so tools
|
|
106
|
+
// that populate `details` for client-side renderers (e.g. save_gate_result)
|
|
107
|
+
// would otherwise arrive empty on the other side. See #4472.
|
|
108
|
+
//
|
|
109
|
+
// Use a strict plain-object guard (prototype-chain check) rather than just
|
|
110
|
+
// `typeof === 'object' && !Array.isArray()` — Date, URL, Map, Set, and
|
|
111
|
+
// class instances would otherwise pass through and end up as
|
|
112
|
+
// `structuredContent`, violating the protocol's JSON-object contract.
|
|
113
|
+
// The mirror discipline applies in `workflow-tools.ts adaptExecutorResult`.
|
|
114
|
+
const base = { content };
|
|
115
|
+
if (isPlainObject(result.details)) {
|
|
116
|
+
base.structuredContent = result.details;
|
|
117
|
+
}
|
|
118
|
+
if (result.isError === true)
|
|
119
|
+
base.isError = true;
|
|
120
|
+
return base;
|
|
87
121
|
}
|
|
88
122
|
catch (err) {
|
|
89
123
|
// AbortError from a cancelled tool surfaces as a normal error — MCP
|
package/dist/onboarding.js
CHANGED
|
@@ -60,6 +60,8 @@ const OTHER_PROVIDERS = [
|
|
|
60
60
|
{ value: 'xai', label: 'xAI (Grok)', hint: 'console.x.ai' },
|
|
61
61
|
{ value: 'openrouter', label: 'OpenRouter', hint: '200+ models — openrouter.ai/keys' },
|
|
62
62
|
{ value: 'mistral', label: 'Mistral', hint: 'console.mistral.ai/api-keys' },
|
|
63
|
+
{ value: 'minimax', label: 'MiniMax', hint: 'platform.minimax.io (Anthropic-compatible recommended)' },
|
|
64
|
+
{ value: 'minimax-cn', label: 'MiniMax CN', hint: 'api.minimaxi.com (Anthropic-compatible)' },
|
|
63
65
|
{ value: 'ollama-cloud', label: 'Ollama Cloud' },
|
|
64
66
|
{ value: 'custom-openai', label: 'Custom (OpenAI-compatible)', hint: 'Ollama, LM Studio, vLLM, proxies — see docs/providers.md' },
|
|
65
67
|
];
|
|
@@ -131,6 +133,36 @@ function persistDefaultProvider(providerId) {
|
|
|
131
133
|
// Non-fatal: startup fallback logic will still run.
|
|
132
134
|
}
|
|
133
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Persist the selected default model to settings.json.
|
|
138
|
+
*/
|
|
139
|
+
function persistDefaultModel(modelId) {
|
|
140
|
+
const settingsPath = join(agentDir, 'settings.json');
|
|
141
|
+
try {
|
|
142
|
+
const raw = existsSync(settingsPath) ? JSON.parse(readFileSync(settingsPath, 'utf-8')) : {};
|
|
143
|
+
raw.defaultModel = modelId;
|
|
144
|
+
mkdirSync(dirname(settingsPath), { recursive: true });
|
|
145
|
+
writeFileSync(settingsPath, JSON.stringify(raw, null, 2), 'utf-8');
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// Non-fatal: startup fallback logic will still run.
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function detectNativeProviderFromBaseUrl(baseUrl) {
|
|
152
|
+
try {
|
|
153
|
+
const hostname = new URL(baseUrl).hostname.toLowerCase();
|
|
154
|
+
if (hostname === 'api.minimax.io' || hostname.endsWith('.minimax.io')) {
|
|
155
|
+
return 'minimax';
|
|
156
|
+
}
|
|
157
|
+
if (hostname === 'api.minimaxi.com' || hostname.endsWith('.minimaxi.com')) {
|
|
158
|
+
return 'minimax-cn';
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// ignore parse failures; handled by prior validation
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
134
166
|
/** Sentinel returned by runStep when the user cancels — tells the caller
|
|
135
167
|
* to abort the entire wizard. */
|
|
136
168
|
const STEP_CANCELLED = Symbol('step-cancelled');
|
|
@@ -558,9 +590,22 @@ async function runCustomOpenAIFlow(p, pc, authStorage) {
|
|
|
558
590
|
if (p.isCancel(modelId) || !modelId)
|
|
559
591
|
return false;
|
|
560
592
|
const trimmedModelId = modelId.trim();
|
|
593
|
+
const nativeProvider = detectNativeProviderFromBaseUrl(trimmedUrl);
|
|
594
|
+
if (nativeProvider) {
|
|
595
|
+
const envVar = nativeProvider === 'minimax' ? 'MINIMAX_API_KEY' : 'MINIMAX_CN_API_KEY';
|
|
596
|
+
authStorage.set(nativeProvider, { type: 'api_key', key: trimmedKey });
|
|
597
|
+
persistDefaultProvider(nativeProvider);
|
|
598
|
+
persistDefaultModel(trimmedModelId);
|
|
599
|
+
process.env[envVar] = trimmedKey;
|
|
600
|
+
p.log.success(`${pc.green('MiniMax')} detected — configured as native provider (${pc.cyan(nativeProvider)})`);
|
|
601
|
+
p.log.info(`Model: ${pc.cyan(trimmedModelId)}`);
|
|
602
|
+
p.log.info(pc.dim('Using Anthropic-compatible MiniMax integration for full model metadata and clean thinking output.'));
|
|
603
|
+
return true;
|
|
604
|
+
}
|
|
561
605
|
// Save API key to auth storage
|
|
562
606
|
authStorage.set('custom-openai', { type: 'api_key', key: trimmedKey });
|
|
563
607
|
persistDefaultProvider('custom-openai');
|
|
608
|
+
persistDefaultModel(trimmedModelId);
|
|
564
609
|
// Write or merge into models.json
|
|
565
610
|
const modelsJsonPath = join(agentDir, 'models.json');
|
|
566
611
|
let config = { providers: {} };
|
|
@@ -21,6 +21,6 @@ export declare function getNewerManagedResourceVersion(agentDir: string, current
|
|
|
21
21
|
*
|
|
22
22
|
* Inspectable: `ls ~/.gsd/agent/extensions/`
|
|
23
23
|
*/
|
|
24
|
-
export declare function initResources(agentDir: string): void;
|
|
24
|
+
export declare function initResources(agentDir: string, skillsDir?: string): void;
|
|
25
25
|
export declare function hasStaleCompiledExtensionSiblings(extensionsDir: string, sourceDir?: string): boolean;
|
|
26
26
|
export declare function buildResourceLoader(agentDir: string): DefaultResourceLoader;
|
package/dist/resource-loader.js
CHANGED
|
@@ -506,7 +506,7 @@ function pruneRemovedBundledExtensions(manifest, agentDir) {
|
|
|
506
506
|
*
|
|
507
507
|
* Inspectable: `ls ~/.gsd/agent/extensions/`
|
|
508
508
|
*/
|
|
509
|
-
export function initResources(agentDir) {
|
|
509
|
+
export function initResources(agentDir, skillsDir = join(homedir(), '.agents', 'skills')) {
|
|
510
510
|
mkdirSync(agentDir, { recursive: true });
|
|
511
511
|
const currentVersion = getBundledGsdVersion();
|
|
512
512
|
const manifest = readManagedResourceManifest(agentDir);
|
|
@@ -538,13 +538,7 @@ export function initResources(agentDir) {
|
|
|
538
538
|
// Sync bundled resources — overwrite so updates land on next launch.
|
|
539
539
|
syncResourceDir(bundledExtensionsDir, join(agentDir, 'extensions'));
|
|
540
540
|
syncResourceDir(join(resourcesDir, 'agents'), join(agentDir, 'agents'));
|
|
541
|
-
|
|
542
|
-
// skills.sh CLI (`npx skills add <repo>`) into ~/.agents/skills/ which
|
|
543
|
-
// is the industry-standard Agent Skills ecosystem directory.
|
|
544
|
-
//
|
|
545
|
-
// Migration from the legacy ~/.gsd/agent/skills/ directory is handled
|
|
546
|
-
// above the manifest check so it runs on every launch (including retries
|
|
547
|
-
// after partial copy failures).
|
|
541
|
+
syncResourceDir(join(resourcesDir, 'skills'), skillsDir);
|
|
548
542
|
// Sync GSD-WORKFLOW.md to agentDir as a fallback for when GSD_WORKFLOW_PATH
|
|
549
543
|
// env var is not set (e.g. fork/dev builds, alternative entry points).
|
|
550
544
|
const workflowSrc = join(resourcesDir, 'GSD-WORKFLOW.md');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: researcher
|
|
3
3
|
description: Web researcher that finds and synthesizes current information using Brave Search
|
|
4
|
-
tools: search-the-web, bash
|
|
4
|
+
tools: search-the-web, bash, capture_thought, memory_query, gsd_graph
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
You are a web researcher. You find current, accurate information using web search and synthesize it into a clear, well-structured report.
|
|
@@ -10,15 +10,38 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { execFileSync } from "node:child_process";
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* Candidate executable names for the Claude Code CLI.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* `claude` would fail with ENOENT even when the CLI is installed and
|
|
18
|
-
* authenticated. Mirrors the `NPM_COMMAND` pattern in
|
|
19
|
-
* `src/resources/extensions/gsd/pre-execution-checks.ts`.
|
|
15
|
+
* Keep the explicit win32 ternary selector for regression coverage (Issue #4424):
|
|
16
|
+
* Node's execFileSync must target `claude.cmd` directly on Windows.
|
|
20
17
|
*/
|
|
21
18
|
const CLAUDE_COMMAND = process.platform === "win32" ? "claude.cmd" : "claude";
|
|
19
|
+
/**
|
|
20
|
+
* Windows installs vary: some environments expose `claude.cmd` (npm shim),
|
|
21
|
+
* `claude.exe` (direct binary install), or a bare `claude` shim on PATH
|
|
22
|
+
* (for example Git Bash wrappers). Try all three to avoid false "not
|
|
23
|
+
* installed" results in readiness checks.
|
|
24
|
+
*/
|
|
25
|
+
const CLAUDE_COMMAND_CANDIDATES = process.platform === "win32" ? [CLAUDE_COMMAND, "claude.exe", "claude"] : [CLAUDE_COMMAND];
|
|
26
|
+
function execClaude(args) {
|
|
27
|
+
let lastError;
|
|
28
|
+
for (const command of CLAUDE_COMMAND_CANDIDATES) {
|
|
29
|
+
try {
|
|
30
|
+
return execFileSync(command, args, { timeout: 5_000, stdio: "pipe" });
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
lastError = error;
|
|
34
|
+
const code = error?.code;
|
|
35
|
+
// Windows Git Bash can surface `.cmd` spawn failures as EINVAL instead
|
|
36
|
+
// of ENOENT. Treat both as "try next candidate".
|
|
37
|
+
if (code === "ENOENT" || code === "EINVAL") {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
throw lastError ?? new Error(`Claude CLI executable not found (tried: ${CLAUDE_COMMAND_CANDIDATES.join(", ")})`);
|
|
44
|
+
}
|
|
22
45
|
let cachedBinaryPresent = null;
|
|
23
46
|
let cachedAuthed = null;
|
|
24
47
|
let lastCheckMs = 0;
|
|
@@ -32,7 +55,7 @@ function refreshCache() {
|
|
|
32
55
|
lastCheckMs = now;
|
|
33
56
|
// Check binary presence
|
|
34
57
|
try {
|
|
35
|
-
|
|
58
|
+
execClaude(["--version"]);
|
|
36
59
|
cachedBinaryPresent = true;
|
|
37
60
|
}
|
|
38
61
|
catch {
|
|
@@ -42,7 +65,7 @@ function refreshCache() {
|
|
|
42
65
|
}
|
|
43
66
|
// Check auth status — exit code 0 with non-error output means authenticated
|
|
44
67
|
try {
|
|
45
|
-
const output =
|
|
68
|
+
const output = execClaude(["auth", "status"])
|
|
46
69
|
.toString()
|
|
47
70
|
.toLowerCase();
|
|
48
71
|
// The CLI outputs "not logged in", "no credentials", or similar when unauthenticated
|
|
@@ -484,25 +484,23 @@ export function makeAbortedMessage(model, lastTextContent) {
|
|
|
484
484
|
/**
|
|
485
485
|
* Resolve the Claude Code permission mode for the current run.
|
|
486
486
|
*
|
|
487
|
-
*
|
|
488
|
-
*
|
|
489
|
-
*
|
|
490
|
-
*
|
|
491
|
-
*
|
|
492
|
-
*
|
|
493
|
-
* users opt into a stricter mode (`acceptEdits`, `default`, `plan`).
|
|
487
|
+
* Defaults to `acceptEdits`, which auto-approves file reads/edits but
|
|
488
|
+
* surfaces a permission dialog for dangerous operations (e.g. general Bash,
|
|
489
|
+
* Agent, WebFetch). This prevents tools outside the allowlist from being
|
|
490
|
+
* silently denied — the SDK emits an `extension_ui_request` event so the
|
|
491
|
+
* user sees a prompt instead of a silent refusal that Claude Code mistakes
|
|
492
|
+
* for user rejection (#4383).
|
|
494
493
|
*
|
|
495
|
-
*
|
|
496
|
-
*
|
|
497
|
-
*
|
|
498
|
-
* (#4099) is continuous approval fatigue that blocks real work.
|
|
494
|
+
* Set `GSD_CLAUDE_CODE_PERMISSION_MODE` to `bypassPermissions` to restore
|
|
495
|
+
* the old always-approve behaviour, or to `default` / `plan` for stricter
|
|
496
|
+
* modes.
|
|
499
497
|
*/
|
|
500
498
|
export async function resolveClaudePermissionMode(env = process.env) {
|
|
501
499
|
const override = env.GSD_CLAUDE_CODE_PERMISSION_MODE?.trim();
|
|
502
500
|
if (override === "bypassPermissions" || override === "acceptEdits" || override === "default" || override === "plan") {
|
|
503
501
|
return override;
|
|
504
502
|
}
|
|
505
|
-
return "
|
|
503
|
+
return "acceptEdits";
|
|
506
504
|
}
|
|
507
505
|
// NOTE: These helpers intentionally mirror @gsd/pi-ai anthropic-shared
|
|
508
506
|
// behavior so this extension remains typecheck-stable even when the published
|
|
@@ -554,7 +552,7 @@ function mapThinkingLevelToAnthropicEffort(level, modelId) {
|
|
|
554
552
|
export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
|
|
555
553
|
const { reasoning, ...sdkExtraOptions } = extraOptions;
|
|
556
554
|
const mcpServers = buildWorkflowMcpServers();
|
|
557
|
-
const permissionMode = overrides?.permissionMode ?? "
|
|
555
|
+
const permissionMode = overrides?.permissionMode ?? "acceptEdits";
|
|
558
556
|
const disallowedTools = ["AskUserQuestion"];
|
|
559
557
|
// Pre-authorize the safe built-ins and every registered workflow MCP
|
|
560
558
|
// server's tools. `acceptEdits` mode (the interactive default) only
|
|
@@ -637,6 +635,68 @@ function normalizeToolResultContent(content) {
|
|
|
637
635
|
}
|
|
638
636
|
return blocks.length > 0 ? blocks : [{ type: "text", text: "" }];
|
|
639
637
|
}
|
|
638
|
+
/**
|
|
639
|
+
* Extract a `details` payload from an MCP tool-result block.
|
|
640
|
+
*
|
|
641
|
+
* MCP's `CallToolResult` carries structured data in `structuredContent` — the
|
|
642
|
+
* protocol's supported channel for non-text payloads. Claude Code's synthetic
|
|
643
|
+
* user message may surface that field in one of two shapes depending on SDK
|
|
644
|
+
* version: as a sibling on the `mcp_tool_result` block itself, or as a
|
|
645
|
+
* dedicated content sub-block with `type: "structuredContent"`. Snake-case
|
|
646
|
+
* (`structured_content`) is accepted defensively in case a transport hop
|
|
647
|
+
* rewrites casing. All other shapes fall back to an empty object so callers
|
|
648
|
+
* can rely on `details` being present.
|
|
649
|
+
*/
|
|
650
|
+
function extractStructuredDetailsFromBlock(block) {
|
|
651
|
+
const sibling = block.structuredContent ?? block.structured_content;
|
|
652
|
+
if (sibling && typeof sibling === "object" && !Array.isArray(sibling)) {
|
|
653
|
+
return sibling;
|
|
654
|
+
}
|
|
655
|
+
if (Array.isArray(block.content)) {
|
|
656
|
+
for (const item of block.content) {
|
|
657
|
+
if (!item || typeof item !== "object")
|
|
658
|
+
continue;
|
|
659
|
+
const sub = item;
|
|
660
|
+
if (sub.type !== "structuredContent" && sub.type !== "structured_content")
|
|
661
|
+
continue;
|
|
662
|
+
const payload = sub.structuredContent ?? sub.structured_content ?? sub.data ?? sub.value;
|
|
663
|
+
if (payload && typeof payload === "object" && !Array.isArray(payload)) {
|
|
664
|
+
return payload;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
// Return undefined (not {}) when no structured payload is present, matching
|
|
669
|
+
// the pre-#4477 contract where `details` was nullable. An empty-object
|
|
670
|
+
// sentinel is truthy and breaks downstream consumers that gate on
|
|
671
|
+
// `if (details)`. `undefined` matches the type of the field these results
|
|
672
|
+
// flow into (`Record<string, unknown> | undefined`).
|
|
673
|
+
return undefined;
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* True for items that are MCP `structuredContent` pseudo-blocks living inside
|
|
677
|
+
* a tool-result `content[]` array. These blocks carry the structured payload
|
|
678
|
+
* (extracted separately by `extractStructuredDetailsFromBlock`) and must NOT
|
|
679
|
+
* leak into the visible content rendered to the user — otherwise the renderer
|
|
680
|
+
* stringifies the JSON pseudo-block and shows it next to the actual tool
|
|
681
|
+
* output. See PR #4477 review (CodeRabbit, post-fix-round).
|
|
682
|
+
*/
|
|
683
|
+
function isStructuredContentPseudoBlock(item) {
|
|
684
|
+
if (!item || typeof item !== "object")
|
|
685
|
+
return false;
|
|
686
|
+
const type = item.type;
|
|
687
|
+
return type === "structuredContent" || type === "structured_content";
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Strip `structuredContent` pseudo-blocks from a tool-result content array
|
|
691
|
+
* before normalization. The structured payload is extracted via the sibling
|
|
692
|
+
* `structuredContent` field (or a dedicated extractor pass on the raw block);
|
|
693
|
+
* the visible content path must not include the pseudo-block itself.
|
|
694
|
+
*/
|
|
695
|
+
function stripStructuredContentPseudoBlocks(content) {
|
|
696
|
+
if (!Array.isArray(content))
|
|
697
|
+
return content;
|
|
698
|
+
return content.filter((item) => !isStructuredContentPseudoBlock(item));
|
|
699
|
+
}
|
|
640
700
|
/** Extract tool result payloads from an SDK synthetic user message, keyed by tool-use ID. */
|
|
641
701
|
export function extractToolResultsFromSdkUserMessage(message) {
|
|
642
702
|
const extracted = [];
|
|
@@ -657,8 +717,8 @@ export function extractToolResultsFromSdkUserMessage(message) {
|
|
|
657
717
|
extracted.push({
|
|
658
718
|
toolUseId,
|
|
659
719
|
result: {
|
|
660
|
-
content: normalizeToolResultContent(block.content),
|
|
661
|
-
details:
|
|
720
|
+
content: normalizeToolResultContent(stripStructuredContentPseudoBlocks(block.content)),
|
|
721
|
+
details: extractStructuredDetailsFromBlock(block),
|
|
662
722
|
isError: block.is_error === true,
|
|
663
723
|
},
|
|
664
724
|
});
|
|
@@ -672,8 +732,8 @@ export function extractToolResultsFromSdkUserMessage(message) {
|
|
|
672
732
|
extracted.push({
|
|
673
733
|
toolUseId,
|
|
674
734
|
result: {
|
|
675
|
-
content: normalizeToolResultContent(toolResult.content),
|
|
676
|
-
details:
|
|
735
|
+
content: normalizeToolResultContent(stripStructuredContentPseudoBlocks(toolResult.content)),
|
|
736
|
+
details: extractStructuredDetailsFromBlock(toolResult),
|
|
677
737
|
isError: toolResult.is_error === true,
|
|
678
738
|
},
|
|
679
739
|
});
|
|
@@ -30,6 +30,13 @@ function stuckStatePath(basePath) {
|
|
|
30
30
|
function loadStuckState(basePath) {
|
|
31
31
|
try {
|
|
32
32
|
const data = JSON.parse(readFileSync(stuckStatePath(basePath), "utf-8"));
|
|
33
|
+
// Only load state written by a DIFFERENT process (real session restart).
|
|
34
|
+
// If the PID matches the current process, this state was written by an earlier
|
|
35
|
+
// autoLoop call in the same process (e.g., a test that completed before this
|
|
36
|
+
// one), not by a crashed session — skip it to prevent test state pollution.
|
|
37
|
+
if (data.pid === process.pid) {
|
|
38
|
+
return { recentUnits: [], stuckRecoveryAttempts: 0 };
|
|
39
|
+
}
|
|
33
40
|
return {
|
|
34
41
|
recentUnits: Array.isArray(data.recentUnits) ? data.recentUnits : [],
|
|
35
42
|
stuckRecoveryAttempts: typeof data.stuckRecoveryAttempts === "number" ? data.stuckRecoveryAttempts : 0,
|
|
@@ -45,6 +52,7 @@ function saveStuckState(basePath, state) {
|
|
|
45
52
|
const filePath = stuckStatePath(basePath);
|
|
46
53
|
mkdirSync(join(gsdRoot(basePath), "runtime"), { recursive: true });
|
|
47
54
|
writeFileSync(filePath, JSON.stringify({
|
|
55
|
+
pid: process.pid,
|
|
48
56
|
recentUnits: state.recentUnits.slice(-20), // keep last 20 entries
|
|
49
57
|
stuckRecoveryAttempts: state.stuckRecoveryAttempts,
|
|
50
58
|
updatedAt: new Date().toISOString(),
|
|
@@ -497,6 +505,7 @@ export async function autoLoop(ctx, pi, s, deps, options) {
|
|
|
497
505
|
consecutiveCooldowns = 0;
|
|
498
506
|
recentErrorMessages.length = 0;
|
|
499
507
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId, seq: nextSeq(), eventType: "iteration-end", data: { iteration } });
|
|
508
|
+
saveStuckState(s.basePath, loopState); // persist across session restarts (#4382)
|
|
500
509
|
debugLog("autoLoop", { phase: "iteration-complete", iteration });
|
|
501
510
|
finishTurn("completed");
|
|
502
511
|
}
|