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
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
// GSD Extension — Layer 2 Event Emitter Bridge
|
|
2
|
+
//
|
|
3
|
+
// Holds a module-scoped reference to the ExtensionAPI so deeply-nested code
|
|
4
|
+
// (auto-loop, git-service callers, verification, budget) can emit Layer 2
|
|
5
|
+
// events without having to thread `pi` through every function signature.
|
|
6
|
+
//
|
|
7
|
+
// Set once from `registerGsdExtension`. All emitters are best-effort — a
|
|
8
|
+
// missing `pi` (e.g. in standalone unit tests) silently becomes a no-op.
|
|
9
|
+
|
|
10
|
+
import type { ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
11
|
+
import type {
|
|
12
|
+
BeforeCommitEventResult,
|
|
13
|
+
BeforePrEventResult,
|
|
14
|
+
BeforePushEventResult,
|
|
15
|
+
BeforeVerifyEventResult,
|
|
16
|
+
BudgetThresholdEventResult,
|
|
17
|
+
VerifyFailure,
|
|
18
|
+
} from "@gsd/pi-coding-agent";
|
|
19
|
+
|
|
20
|
+
let _pi: ExtensionAPI | undefined;
|
|
21
|
+
|
|
22
|
+
export function setHookEmitter(pi: ExtensionAPI): void {
|
|
23
|
+
_pi = pi;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function clearHookEmitter(): void {
|
|
27
|
+
_pi = undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ─── Notification ──────────────────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
export async function emitNotification(
|
|
33
|
+
kind: "blocked" | "input_needed" | "milestone_ready" | "idle" | "error",
|
|
34
|
+
message: string,
|
|
35
|
+
details?: Record<string, unknown>,
|
|
36
|
+
): Promise<void> {
|
|
37
|
+
if (!_pi) return;
|
|
38
|
+
await _pi.emitExtensionEvent({ type: "notification", kind, message, details });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ─── Git Lifecycle ─────────────────────────────────────────────────────────
|
|
42
|
+
|
|
43
|
+
export async function emitBeforeCommit(args: {
|
|
44
|
+
message: string;
|
|
45
|
+
files: string[];
|
|
46
|
+
cwd: string;
|
|
47
|
+
author?: string;
|
|
48
|
+
}): Promise<BeforeCommitEventResult | undefined> {
|
|
49
|
+
if (!_pi) return undefined;
|
|
50
|
+
return (await _pi.emitExtensionEvent({
|
|
51
|
+
type: "before_commit",
|
|
52
|
+
...args,
|
|
53
|
+
})) as BeforeCommitEventResult | undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function emitCommit(args: {
|
|
57
|
+
sha: string;
|
|
58
|
+
message: string;
|
|
59
|
+
files: string[];
|
|
60
|
+
cwd: string;
|
|
61
|
+
}): Promise<void> {
|
|
62
|
+
if (!_pi) return;
|
|
63
|
+
await _pi.emitExtensionEvent({ type: "commit", ...args });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function emitBeforePush(args: {
|
|
67
|
+
remote: string;
|
|
68
|
+
branch: string;
|
|
69
|
+
cwd: string;
|
|
70
|
+
}): Promise<BeforePushEventResult | undefined> {
|
|
71
|
+
if (!_pi) return undefined;
|
|
72
|
+
return (await _pi.emitExtensionEvent({
|
|
73
|
+
type: "before_push",
|
|
74
|
+
...args,
|
|
75
|
+
})) as BeforePushEventResult | undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export async function emitPush(args: { remote: string; branch: string; cwd: string }): Promise<void> {
|
|
79
|
+
if (!_pi) return;
|
|
80
|
+
await _pi.emitExtensionEvent({ type: "push", ...args });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export async function emitBeforePr(args: {
|
|
84
|
+
branch: string;
|
|
85
|
+
targetBranch: string;
|
|
86
|
+
title: string;
|
|
87
|
+
body: string;
|
|
88
|
+
cwd: string;
|
|
89
|
+
}): Promise<BeforePrEventResult | undefined> {
|
|
90
|
+
if (!_pi) return undefined;
|
|
91
|
+
return (await _pi.emitExtensionEvent({
|
|
92
|
+
type: "before_pr",
|
|
93
|
+
...args,
|
|
94
|
+
})) as BeforePrEventResult | undefined;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export async function emitPrOpened(args: {
|
|
98
|
+
url: string;
|
|
99
|
+
branch: string;
|
|
100
|
+
targetBranch: string;
|
|
101
|
+
cwd: string;
|
|
102
|
+
}): Promise<void> {
|
|
103
|
+
if (!_pi) return;
|
|
104
|
+
await _pi.emitExtensionEvent({ type: "pr_opened", ...args });
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ─── Verification ──────────────────────────────────────────────────────────
|
|
108
|
+
|
|
109
|
+
export async function emitBeforeVerify(args: {
|
|
110
|
+
unitType?: string;
|
|
111
|
+
unitId?: string;
|
|
112
|
+
cwd: string;
|
|
113
|
+
}): Promise<BeforeVerifyEventResult | undefined> {
|
|
114
|
+
if (!_pi) return undefined;
|
|
115
|
+
return (await _pi.emitExtensionEvent({
|
|
116
|
+
type: "before_verify",
|
|
117
|
+
...args,
|
|
118
|
+
})) as BeforeVerifyEventResult | undefined;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export async function emitVerifyResult(args: {
|
|
122
|
+
passed: boolean;
|
|
123
|
+
failures: VerifyFailure[];
|
|
124
|
+
unitType?: string;
|
|
125
|
+
unitId?: string;
|
|
126
|
+
cwd: string;
|
|
127
|
+
}): Promise<void> {
|
|
128
|
+
if (!_pi) return;
|
|
129
|
+
await _pi.emitExtensionEvent({ type: "verify_result", ...args });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ─── Budget ────────────────────────────────────────────────────────────────
|
|
133
|
+
|
|
134
|
+
export async function emitBudgetThreshold(args: {
|
|
135
|
+
fraction: number;
|
|
136
|
+
spent: number;
|
|
137
|
+
limit: number;
|
|
138
|
+
}): Promise<BudgetThresholdEventResult | undefined> {
|
|
139
|
+
if (!_pi) return undefined;
|
|
140
|
+
return (await _pi.emitExtensionEvent({
|
|
141
|
+
type: "budget_threshold",
|
|
142
|
+
fraction: args.fraction,
|
|
143
|
+
spent: args.spent,
|
|
144
|
+
limit: args.limit,
|
|
145
|
+
currency: "USD",
|
|
146
|
+
})) as BudgetThresholdEventResult | undefined;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ─── Orchestrator Boundaries ───────────────────────────────────────────────
|
|
150
|
+
|
|
151
|
+
export async function emitMilestoneStart(args: {
|
|
152
|
+
milestoneId: string;
|
|
153
|
+
title?: string;
|
|
154
|
+
cwd: string;
|
|
155
|
+
}): Promise<void> {
|
|
156
|
+
if (!_pi) return;
|
|
157
|
+
await _pi.emitExtensionEvent({ type: "milestone_start", ...args });
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export async function emitMilestoneEnd(args: {
|
|
161
|
+
milestoneId: string;
|
|
162
|
+
status: "completed" | "failed" | "cancelled";
|
|
163
|
+
cwd: string;
|
|
164
|
+
}): Promise<void> {
|
|
165
|
+
if (!_pi) return;
|
|
166
|
+
await _pi.emitExtensionEvent({ type: "milestone_end", ...args });
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export async function emitUnitStart(args: {
|
|
170
|
+
unitType: string;
|
|
171
|
+
unitId: string;
|
|
172
|
+
milestoneId?: string;
|
|
173
|
+
cwd: string;
|
|
174
|
+
}): Promise<void> {
|
|
175
|
+
if (!_pi) return;
|
|
176
|
+
await _pi.emitExtensionEvent({ type: "unit_start", ...args });
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export async function emitUnitEnd(args: {
|
|
180
|
+
unitType: string;
|
|
181
|
+
unitId: string;
|
|
182
|
+
milestoneId?: string;
|
|
183
|
+
status: "completed" | "failed" | "cancelled" | "blocked";
|
|
184
|
+
cwd: string;
|
|
185
|
+
}): Promise<void> {
|
|
186
|
+
if (!_pi) return;
|
|
187
|
+
await _pi.emitExtensionEvent({ type: "unit_end", ...args });
|
|
188
|
+
}
|
|
@@ -10,7 +10,7 @@ import type { ExtensionAPI, ExtensionCommandContext } from "@gsd/pi-coding-agent
|
|
|
10
10
|
import { existsSync, mkdirSync, writeFileSync, readFileSync } from "node:fs";
|
|
11
11
|
import { join } from "node:path";
|
|
12
12
|
import { showNextAction } from "../shared/tui.js";
|
|
13
|
-
import { nativeIsRepo, nativeInit } from "./native-git-bridge.js";
|
|
13
|
+
import { nativeIsRepo, nativeInit, nativeAddAll, nativeCommit } from "./native-git-bridge.js";
|
|
14
14
|
import { ensureGitignore, untrackRuntimeFiles } from "./gitignore.js";
|
|
15
15
|
import { gsdRoot } from "./paths.js";
|
|
16
16
|
import { assertSafeDirectory } from "./validate-directory.js";
|
|
@@ -74,6 +74,7 @@ export async function showProjectInit(
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
// ── Step 2: Git setup ──────────────────────────────────────────────────────
|
|
77
|
+
let didInitGit = false;
|
|
77
78
|
if (!signals.isGitRepo) {
|
|
78
79
|
const gitChoice = await showNextAction(ctx, {
|
|
79
80
|
title: "GSD — Project Setup",
|
|
@@ -89,6 +90,7 @@ export async function showProjectInit(
|
|
|
89
90
|
|
|
90
91
|
if (gitChoice === "init_git") {
|
|
91
92
|
nativeInit(basePath, prefs.mainBranch);
|
|
93
|
+
didInitGit = true;
|
|
92
94
|
}
|
|
93
95
|
} else {
|
|
94
96
|
// Auto-detect main branch from existing repo
|
|
@@ -295,6 +297,18 @@ export async function showProjectInit(
|
|
|
295
297
|
ensureGitignore(basePath);
|
|
296
298
|
untrackRuntimeFiles(basePath);
|
|
297
299
|
|
|
300
|
+
// Create initial commit so git log and git worktree work immediately (#4530).
|
|
301
|
+
// Without this, the branch is "unborn" (zero commits) and downstream operations
|
|
302
|
+
// like `git log` and `git worktree add` fail.
|
|
303
|
+
if (didInitGit) {
|
|
304
|
+
try {
|
|
305
|
+
nativeAddAll(basePath);
|
|
306
|
+
nativeCommit(basePath, "chore: init project");
|
|
307
|
+
} catch {
|
|
308
|
+
// Non-fatal — user can commit manually; don't block project init
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
298
312
|
// Auto-generate codebase map for instant agent orientation
|
|
299
313
|
try {
|
|
300
314
|
const result = generateCodebaseMap(basePath);
|
|
@@ -39,7 +39,8 @@ export type JournalEventType =
|
|
|
39
39
|
| "worktree-create-failed"
|
|
40
40
|
| "worktree-skip"
|
|
41
41
|
| "worktree-merge-start"
|
|
42
|
-
| "worktree-merge-failed"
|
|
42
|
+
| "worktree-merge-failed"
|
|
43
|
+
| "artifact-verification-retry";
|
|
43
44
|
|
|
44
45
|
/** A single structured event in the journal. */
|
|
45
46
|
export interface JournalEntry {
|
|
@@ -35,6 +35,12 @@ export interface ProviderInfo {
|
|
|
35
35
|
export const PROVIDER_REGISTRY: ProviderInfo[] = [
|
|
36
36
|
// LLM Providers
|
|
37
37
|
{ id: "anthropic", label: "Anthropic (Claude)", category: "llm", envVar: "ANTHROPIC_API_KEY", prefixes: ["sk-ant-"], hasOAuth: true, dashboardUrl: "console.anthropic.com" },
|
|
38
|
+
// Claude Code CLI: routes through the local `claude` binary — no API key,
|
|
39
|
+
// authentication is handled by the CLI's own OAuth flow.
|
|
40
|
+
// Referenced by doctor-providers.ts, auto-model-selection.ts, and others;
|
|
41
|
+
// must be in the canonical registry so all consumers see the same catalog.
|
|
42
|
+
// See: https://github.com/gsd-build/gsd-2/issues/4541
|
|
43
|
+
{ id: "claude-code", label: "Claude Code CLI", category: "llm", hasOAuth: true },
|
|
38
44
|
{ id: "openai", label: "OpenAI", category: "llm", envVar: "OPENAI_API_KEY", prefixes: ["sk-"], dashboardUrl: "platform.openai.com/api-keys" },
|
|
39
45
|
{ id: "github-copilot", label: "GitHub Copilot", category: "llm", envVar: "GITHUB_TOKEN", hasOAuth: true },
|
|
40
46
|
{ id: "openai-codex", label: "ChatGPT Plus/Pro (Codex)",category: "llm", hasOAuth: true },
|
|
@@ -45,6 +51,8 @@ export const PROVIDER_REGISTRY: ProviderInfo[] = [
|
|
|
45
51
|
{ id: "xai", label: "xAI (Grok)", category: "llm", envVar: "XAI_API_KEY", dashboardUrl: "console.x.ai" },
|
|
46
52
|
{ id: "openrouter", label: "OpenRouter", category: "llm", envVar: "OPENROUTER_API_KEY", dashboardUrl: "openrouter.ai/keys" },
|
|
47
53
|
{ id: "mistral", label: "Mistral", category: "llm", envVar: "MISTRAL_API_KEY", dashboardUrl: "console.mistral.ai" },
|
|
54
|
+
{ id: "minimax", label: "MiniMax", category: "llm", envVar: "MINIMAX_API_KEY", dashboardUrl: "platform.minimax.io" },
|
|
55
|
+
{ id: "minimax-cn", label: "MiniMax CN", category: "llm", envVar: "MINIMAX_CN_API_KEY", dashboardUrl: "platform.minimax.io" },
|
|
48
56
|
{ id: "ollama-cloud", label: "Ollama Cloud", category: "llm", envVar: "OLLAMA_API_KEY" },
|
|
49
57
|
{ id: "custom-openai", label: "Custom (OpenAI-compat)", category: "llm", envVar: "CUSTOM_OPENAI_API_KEY" },
|
|
50
58
|
{ id: "cerebras", label: "Cerebras", category: "llm", envVar: "CEREBRAS_API_KEY" },
|
|
@@ -480,6 +488,26 @@ const TEST_ENDPOINTS: Record<string, { url: string; method?: string; headers?: (
|
|
|
480
488
|
url: "https://api.mistral.ai/v1/models",
|
|
481
489
|
headers: (key) => ({ Authorization: `Bearer ${key}` }),
|
|
482
490
|
},
|
|
491
|
+
minimax: {
|
|
492
|
+
url: "https://api.minimax.io/anthropic/v1/messages",
|
|
493
|
+
method: "POST",
|
|
494
|
+
headers: (key) => ({
|
|
495
|
+
"x-api-key": key,
|
|
496
|
+
"anthropic-version": "2023-06-01",
|
|
497
|
+
"content-type": "application/json",
|
|
498
|
+
}),
|
|
499
|
+
body: JSON.stringify({ model: "MiniMax-M2.7", max_tokens: 1, messages: [{ role: "user", content: "hi" }] }),
|
|
500
|
+
},
|
|
501
|
+
"minimax-cn": {
|
|
502
|
+
url: "https://api.minimaxi.com/anthropic/v1/messages",
|
|
503
|
+
method: "POST",
|
|
504
|
+
headers: (key) => ({
|
|
505
|
+
"x-api-key": key,
|
|
506
|
+
"anthropic-version": "2023-06-01",
|
|
507
|
+
"content-type": "application/json",
|
|
508
|
+
}),
|
|
509
|
+
body: JSON.stringify({ model: "MiniMax-M2.7", max_tokens: 1, messages: [{ role: "user", content: "hi" }] }),
|
|
510
|
+
},
|
|
483
511
|
openrouter: {
|
|
484
512
|
url: "https://openrouter.ai/api/v1/models",
|
|
485
513
|
headers: (key) => ({ Authorization: `Bearer ${key}` }),
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// GSD2 — Decisions -> memories backfill (ADR-013 step 5)
|
|
2
|
+
//
|
|
3
|
+
// Idempotent one-shot migration that copies every active decisions row into
|
|
4
|
+
// the memories table with category="architecture" and a structured_fields
|
|
5
|
+
// payload preserving the original gsd_save_decision schema (when_context,
|
|
6
|
+
// scope, decision, choice, rationale, made_by, revisable, sourceDecisionId).
|
|
7
|
+
//
|
|
8
|
+
// The backfill exists so the cutover in ADR-013 step 6 can drop the
|
|
9
|
+
// decisions table without losing schema fidelity. Idempotency is enforced
|
|
10
|
+
// by tagging each backfilled memory with structured_fields.sourceDecisionId
|
|
11
|
+
// and skipping any decision whose ID already appears in the memories table.
|
|
12
|
+
//
|
|
13
|
+
// Triggered opportunistically by buildBeforeAgentStartResult so the cost
|
|
14
|
+
// only ever fires once per project. Costs O(N) inserts on first run where
|
|
15
|
+
// N is the active-decisions count; subsequent runs are an O(N) lookup that
|
|
16
|
+
// finds existing markers and exits.
|
|
17
|
+
|
|
18
|
+
import { isDbAvailable, _getAdapter } from "./gsd-db.js";
|
|
19
|
+
import { createMemory } from "./memory-store.js";
|
|
20
|
+
import { logWarning } from "./workflow-logger.js";
|
|
21
|
+
|
|
22
|
+
interface DecisionRow {
|
|
23
|
+
id: string;
|
|
24
|
+
when_context: string;
|
|
25
|
+
scope: string;
|
|
26
|
+
decision: string;
|
|
27
|
+
choice: string;
|
|
28
|
+
rationale: string;
|
|
29
|
+
made_by: string;
|
|
30
|
+
revisable: string;
|
|
31
|
+
superseded_by: string | null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Backfill active decisions rows into the memories table.
|
|
36
|
+
*
|
|
37
|
+
* - Idempotent (per-row): every row written carries
|
|
38
|
+
* `structured_fields.sourceDecisionId = "<decisionId>"`. Each candidate
|
|
39
|
+
* decision is checked individually; only decisions whose id is already
|
|
40
|
+
* present in the memory store are skipped. A user-authored memory with
|
|
41
|
+
* their own `sourceDecisionId` does NOT abort the backfill.
|
|
42
|
+
* - Best-effort: never throws. Logs and returns 0 on failure so a broken
|
|
43
|
+
* backfill cannot block agent startup.
|
|
44
|
+
* - Active-only: skips rows where `superseded_by IS NOT NULL`. Superseded
|
|
45
|
+
* decisions are historical record; the memory store is for active
|
|
46
|
+
* knowledge.
|
|
47
|
+
*
|
|
48
|
+
* Returns the number of memories written (0 when already backfilled or
|
|
49
|
+
* when the DB has no decisions). Callers can log the result or surface it
|
|
50
|
+
* to the user.
|
|
51
|
+
*/
|
|
52
|
+
export function backfillDecisionsToMemories(): number {
|
|
53
|
+
if (!isDbAvailable()) return 0;
|
|
54
|
+
const adapter = _getAdapter();
|
|
55
|
+
if (!adapter) return 0;
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const decisions = adapter
|
|
59
|
+
.prepare("SELECT id, when_context, scope, decision, choice, rationale, made_by, revisable, superseded_by FROM decisions WHERE superseded_by IS NULL")
|
|
60
|
+
.all() as Array<Record<string, unknown>>;
|
|
61
|
+
|
|
62
|
+
if (decisions.length === 0) return 0;
|
|
63
|
+
|
|
64
|
+
// Per-row idempotency: each memory backfilled from a decision carries
|
|
65
|
+
// structured_fields.sourceDecisionId="<decisionId>". Skipping is decided
|
|
66
|
+
// per row by matching that exact id, NOT by a global sentinel — a global
|
|
67
|
+
// sentinel would silently abort the backfill if a user manually called
|
|
68
|
+
// capture_thought with their own structuredFields.sourceDecisionId.
|
|
69
|
+
const checkExisting = adapter.prepare(
|
|
70
|
+
"SELECT 1 FROM memories WHERE structured_fields LIKE :pattern LIMIT 1",
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
let written = 0;
|
|
74
|
+
for (const raw of decisions) {
|
|
75
|
+
const row: DecisionRow = {
|
|
76
|
+
id: String(raw["id"] ?? ""),
|
|
77
|
+
when_context: String(raw["when_context"] ?? ""),
|
|
78
|
+
scope: String(raw["scope"] ?? ""),
|
|
79
|
+
decision: String(raw["decision"] ?? ""),
|
|
80
|
+
choice: String(raw["choice"] ?? ""),
|
|
81
|
+
rationale: String(raw["rationale"] ?? ""),
|
|
82
|
+
made_by: String(raw["made_by"] ?? "agent"),
|
|
83
|
+
revisable: String(raw["revisable"] ?? ""),
|
|
84
|
+
superseded_by: raw["superseded_by"] == null ? null : String(raw["superseded_by"]),
|
|
85
|
+
};
|
|
86
|
+
if (!row.id) continue;
|
|
87
|
+
|
|
88
|
+
// Pattern is anchored to the JSON-stringified shape and the exact
|
|
89
|
+
// decision id to avoid prefix collisions (e.g. "D1" vs "D10").
|
|
90
|
+
if (checkExisting.get({ ":pattern": `%"sourceDecisionId":"${row.id}"%` })) continue;
|
|
91
|
+
|
|
92
|
+
const content = synthesizeContent(row);
|
|
93
|
+
const id = createMemory({
|
|
94
|
+
category: "architecture",
|
|
95
|
+
content,
|
|
96
|
+
scope: row.scope || "project",
|
|
97
|
+
confidence: 0.85,
|
|
98
|
+
structuredFields: {
|
|
99
|
+
sourceDecisionId: row.id,
|
|
100
|
+
when_context: row.when_context,
|
|
101
|
+
scope: row.scope,
|
|
102
|
+
decision: row.decision,
|
|
103
|
+
choice: row.choice,
|
|
104
|
+
rationale: row.rationale,
|
|
105
|
+
made_by: row.made_by,
|
|
106
|
+
revisable: row.revisable,
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
if (id) written += 1;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return written;
|
|
113
|
+
} catch (e) {
|
|
114
|
+
logWarning("memory-backfill", `decisions->memories backfill failed: ${(e as Error).message}`);
|
|
115
|
+
return 0;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Combine the decision's structured fields into a 1-3 sentence content
|
|
121
|
+
* string suitable for keyword retrieval and human review.
|
|
122
|
+
*
|
|
123
|
+
* Format: "<decision> Chose: <choice>. Rationale: <rationale>."
|
|
124
|
+
* Truncates each field to keep the synthesized line under ~600 chars so
|
|
125
|
+
* memory_query rendering stays readable.
|
|
126
|
+
*/
|
|
127
|
+
function synthesizeContent(row: DecisionRow): string {
|
|
128
|
+
const trim = (value: string, max: number): string => {
|
|
129
|
+
const cleaned = value.replace(/\s+/g, " ").trim();
|
|
130
|
+
return cleaned.length > max ? cleaned.slice(0, max - 1) + "\u2026" : cleaned;
|
|
131
|
+
};
|
|
132
|
+
const parts: string[] = [];
|
|
133
|
+
const decision = trim(row.decision, 240);
|
|
134
|
+
const choice = trim(row.choice, 200);
|
|
135
|
+
const rationale = trim(row.rationale, 200);
|
|
136
|
+
if (decision) parts.push(decision);
|
|
137
|
+
if (choice) parts.push(`Chose: ${choice}.`);
|
|
138
|
+
if (rationale) parts.push(`Rationale: ${rationale}.`);
|
|
139
|
+
return parts.join(" ");
|
|
140
|
+
}
|
|
@@ -36,6 +36,12 @@ export interface Memory {
|
|
|
36
36
|
hit_count: number;
|
|
37
37
|
scope: string;
|
|
38
38
|
tags: string[];
|
|
39
|
+
/**
|
|
40
|
+
* ADR-013 Step 2: optional structured payload. NULL for memories captured
|
|
41
|
+
* via plain capture_thought. Populated on memories backfilled from the
|
|
42
|
+
* decisions table (Step 5) with the original scope/decision/choice/etc.
|
|
43
|
+
*/
|
|
44
|
+
structured_fields: Record<string, unknown> | null;
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
export type MemoryActionCreate = {
|
|
@@ -45,6 +51,7 @@ export type MemoryActionCreate = {
|
|
|
45
51
|
confidence?: number;
|
|
46
52
|
scope?: string;
|
|
47
53
|
tags?: string[];
|
|
54
|
+
structuredFields?: Record<string, unknown> | null;
|
|
48
55
|
};
|
|
49
56
|
|
|
50
57
|
export type MemoryActionUpdate = {
|
|
@@ -108,9 +115,22 @@ function rowToMemory(row: Record<string, unknown>): Memory {
|
|
|
108
115
|
hit_count: row['hit_count'] as number,
|
|
109
116
|
scope: (row['scope'] as string) ?? 'project',
|
|
110
117
|
tags: parseTags(row['tags']),
|
|
118
|
+
structured_fields: parseStructuredFields(row['structured_fields']),
|
|
111
119
|
};
|
|
112
120
|
}
|
|
113
121
|
|
|
122
|
+
function parseStructuredFields(raw: unknown): Record<string, unknown> | null {
|
|
123
|
+
if (typeof raw !== 'string' || raw.length === 0) return null;
|
|
124
|
+
try {
|
|
125
|
+
const parsed = JSON.parse(raw);
|
|
126
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
127
|
+
? (parsed as Record<string, unknown>)
|
|
128
|
+
: null;
|
|
129
|
+
} catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
114
134
|
function parseTags(raw: unknown): string[] {
|
|
115
135
|
if (typeof raw !== 'string' || raw.length === 0) return [];
|
|
116
136
|
try {
|
|
@@ -477,6 +497,7 @@ export function createMemory(fields: {
|
|
|
477
497
|
source_unit_id?: string;
|
|
478
498
|
scope?: string;
|
|
479
499
|
tags?: string[];
|
|
500
|
+
structuredFields?: Record<string, unknown> | null;
|
|
480
501
|
}): string | null {
|
|
481
502
|
if (!isDbAvailable()) return null;
|
|
482
503
|
const adapter = _getAdapter();
|
|
@@ -497,6 +518,7 @@ export function createMemory(fields: {
|
|
|
497
518
|
updatedAt: now,
|
|
498
519
|
scope: fields.scope ?? 'project',
|
|
499
520
|
tags: fields.tags ?? [],
|
|
521
|
+
structuredFields: fields.structuredFields ?? null,
|
|
500
522
|
});
|
|
501
523
|
// Derive the real ID from the assigned seq (SELECT is still fine via adapter)
|
|
502
524
|
const row = adapter.prepare('SELECT seq FROM memories WHERE id = :id').get({ ':id': placeholder });
|
|
@@ -684,6 +706,10 @@ export function applyMemoryActions(
|
|
|
684
706
|
source_unit_id: unitId,
|
|
685
707
|
scope: action.scope,
|
|
686
708
|
tags: action.tags,
|
|
709
|
+
// ADR-013: forward structured payload through the action layer so
|
|
710
|
+
// bulk applyMemoryActions callers (extraction, ingestion) don't
|
|
711
|
+
// silently drop it.
|
|
712
|
+
structuredFields: action.structuredFields ?? null,
|
|
687
713
|
});
|
|
688
714
|
break;
|
|
689
715
|
case 'UPDATE':
|
|
@@ -561,6 +561,23 @@ function bareModelId(modelId: string): string {
|
|
|
561
561
|
return modelId.includes("/") ? modelId.split("/").pop()! : modelId;
|
|
562
562
|
}
|
|
563
563
|
|
|
564
|
+
// ─── Provider-specific Tool Limits ─────────────────────────────────────────
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Groq enforces a hard limit of 128 tools per request.
|
|
568
|
+
* Requests exceeding this limit receive a 400 error:
|
|
569
|
+
* "maximum number of items is 128"
|
|
570
|
+
* @see https://console.groq.com/docs/tool-use
|
|
571
|
+
*/
|
|
572
|
+
export const GROQ_MAX_TOOLS = 128;
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Provider IDs that map to the Groq API backend.
|
|
576
|
+
* Used to detect Groq at the GSD routing layer where only the provider string
|
|
577
|
+
* is available (the pi-ai openai-completions adapter is shared across providers).
|
|
578
|
+
*/
|
|
579
|
+
const GROQ_PROVIDER_IDS = new Set(["groq"]);
|
|
580
|
+
|
|
564
581
|
// ─── Tool Compatibility Filter (ADR-005 Phase 3) ───────────────────────────
|
|
565
582
|
|
|
566
583
|
/**
|
|
@@ -588,10 +605,17 @@ export function isToolCompatibleWithProvider(
|
|
|
588
605
|
/**
|
|
589
606
|
* Filter a list of tool names to only those compatible with a provider.
|
|
590
607
|
* Used by the routing pipeline to adjust tool sets when switching providers.
|
|
608
|
+
*
|
|
609
|
+
* @param toolNames - The full list of active tool names to filter.
|
|
610
|
+
* @param providerApi - The pi-ai API string (e.g. "openai-completions").
|
|
611
|
+
* @param provider - Optional provider ID (e.g. "groq"). Used to apply
|
|
612
|
+
* provider-specific limits that can't be expressed as API-level capabilities
|
|
613
|
+
* (e.g. Groq's 128-tool hard limit on the shared openai-completions adapter).
|
|
591
614
|
*/
|
|
592
615
|
export function filterToolsForProvider(
|
|
593
616
|
toolNames: string[],
|
|
594
617
|
providerApi: string,
|
|
618
|
+
provider?: string,
|
|
595
619
|
): { compatible: string[]; filtered: string[] } {
|
|
596
620
|
const providerCaps = getProviderCapabilities(providerApi);
|
|
597
621
|
|
|
@@ -611,6 +635,17 @@ export function filterToolsForProvider(
|
|
|
611
635
|
}
|
|
612
636
|
}
|
|
613
637
|
|
|
638
|
+
// Groq enforces a hard limit of 128 tools per request (#4376).
|
|
639
|
+
// Trim the compatible list to GROQ_MAX_TOOLS and move the excess to filtered.
|
|
640
|
+
if (provider && GROQ_PROVIDER_IDS.has(provider) && compatible.length > GROQ_MAX_TOOLS) {
|
|
641
|
+
const trimmed = compatible.splice(GROQ_MAX_TOOLS);
|
|
642
|
+
filtered.push(...trimmed);
|
|
643
|
+
console.warn(
|
|
644
|
+
`[gsd] Groq tool limit: ${compatible.length + trimmed.length} tools active but Groq allows at most ${GROQ_MAX_TOOLS}. ` +
|
|
645
|
+
`Trimming to the first ${GROQ_MAX_TOOLS} tools. Removed: ${trimmed.join(", ")}`,
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
|
|
614
649
|
return { compatible, filtered };
|
|
615
650
|
}
|
|
616
651
|
|
|
@@ -620,11 +655,17 @@ export function filterToolsForProvider(
|
|
|
620
655
|
*
|
|
621
656
|
* This is a hard filter only — it removes tools that would fail at the
|
|
622
657
|
* provider level. It does NOT remove tools based on soft heuristics.
|
|
658
|
+
*
|
|
659
|
+
* @param activeToolNames - The full list of currently active tool names.
|
|
660
|
+
* @param selectedModelApi - The pi-ai API string for the selected model.
|
|
661
|
+
* @param provider - Optional provider ID (e.g. "groq") for provider-specific
|
|
662
|
+
* limits beyond what the API-level capability profile expresses.
|
|
623
663
|
*/
|
|
624
664
|
export function adjustToolSet(
|
|
625
665
|
activeToolNames: string[],
|
|
626
666
|
selectedModelApi: string,
|
|
667
|
+
provider?: string,
|
|
627
668
|
): { toolNames: string[]; removedTools: string[] } {
|
|
628
|
-
const { compatible, filtered } = filterToolsForProvider(activeToolNames, selectedModelApi);
|
|
669
|
+
const { compatible, filtered } = filterToolsForProvider(activeToolNames, selectedModelApi, provider);
|
|
629
670
|
return { toolNames: compatible, removedTools: filtered };
|
|
630
671
|
}
|
|
@@ -91,8 +91,13 @@ export function extractPackageReferences(description: string): string[] {
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
// require('pkg') or import from 'pkg' in code blocks
|
|
95
|
-
|
|
94
|
+
// require('pkg') or `import ... from 'pkg'` in code blocks.
|
|
95
|
+
// The `from\s+['"]` branch MUST be preceded by an `import` keyword so that
|
|
96
|
+
// natural-language prose like `from "What's Next"` or `from 'master'` does
|
|
97
|
+
// not produce false package-existence failures. Requiring the leading import
|
|
98
|
+
// keyword anchors the match to JavaScript/TypeScript syntax.
|
|
99
|
+
// See: https://github.com/gsd-build/gsd-2/issues/4388
|
|
100
|
+
const importPattern = /(?:require\s*\(\s*['"]|import\b[\s\S]*?\bfrom\s+['"])([a-zA-Z0-9@/_-]+)['"\)]/g;
|
|
96
101
|
let importMatch: RegExpExecArray | null;
|
|
97
102
|
while ((importMatch = importPattern.exec(description)) !== null) {
|
|
98
103
|
// Skip relative imports and node builtins
|
|
@@ -323,9 +328,24 @@ function extractPathFromAnnotation(raw: string): string {
|
|
|
323
328
|
return backtickMatch[2].trim();
|
|
324
329
|
}
|
|
325
330
|
|
|
331
|
+
// Strip leading/trailing double or single quotes wrapping the whole value.
|
|
332
|
+
// Plan documents sometimes emit `"src/foo.ts"` or `'src/bar.ts'` as input
|
|
333
|
+
// annotations. Stripping the wrapper allows the inner path to be checked
|
|
334
|
+
// correctly instead of producing a false-positive "file not found" error
|
|
335
|
+
// for a literal string with quote characters in it (#3747).
|
|
336
|
+
const quoteMatch = trimmed.match(/^(["'])([^"']+)\1$/);
|
|
337
|
+
if (quoteMatch) {
|
|
338
|
+
return quoteMatch[2].trim();
|
|
339
|
+
}
|
|
340
|
+
|
|
326
341
|
const annotatedMatch = trimmed.match(/^(.+?)\s+[—–-]\s+.+$/);
|
|
327
342
|
if (annotatedMatch) {
|
|
328
|
-
|
|
343
|
+
const prefix = annotatedMatch[1].trim();
|
|
344
|
+
const prefixBacktickMatch = prefix.match(/`([^`]+)`/);
|
|
345
|
+
if (prefixBacktickMatch && looksLikePathOrUrl(prefixBacktickMatch[1].trim())) {
|
|
346
|
+
return prefixBacktickMatch[1].trim();
|
|
347
|
+
}
|
|
348
|
+
return prefix.replace(/`/g, "").trim();
|
|
329
349
|
}
|
|
330
350
|
|
|
331
351
|
// Fallback: scan all backticked tokens and return the first one that looks
|
|
@@ -388,13 +408,19 @@ function containsGlobPattern(candidate: string): boolean {
|
|
|
388
408
|
|
|
389
409
|
/**
|
|
390
410
|
* Build a set of files that will be created by tasks up to (but not including) taskIndex.
|
|
411
|
+
* Also includes outputs of completed tasks at any position — a completed task has already
|
|
412
|
+
* run and its outputs are available regardless of sequence position or disk state (#4071).
|
|
391
413
|
* All paths are normalized for consistent comparison.
|
|
392
414
|
*/
|
|
393
415
|
function getExpectedOutputsUpTo(tasks: TaskRow[], taskIndex: number): Set<string> {
|
|
394
416
|
const outputs = new Set<string>();
|
|
395
|
-
for (let i = 0; i <
|
|
396
|
-
|
|
397
|
-
|
|
417
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
418
|
+
const task = tasks[i];
|
|
419
|
+
// Include prior tasks (i < taskIndex) OR completed tasks at any position
|
|
420
|
+
if (i < taskIndex || task.status === "completed") {
|
|
421
|
+
for (const file of task.expected_output) {
|
|
422
|
+
outputs.add(normalizeFilePath(file));
|
|
423
|
+
}
|
|
398
424
|
}
|
|
399
425
|
}
|
|
400
426
|
return outputs;
|
|
@@ -481,13 +507,19 @@ export function checkTaskOrdering(
|
|
|
481
507
|
const results: PreExecutionCheckJSON[] = [];
|
|
482
508
|
|
|
483
509
|
// Build map: normalized file → task index that creates it
|
|
484
|
-
const fileCreators = new Map<string, { taskId: string; index: number; originalPath: string }>();
|
|
510
|
+
const fileCreators = new Map<string, { taskId: string; index: number; originalPath: string; completed: boolean }>();
|
|
485
511
|
for (let i = 0; i < tasks.length; i++) {
|
|
486
512
|
const task = tasks[i];
|
|
487
513
|
for (const file of task.expected_output) {
|
|
488
514
|
const normalizedFile = normalizeFilePath(file);
|
|
489
|
-
|
|
490
|
-
|
|
515
|
+
const existing = fileCreators.get(normalizedFile);
|
|
516
|
+
if (!existing || (!existing.completed && task.status === "completed")) {
|
|
517
|
+
fileCreators.set(normalizedFile, {
|
|
518
|
+
taskId: task.id,
|
|
519
|
+
index: i,
|
|
520
|
+
originalPath: file,
|
|
521
|
+
completed: task.status === "completed",
|
|
522
|
+
});
|
|
491
523
|
}
|
|
492
524
|
}
|
|
493
525
|
}
|
|
@@ -511,7 +543,11 @@ export function checkTaskOrdering(
|
|
|
511
543
|
const creator = fileCreators.get(normalizedFile);
|
|
512
544
|
const absolutePath = resolve(basePath, normalizedFile);
|
|
513
545
|
const existsOnDisk = existsSync(absolutePath);
|
|
514
|
-
if
|
|
546
|
+
// Skip if the creating task has already completed — its output is available
|
|
547
|
+
// regardless of disk state (e.g. file was a temp artifact cleaned up after
|
|
548
|
+
// the task ran, or a replan introduced a new earlier-sequence task that
|
|
549
|
+
// reads this pre-execution output). (#4071)
|
|
550
|
+
if (creator && creator.index > i && !existsOnDisk && !creator.completed) {
|
|
515
551
|
// Task reads file that is created later — impossible ordering
|
|
516
552
|
results.push({
|
|
517
553
|
category: "file",
|