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
|
@@ -55,7 +55,7 @@ import { hasPendingCaptures, loadPendingCaptures, revertExecutorResolvedCaptures
|
|
|
55
55
|
import { debugLog } from "./debug-logger.js";
|
|
56
56
|
import { runSafely } from "./auto-utils.js";
|
|
57
57
|
import type { AutoSession, SidecarItem } from "./auto/session.js";
|
|
58
|
-
import { getEvidence } from "./safety/evidence-collector.js";
|
|
58
|
+
import { getEvidence, clearEvidenceFromDisk } from "./safety/evidence-collector.js";
|
|
59
59
|
import { validateFileChanges } from "./safety/file-change-validator.js";
|
|
60
60
|
// crossReferenceEvidence available for future use when verification_evidence is stored in DB
|
|
61
61
|
// import { crossReferenceEvidence, type ClaimedEvidence } from "./safety/evidence-cross-ref.js";
|
|
@@ -107,7 +107,6 @@ import {
|
|
|
107
107
|
updateProgressWidget as _updateProgressWidget,
|
|
108
108
|
updateSliceProgressCache,
|
|
109
109
|
unitVerb,
|
|
110
|
-
hideFooter,
|
|
111
110
|
describeNextUnit,
|
|
112
111
|
} from "./auto-dashboard.js";
|
|
113
112
|
import { existsSync, unlinkSync } from "node:fs";
|
|
@@ -654,7 +653,7 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
654
653
|
if (taskRow) {
|
|
655
654
|
const expectedOutput = taskRow.expected_output ?? [];
|
|
656
655
|
const plannedFiles = taskRow.files ?? [];
|
|
657
|
-
const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles);
|
|
656
|
+
const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, safetyConfig.file_change_allowlist);
|
|
658
657
|
if (audit && audit.violations.length > 0) {
|
|
659
658
|
const warnings = audit.violations.filter(v => v.severity === "warning");
|
|
660
659
|
for (const v of warnings) {
|
|
@@ -712,6 +711,16 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
712
711
|
debugLog("postUnit", { phase: "safety-content-validation", error: String(e) });
|
|
713
712
|
}
|
|
714
713
|
}
|
|
714
|
+
|
|
715
|
+
// Clear persisted evidence file now that post-unit processing is complete
|
|
716
|
+
// (Bug #4385 — prevents stale evidence from affecting retries of same unit ID).
|
|
717
|
+
if (safetyConfig.evidence_collection && s.currentUnit.type === "execute-task" && sMid && sSid && sTid) {
|
|
718
|
+
try {
|
|
719
|
+
clearEvidenceFromDisk(s.basePath, sMid, sSid, sTid);
|
|
720
|
+
} catch (e) {
|
|
721
|
+
debugLog("postUnit", { phase: "safety-evidence-clear", error: String(e) });
|
|
722
|
+
}
|
|
723
|
+
}
|
|
715
724
|
}
|
|
716
725
|
} catch (e) {
|
|
717
726
|
debugLog("postUnit", { phase: "safety-harness", error: String(e) });
|
|
@@ -1134,6 +1143,15 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
1134
1143
|
`Pre-execution checks failed: ${blockingCount} blocking issue${blockingCount === 1 ? "" : "s"} found\n${details}${suffix}${evidenceNote}`,
|
|
1135
1144
|
"error",
|
|
1136
1145
|
);
|
|
1146
|
+
// Persist failure context so the next plan-slice re-dispatch can inject
|
|
1147
|
+
// it into the prompt and break the infinite loop (#4551).
|
|
1148
|
+
s.lastPreExecFailure = {
|
|
1149
|
+
unitId: currentUnit.id,
|
|
1150
|
+
blockingFindings: blockingChecks.map(
|
|
1151
|
+
c => `[${c.category}] ${c.target}: ${c.message}`,
|
|
1152
|
+
),
|
|
1153
|
+
verdictExcerpt: `status=${result.status}; ${blockingCount} blocking issue${blockingCount === 1 ? "" : "s"} detected`,
|
|
1154
|
+
};
|
|
1137
1155
|
preExecPauseNeeded = true;
|
|
1138
1156
|
} else if (result.status === "warn") {
|
|
1139
1157
|
ctx.ui.notify(
|
|
@@ -1142,6 +1160,14 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
1142
1160
|
);
|
|
1143
1161
|
// Strict mode: treat warnings as blocking
|
|
1144
1162
|
if (prefs?.enhanced_verification_strict === true) {
|
|
1163
|
+
const warnChecks = result.checks.filter(c => !c.passed);
|
|
1164
|
+
s.lastPreExecFailure = {
|
|
1165
|
+
unitId: currentUnit.id,
|
|
1166
|
+
blockingFindings: warnChecks.map(
|
|
1167
|
+
c => `[${c.category}] ${c.target}: ${c.message}`,
|
|
1168
|
+
),
|
|
1169
|
+
verdictExcerpt: `status=${result.status} (strict mode); ${warnChecks.length} warning${warnChecks.length === 1 ? "" : "s"} treated as blocking`,
|
|
1170
|
+
};
|
|
1145
1171
|
preExecPauseNeeded = true;
|
|
1146
1172
|
}
|
|
1147
1173
|
}
|
|
@@ -1380,7 +1380,18 @@ async function renderSlicePrompt(options: {
|
|
|
1380
1380
|
|
|
1381
1381
|
export async function buildPlanSlicePrompt(
|
|
1382
1382
|
mid: string, _midTitle: string, sid: string, sTitle: string, base: string, level?: InlineLevel,
|
|
1383
|
-
options?: {
|
|
1383
|
+
options?: {
|
|
1384
|
+
softScopeHint?: string;
|
|
1385
|
+
sessionContextWindow?: number;
|
|
1386
|
+
modelRegistry?: MinimalModelRegistry;
|
|
1387
|
+
/** Failure context from a prior pre-exec gate run (#4551). When present, a
|
|
1388
|
+
* "Fix these specific issues" section is appended so the LLM addresses the
|
|
1389
|
+
* exact problems instead of producing an identical plan that fails again. */
|
|
1390
|
+
priorPreExecFailure?: {
|
|
1391
|
+
blockingFindings: string[];
|
|
1392
|
+
verdictExcerpt: string;
|
|
1393
|
+
};
|
|
1394
|
+
},
|
|
1384
1395
|
): Promise<string> {
|
|
1385
1396
|
const prependBlocks: string[] = [];
|
|
1386
1397
|
// ADR-011: when the refining-phase dispatch rule gracefully downgrades to
|
|
@@ -1393,6 +1404,22 @@ export async function buildPlanSlicePrompt(
|
|
|
1393
1404
|
`This scope was captured during an earlier progressive-planning pass that was later disabled. Treat it as context only — you may plan beyond it if the work genuinely requires more scope. Do NOT treat this as a hard boundary.`,
|
|
1394
1405
|
);
|
|
1395
1406
|
}
|
|
1407
|
+
// #4551: inject pre-exec failure context so the re-dispatched plan-slice
|
|
1408
|
+
// addresses the exact blocked references rather than reproducing the same plan.
|
|
1409
|
+
if (options?.priorPreExecFailure) {
|
|
1410
|
+
const { blockingFindings, verdictExcerpt } = options.priorPreExecFailure;
|
|
1411
|
+
const findingsList = blockingFindings.length > 0
|
|
1412
|
+
? blockingFindings.map(f => `- ${f}`).join("\n")
|
|
1413
|
+
: "- (no specific findings recorded)";
|
|
1414
|
+
prependBlocks.push(
|
|
1415
|
+
`## Fix these specific issues from the prior pre-exec check\n\n` +
|
|
1416
|
+
`The previous plan-slice attempt was blocked by pre-execution validation.\n` +
|
|
1417
|
+
`Gate verdict: ${verdictExcerpt}\n\n` +
|
|
1418
|
+
`Blocked references that must be resolved in this plan:\n${findingsList}\n\n` +
|
|
1419
|
+
`Revise the plan so that every reference listed above is satisfied before execution begins. ` +
|
|
1420
|
+
`Do not reproduce the same file paths, package names, or task ordering that caused these failures.`,
|
|
1421
|
+
);
|
|
1422
|
+
}
|
|
1396
1423
|
return renderSlicePrompt({
|
|
1397
1424
|
mid, sid, sTitle, base,
|
|
1398
1425
|
level: level ?? resolveInlineLevel(),
|
|
@@ -13,7 +13,7 @@ import { appendEvent } from "./workflow-events.js";
|
|
|
13
13
|
import { atomicWriteSync } from "./atomic-write.js";
|
|
14
14
|
import { clearParseCache } from "./files.js";
|
|
15
15
|
import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from "./parsers-legacy.js";
|
|
16
|
-
import { isDbAvailable, getTask, getSlice, getSliceTasks, getPendingGates, updateTaskStatus, updateSliceStatus } from "./gsd-db.js";
|
|
16
|
+
import { isDbAvailable, getTask, getSlice, getSliceTasks, getPendingGates, updateTaskStatus, updateSliceStatus, insertSlice } from "./gsd-db.js";
|
|
17
17
|
import { isValidationTerminal } from "./state.js";
|
|
18
18
|
import { getErrorMessage } from "./error-utils.js";
|
|
19
19
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
@@ -268,11 +268,26 @@ export function verifyExpectedArtifact(
|
|
|
268
268
|
// RESEARCH file. Without this, resolveExpectedArtifactPath returns null and
|
|
269
269
|
// the retry/escalation machinery silently re-dispatches forever.
|
|
270
270
|
//
|
|
271
|
+
// #4068: Also treat a PARALLEL-BLOCKER placeholder as a terminal completion
|
|
272
|
+
// so that timeout-recovery can write the blocker, have verifyExpectedArtifact
|
|
273
|
+
// return true, and let the dispatch loop advance past this unit. Without
|
|
274
|
+
// this, the blocker is written but verification still returns false, the unit
|
|
275
|
+
// is never cleared from unitDispatchCount, and on the next iteration the
|
|
276
|
+
// dispatch rule (which correctly skips parallel-research when PARALLEL-BLOCKER
|
|
277
|
+
// exists) returns null — leaving the loop stuck re-deriving indefinitely.
|
|
278
|
+
//
|
|
271
279
|
// NOTE: this predicate mirrors the dispatch rule at
|
|
272
280
|
// auto-dispatch.ts parallel-research-slices — keep the two in sync.
|
|
273
281
|
if (unitType === "research-slice" && unitId.endsWith("/parallel-research")) {
|
|
274
282
|
const { milestone: mid } = parseUnitId(unitId);
|
|
275
283
|
if (!mid) return false;
|
|
284
|
+
|
|
285
|
+
// #4068: PARALLEL-BLOCKER written by timeout-recovery is a terminal state.
|
|
286
|
+
const blockerPath = resolveExpectedArtifactPath(unitType, unitId, base);
|
|
287
|
+
if (blockerPath && existsSync(blockerPath)) {
|
|
288
|
+
return true;
|
|
289
|
+
}
|
|
290
|
+
|
|
276
291
|
const roadmapFile = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
277
292
|
if (!roadmapFile || !existsSync(roadmapFile)) {
|
|
278
293
|
logWarning("recovery", `verify-fail ${unitType} ${unitId}: roadmap missing`);
|
|
@@ -532,6 +547,16 @@ export function writeBlockerPlaceholder(
|
|
|
532
547
|
try { updateSliceStatus(mid, sid, "complete", ts); } catch (e) { logWarning("recovery", `updateSliceStatus failed during context exhaustion: ${e instanceof Error ? e.message : String(e)}`); }
|
|
533
548
|
try { appendEvent(base, { cmd: "complete-slice", params: { milestoneId: mid, sliceId: sid }, ts, actor: "system", trigger_reason: "blocker-placeholder-recovery" }); } catch (e) { logWarning("recovery", `appendEvent failed for slice recovery: ${e instanceof Error ? e.message : String(e)}`); }
|
|
534
549
|
}
|
|
550
|
+
// Insert a placeholder complete slice so deriveState sees activeMilestoneSlices.length > 0
|
|
551
|
+
// and exits the pre-planning phase. Without this, activeMilestoneSlices stays empty
|
|
552
|
+
// after the blocker ROADMAP.md is written, causing deriveState to return phase:'pre-planning'
|
|
553
|
+
// indefinitely and re-dispatching plan-milestone in an infinite loop (#4378).
|
|
554
|
+
if (unitType === "plan-milestone" && mid) {
|
|
555
|
+
try {
|
|
556
|
+
insertSlice({ id: "S00-blocker", milestoneId: mid, title: "Blocker placeholder — planning failed", status: "complete", sequence: 0 });
|
|
557
|
+
} catch (e) { logWarning("recovery", `insertSlice placeholder failed for plan-milestone recovery: ${e instanceof Error ? e.message : String(e)}`); }
|
|
558
|
+
try { appendEvent(base, { cmd: "plan-milestone", params: { milestoneId: mid }, ts, actor: "system", trigger_reason: "blocker-placeholder-recovery" }); } catch (e) { logWarning("recovery", `appendEvent failed for plan-milestone recovery: ${e instanceof Error ? e.message : String(e)}`); }
|
|
559
|
+
}
|
|
535
560
|
}
|
|
536
561
|
|
|
537
562
|
return diagnoseExpectedArtifact(unitType, unitId, base);
|
|
@@ -60,8 +60,8 @@ import { initRoutingHistory } from "./routing-history.js";
|
|
|
60
60
|
import { restoreHookState, resetHookState } from "./post-unit-hooks.js";
|
|
61
61
|
import { resetProactiveHealing, setLevelChangeCallback } from "./doctor-proactive.js";
|
|
62
62
|
import { snapshotSkills } from "./skill-discovery.js";
|
|
63
|
-
import { isDbAvailable, getMilestone, openDatabase } from "./gsd-db.js";
|
|
64
|
-
|
|
63
|
+
import { isDbAvailable, getMilestone, openDatabase, getDbStatus } from "./gsd-db.js";
|
|
64
|
+
|
|
65
65
|
import {
|
|
66
66
|
debugLog,
|
|
67
67
|
enableDebug,
|
|
@@ -92,7 +92,7 @@ import type { WorktreeResolver } from "./worktree-resolver.js";
|
|
|
92
92
|
import { getSessionModelOverride } from "./session-model-override.js";
|
|
93
93
|
|
|
94
94
|
export interface BootstrapDeps {
|
|
95
|
-
shouldUseWorktreeIsolation: () => boolean;
|
|
95
|
+
shouldUseWorktreeIsolation: (basePath?: string) => boolean;
|
|
96
96
|
registerSigtermHandler: (basePath: string) => void;
|
|
97
97
|
lockBase: () => string;
|
|
98
98
|
buildResolver: () => WorktreeResolver;
|
|
@@ -273,8 +273,8 @@ export async function bootstrapAutoSession(
|
|
|
273
273
|
//
|
|
274
274
|
// Precedence:
|
|
275
275
|
// 1) Explicit session override via /gsd model (this session)
|
|
276
|
-
// 2)
|
|
277
|
-
// 3)
|
|
276
|
+
// 2) Current session model from settings/session restore (if provider ready)
|
|
277
|
+
// 3) GSD model preferences from PREFERENCES.md (validated against live auth)
|
|
278
278
|
//
|
|
279
279
|
// This preserves #3517 defaults while honoring explicit runtime model
|
|
280
280
|
// selection for subsequent /gsd runs in the same session.
|
|
@@ -314,11 +314,14 @@ export async function bootstrapAutoSession(
|
|
|
314
314
|
}
|
|
315
315
|
const sessionModelReady =
|
|
316
316
|
ctx.model && ctx.modelRegistry.isProviderRequestReady(ctx.model.provider);
|
|
317
|
+
const currentSessionModel = (sessionModelReady && ctx.model)
|
|
318
|
+
? { provider: ctx.model.provider, id: ctx.model.id }
|
|
319
|
+
: null;
|
|
320
|
+
const startThinkingSnapshot = pi.getThinkingLevel();
|
|
317
321
|
const startModelSnapshot = manualSessionOverride
|
|
322
|
+
?? currentSessionModel
|
|
318
323
|
?? validatedPreferredModel
|
|
319
|
-
??
|
|
320
|
-
? { provider: ctx.model.provider, id: ctx.model.id }
|
|
321
|
-
: null);
|
|
324
|
+
?? null;
|
|
322
325
|
|
|
323
326
|
try {
|
|
324
327
|
// Validate GSD_PROJECT_ID early so the user gets immediate feedback
|
|
@@ -340,7 +343,7 @@ export async function bootstrapAutoSession(
|
|
|
340
343
|
const hasLocalGit = existsSync(join(base, ".git"));
|
|
341
344
|
if (!hasLocalGit || isInheritedRepo(base)) {
|
|
342
345
|
const mainBranch =
|
|
343
|
-
loadEffectiveGSDPreferences()?.preferences?.git?.main_branch || "main";
|
|
346
|
+
loadEffectiveGSDPreferences(base)?.preferences?.git?.main_branch || "main";
|
|
344
347
|
nativeInit(base, mainBranch);
|
|
345
348
|
}
|
|
346
349
|
|
|
@@ -358,7 +361,7 @@ export async function bootstrapAutoSession(
|
|
|
358
361
|
// Ensure .gitignore has baseline patterns.
|
|
359
362
|
// ensureGitignore checks for git-tracked .gsd/ files and skips the
|
|
360
363
|
// ".gsd" pattern if the project intentionally tracks .gsd/ in git.
|
|
361
|
-
const gitPrefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
364
|
+
const gitPrefs = loadEffectiveGSDPreferences(base)?.preferences?.git;
|
|
362
365
|
const manageGitignore = gitPrefs?.manage_gitignore;
|
|
363
366
|
ensureGitignore(base, { manageGitignore });
|
|
364
367
|
if (manageGitignore !== false) untrackRuntimeFiles(base);
|
|
@@ -387,7 +390,7 @@ export async function bootstrapAutoSession(
|
|
|
387
390
|
// Initialize GitServiceImpl
|
|
388
391
|
s.gitService = new GitServiceImpl(
|
|
389
392
|
s.basePath,
|
|
390
|
-
loadEffectiveGSDPreferences()?.preferences?.git ?? {},
|
|
393
|
+
loadEffectiveGSDPreferences(base)?.preferences?.git ?? {},
|
|
391
394
|
);
|
|
392
395
|
|
|
393
396
|
// ── Debug mode ──
|
|
@@ -431,7 +434,7 @@ export async function bootstrapAutoSession(
|
|
|
431
434
|
// was lost due to session ending between completion and teardown.
|
|
432
435
|
// Must run after DB open and before worktree entry.
|
|
433
436
|
try {
|
|
434
|
-
const auditResult = auditOrphanedMilestoneBranches(base, getIsolationMode());
|
|
437
|
+
const auditResult = auditOrphanedMilestoneBranches(base, getIsolationMode(base));
|
|
435
438
|
for (const msg of auditResult.recovered) {
|
|
436
439
|
ctx.ui.notify(`Orphan audit: ${msg}`, "info");
|
|
437
440
|
}
|
|
@@ -451,7 +454,7 @@ export async function bootstrapAutoSession(
|
|
|
451
454
|
// Stale worktree state recovery (#654)
|
|
452
455
|
if (
|
|
453
456
|
state.activeMilestone &&
|
|
454
|
-
shouldUseWorktreeIsolation() &&
|
|
457
|
+
shouldUseWorktreeIsolation(base) &&
|
|
455
458
|
!detectWorktreeName(base)
|
|
456
459
|
) {
|
|
457
460
|
const wtPath = getAutoWorktreePath(base, state.activeMilestone.id);
|
|
@@ -469,7 +472,7 @@ export async function bootstrapAutoSession(
|
|
|
469
472
|
if (
|
|
470
473
|
state.activeMilestone &&
|
|
471
474
|
(state.phase === "pre-planning" || state.phase === "complete") &&
|
|
472
|
-
getIsolationMode() !== "none" &&
|
|
475
|
+
getIsolationMode(base) !== "none" &&
|
|
473
476
|
!detectWorktreeName(base) &&
|
|
474
477
|
!base.includes(`${pathSep}.gsd${pathSep}worktrees${pathSep}`)
|
|
475
478
|
) {
|
|
@@ -550,37 +553,15 @@ export async function bootstrapAutoSession(
|
|
|
550
553
|
const { showSmartEntry } = await import("./guided-flow.js");
|
|
551
554
|
await showSmartEntry(ctx, pi, base, { step: requestedStepMode });
|
|
552
555
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
} else if (
|
|
563
|
-
postState.activeMilestone &&
|
|
564
|
-
postState.phase === "pre-planning"
|
|
565
|
-
) {
|
|
566
|
-
const contextFile = resolveMilestoneFile(
|
|
567
|
-
base,
|
|
568
|
-
postState.activeMilestone.id,
|
|
569
|
-
"CONTEXT",
|
|
570
|
-
);
|
|
571
|
-
const hasContext = !!(contextFile && (await loadFile(contextFile)));
|
|
572
|
-
if (hasContext) {
|
|
573
|
-
state = postState;
|
|
574
|
-
} else {
|
|
575
|
-
ctx.ui.notify(
|
|
576
|
-
"Discussion completed but no milestone context was written. Run /gsd to try the discussion again, or /gsd auto after creating the milestone manually.",
|
|
577
|
-
"warning",
|
|
578
|
-
);
|
|
579
|
-
return releaseLockAndReturn();
|
|
580
|
-
}
|
|
581
|
-
} else {
|
|
582
|
-
return releaseLockAndReturn();
|
|
583
|
-
}
|
|
556
|
+
// showSmartEntry dispatches via pi.sendMessage() which is fire-and-forget:
|
|
557
|
+
// it queues the message and returns immediately, before the LLM turn runs.
|
|
558
|
+
// Checking postState here would always see the pre-dispatch state, causing
|
|
559
|
+
// the premature "Discussion completed but..." warning (#3420).
|
|
560
|
+
//
|
|
561
|
+
// checkAutoStartAfterDiscuss (in guided-flow.ts) already handles re-entering
|
|
562
|
+
// auto-mode by calling startAutoDetached after the discussion completes.
|
|
563
|
+
// Release the lock and let the async dispatch proceed.
|
|
564
|
+
return releaseLockAndReturn();
|
|
584
565
|
}
|
|
585
566
|
|
|
586
567
|
// Active milestone exists but has no roadmap
|
|
@@ -592,17 +573,16 @@ export async function bootstrapAutoSession(
|
|
|
592
573
|
const { showSmartEntry } = await import("./guided-flow.js");
|
|
593
574
|
await showSmartEntry(ctx, pi, base, { step: requestedStepMode });
|
|
594
575
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
}
|
|
576
|
+
// showSmartEntry dispatches via pi.sendMessage() which is fire-and-forget:
|
|
577
|
+
// it queues the message and returns immediately, before the LLM turn runs.
|
|
578
|
+
// Checking postState here fires before the LLM has had a turn, so the
|
|
579
|
+
// pre-planning phase would still appear unchanged and a premature warning
|
|
580
|
+
// would be emitted (#3420).
|
|
581
|
+
//
|
|
582
|
+
// checkAutoStartAfterDiscuss (in guided-flow.ts) already handles re-entering
|
|
583
|
+
// auto-mode by calling startAutoDetached after the discussion completes.
|
|
584
|
+
// Release the lock and let the async dispatch proceed.
|
|
585
|
+
return releaseLockAndReturn();
|
|
606
586
|
}
|
|
607
587
|
}
|
|
608
588
|
|
|
@@ -664,15 +644,16 @@ export async function bootstrapAutoSession(
|
|
|
664
644
|
s.pendingQuickTasks = [];
|
|
665
645
|
s.currentUnit = null;
|
|
666
646
|
s.currentMilestoneId = state.activeMilestone?.id ?? null;
|
|
667
|
-
s.originalModelId = ctx.model?.id ?? null;
|
|
668
|
-
s.originalModelProvider = ctx.model?.provider ?? null;
|
|
647
|
+
s.originalModelId = startModelSnapshot?.id ?? ctx.model?.id ?? null;
|
|
648
|
+
s.originalModelProvider = startModelSnapshot?.provider ?? ctx.model?.provider ?? null;
|
|
649
|
+
s.originalThinkingLevel = startThinkingSnapshot ?? null;
|
|
669
650
|
|
|
670
651
|
// Register SIGTERM handler
|
|
671
652
|
registerSigtermHandler(base);
|
|
672
653
|
|
|
673
654
|
// Capture integration branch
|
|
674
655
|
if (s.currentMilestoneId) {
|
|
675
|
-
if (getIsolationMode() !== "none") {
|
|
656
|
+
if (getIsolationMode(base) !== "none") {
|
|
676
657
|
captureIntegrationBranch(base, s.currentMilestoneId);
|
|
677
658
|
}
|
|
678
659
|
setActiveMilestoneId(base, s.currentMilestoneId);
|
|
@@ -681,7 +662,7 @@ export async function bootstrapAutoSession(
|
|
|
681
662
|
// Guard against stale milestone branch when isolation:none (#3613).
|
|
682
663
|
// A prior session with isolation:branch/worktree may have left HEAD on
|
|
683
664
|
// milestone/<MID>. Auto-checkout back to the integration branch.
|
|
684
|
-
if (getIsolationMode() === "none" && nativeIsRepo(base)) {
|
|
665
|
+
if (getIsolationMode(base) === "none" && nativeIsRepo(base)) {
|
|
685
666
|
try {
|
|
686
667
|
const currentBranch = nativeGetCurrentBranch(base);
|
|
687
668
|
if (currentBranch.startsWith("milestone/")) {
|
|
@@ -712,7 +693,7 @@ export async function bootstrapAutoSession(
|
|
|
712
693
|
|
|
713
694
|
if (
|
|
714
695
|
s.currentMilestoneId &&
|
|
715
|
-
getIsolationMode() !== "none" &&
|
|
696
|
+
getIsolationMode(base) !== "none" &&
|
|
716
697
|
!detectWorktreeName(base) &&
|
|
717
698
|
!isUnderGsdWorktrees(base)
|
|
718
699
|
) {
|
|
@@ -758,9 +739,22 @@ export async function bootstrapAutoSession(
|
|
|
758
739
|
// call returns "db_unavailable", triggering artifact-retry which
|
|
759
740
|
// re-dispatches the same task — producing an infinite loop (#2419).
|
|
760
741
|
if (existsSync(gsdDbPath) && !isDbAvailable()) {
|
|
742
|
+
const dbStatus = getDbStatus();
|
|
743
|
+
const phaseHint = dbStatus.lastPhase === "open"
|
|
744
|
+
? "The database file could not be opened"
|
|
745
|
+
: dbStatus.lastPhase === "initSchema"
|
|
746
|
+
? "The database schema could not be initialized"
|
|
747
|
+
: dbStatus.lastPhase === "vacuum-recovery"
|
|
748
|
+
? "Corruption recovery (VACUUM) failed"
|
|
749
|
+
: dbStatus.attempted
|
|
750
|
+
? "The database could not be opened (phase unknown)"
|
|
751
|
+
: "The database provider could not be loaded";
|
|
752
|
+
const errorDetail = dbStatus.lastError ? ` (${dbStatus.lastError.message})` : "";
|
|
753
|
+
const providerHint = dbStatus.provider
|
|
754
|
+
? ` Provider: ${dbStatus.provider}.`
|
|
755
|
+
: " No SQLite provider available — check Node >= 22 or install better-sqlite3.";
|
|
761
756
|
ctx.ui.notify(
|
|
762
|
-
|
|
763
|
-
"Check for corrupt gsd.db or missing native SQLite bindings.",
|
|
757
|
+
`SQLite database exists but failed to open: ${gsdDbPath}. ${phaseHint}${errorDetail}.${providerHint}`,
|
|
764
758
|
"error",
|
|
765
759
|
);
|
|
766
760
|
return releaseLockAndReturn();
|
|
@@ -779,6 +773,7 @@ export async function bootstrapAutoSession(
|
|
|
779
773
|
id: startModelSnapshot.id,
|
|
780
774
|
};
|
|
781
775
|
}
|
|
776
|
+
s.autoModeStartThinkingLevel = startThinkingSnapshot ?? null;
|
|
782
777
|
s.manualSessionModelOverride = manualSessionOverride ?? null;
|
|
783
778
|
|
|
784
779
|
// Apply worker model override from parallel orchestrator (#worker-model).
|
|
@@ -801,14 +796,11 @@ export async function bootstrapAutoSession(
|
|
|
801
796
|
}
|
|
802
797
|
|
|
803
798
|
// Snapshot installed skills
|
|
804
|
-
if (resolveSkillDiscoveryMode() !== "off") {
|
|
799
|
+
if (resolveSkillDiscoveryMode(base) !== "off") {
|
|
805
800
|
snapshotSkills();
|
|
806
801
|
}
|
|
807
802
|
|
|
808
803
|
ctx.ui.setStatus("gsd-auto", s.stepMode ? "next" : "auto");
|
|
809
|
-
ctx.ui.setFooter(hideFooter);
|
|
810
|
-
// Hide gsd-health during AUTO — gsd-progress is the single source of truth
|
|
811
|
-
// for last-commit / cost / health signal while auto is running.
|
|
812
804
|
ctx.ui.setWidget("gsd-health", undefined);
|
|
813
805
|
const modeLabel = s.stepMode ? "Step-mode" : "Auto-mode";
|
|
814
806
|
const pendingCount = (state.registry ?? []).filter(
|
|
@@ -835,7 +827,7 @@ export async function bootstrapAutoSession(
|
|
|
835
827
|
// FlatRateContext used by selectAndApplyModel so user-declared
|
|
836
828
|
// flat-rate providers and externalCli auto-detection are respected.
|
|
837
829
|
const { isFlatRateProvider, buildFlatRateContext } = await import("./auto-model-selection.js");
|
|
838
|
-
const bannerPrefs = loadEffectiveGSDPreferences()?.preferences;
|
|
830
|
+
const bannerPrefs = loadEffectiveGSDPreferences(base)?.preferences;
|
|
839
831
|
const effectiveProvider = s.autoModeStartModel?.provider ?? ctx.model?.provider;
|
|
840
832
|
const effectivelyEnabled = routingConfig.enabled
|
|
841
833
|
&& (routingConfig.allow_flat_rate_providers
|
|
@@ -526,6 +526,39 @@ export async function runPostUnitVerification(
|
|
|
526
526
|
result.passed = false;
|
|
527
527
|
}
|
|
528
528
|
|
|
529
|
+
// Emit Layer 2 verify_result event with the final, post-exec verdict so hooks
|
|
530
|
+
// see the authoritative pass/fail and the complete set of failures.
|
|
531
|
+
try {
|
|
532
|
+
const { emitVerifyResult } = await import("./hook-emitter.js");
|
|
533
|
+
const checkFailures = result.checks
|
|
534
|
+
.filter((c) => c.exitCode !== 0)
|
|
535
|
+
.map((c) => ({
|
|
536
|
+
kind: "gate" as const,
|
|
537
|
+
message: `${c.command} exited ${c.exitCode}${c.stderr ? `: ${c.stderr.slice(0, 200)}` : ""}`,
|
|
538
|
+
}));
|
|
539
|
+
const runtimeFailures = (result.runtimeErrors ?? [])
|
|
540
|
+
.filter((e) => e.blocking)
|
|
541
|
+
.map((e) => ({
|
|
542
|
+
kind: "other" as const,
|
|
543
|
+
message: `[${e.source}] ${e.message.slice(0, 200)}`,
|
|
544
|
+
}));
|
|
545
|
+
const postExecFailures = (postExecChecks ?? [])
|
|
546
|
+
.filter((c) => !c.passed)
|
|
547
|
+
.map((c) => ({
|
|
548
|
+
kind: "other" as const,
|
|
549
|
+
message: `[${c.category}] ${c.target}: ${c.message}`,
|
|
550
|
+
}));
|
|
551
|
+
await emitVerifyResult({
|
|
552
|
+
passed: result.passed,
|
|
553
|
+
failures: [...checkFailures, ...runtimeFailures, ...postExecFailures],
|
|
554
|
+
unitType: s.currentUnit.type,
|
|
555
|
+
unitId: s.currentUnit.id,
|
|
556
|
+
cwd: s.basePath,
|
|
557
|
+
});
|
|
558
|
+
} catch (hookErr) {
|
|
559
|
+
logWarning("engine", `verify_result hook emission failed: ${(hookErr as Error).message}`);
|
|
560
|
+
}
|
|
561
|
+
|
|
529
562
|
// ── Auto-fix retry logic ──
|
|
530
563
|
if (result.passed) {
|
|
531
564
|
s.verificationRetryCount.delete(s.currentUnit.id);
|
|
@@ -238,14 +238,6 @@ function clearProjectRootStateFiles(basePath: string, milestoneId: string): void
|
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
-
function isProjectGsdSymlink(basePath: string): boolean {
|
|
242
|
-
try {
|
|
243
|
-
return lstatSyncFn(join(basePath, ".gsd")).isSymbolicLink();
|
|
244
|
-
} catch {
|
|
245
|
-
return false;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
241
|
// ─── Build Artifact Auto-Resolve ─────────────────────────────────────────────
|
|
250
242
|
|
|
251
243
|
/** Patterns for machine-generated build artifacts that can be safely
|
|
@@ -1664,54 +1656,15 @@ export function mergeMilestoneToMain(
|
|
|
1664
1656
|
}
|
|
1665
1657
|
}
|
|
1666
1658
|
|
|
1667
|
-
// 7.
|
|
1668
|
-
// blocked by unrelated local changes (#2151). clearProjectRootStateFiles
|
|
1669
|
-
// only removes untracked .gsd/ files; tracked dirty files elsewhere (e.g.
|
|
1670
|
-
// .planning/work-state.json with stash conflict markers) are invisible to
|
|
1671
|
-
// that cleanup but will cause `git merge --squash` to reject.
|
|
1672
|
-
let stashed = false;
|
|
1673
|
-
try {
|
|
1674
|
-
const status = execFileSync("git", ["status", "--porcelain"], {
|
|
1675
|
-
cwd: originalBasePath_,
|
|
1676
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1677
|
-
encoding: "utf-8",
|
|
1678
|
-
}).trim();
|
|
1679
|
-
if (status) {
|
|
1680
|
-
// Use --include-untracked to stash untracked files that would block
|
|
1681
|
-
// the squash merge, but EXCLUDE .gsd/milestones/ (#2505).
|
|
1682
|
-
// --include-untracked without exclusion sweeps queued milestone
|
|
1683
|
-
// CONTEXT files into the stash. If stash pop later fails, those files
|
|
1684
|
-
// are permanently trapped in the stash entry and lost on the next
|
|
1685
|
-
// stash push or drop.
|
|
1686
|
-
//
|
|
1687
|
-
// When `.gsd` itself is a symlink, Git rejects pathspecs below it
|
|
1688
|
-
// ("beyond a symbolic link"). In that layout, exclude the whole symlink
|
|
1689
|
-
// and keep stashing real project files that could block the merge.
|
|
1690
|
-
const stashPathspecs = isProjectGsdSymlink(originalBasePath_)
|
|
1691
|
-
? [".", ":(exclude).gsd"]
|
|
1692
|
-
: [":(exclude).gsd/milestones"];
|
|
1693
|
-
execFileSync(
|
|
1694
|
-
"git",
|
|
1695
|
-
[
|
|
1696
|
-
"stash", "push", "--include-untracked",
|
|
1697
|
-
"-m", `gsd: pre-merge stash for ${milestoneId}`,
|
|
1698
|
-
"--", ...stashPathspecs,
|
|
1699
|
-
],
|
|
1700
|
-
{ cwd: originalBasePath_, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" },
|
|
1701
|
-
);
|
|
1702
|
-
stashed = true;
|
|
1703
|
-
}
|
|
1704
|
-
} catch (err) {
|
|
1705
|
-
// Stash failure is non-fatal — proceed without stash and let the merge
|
|
1706
|
-
// report the dirty tree if it fails.
|
|
1707
|
-
logWarning("worktree", `git stash failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1708
|
-
}
|
|
1709
|
-
|
|
1710
|
-
// 7a. Shelter queued milestone directories before the squash merge (#2505).
|
|
1659
|
+
// 7. Shelter queued milestone directories before the squash merge (#2505).
|
|
1711
1660
|
// The milestone branch may contain copies of queued milestone dirs (via
|
|
1712
1661
|
// copyPlanningArtifacts), so `git merge --squash` rejects when those same
|
|
1713
1662
|
// files exist as untracked in the working tree. Temporarily move them to
|
|
1714
1663
|
// a backup location, then restore after the merge+commit.
|
|
1664
|
+
//
|
|
1665
|
+
// MUST run BEFORE the pre-merge stash (step 7a) so `--include-untracked`
|
|
1666
|
+
// does not sweep queued CONTEXT files into the stash. If stash pop later
|
|
1667
|
+
// fails, files trapped inside the stash are permanently lost (#2505).
|
|
1715
1668
|
const milestonesDir = join(gsdRoot(originalBasePath_), "milestones");
|
|
1716
1669
|
const shelterDir = join(gsdRoot(originalBasePath_), ".milestone-shelter");
|
|
1717
1670
|
const shelteredDirs: string[] = [];
|
|
@@ -1759,6 +1712,35 @@ export function mergeMilestoneToMain(
|
|
|
1759
1712
|
logWarning("worktree", `milestone shelter operation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1760
1713
|
}
|
|
1761
1714
|
|
|
1715
|
+
// 7a. Stash pre-existing dirty files so the squash merge is not blocked by
|
|
1716
|
+
// unrelated local changes (#2151). Includes untracked files to handle
|
|
1717
|
+
// locally-added files that conflict with tracked files on the milestone
|
|
1718
|
+
// branch. Passing NO pathspec lets git skip gitignored paths silently;
|
|
1719
|
+
// adding an explicit pathspec trips a `git add`-style fatal on ignored
|
|
1720
|
+
// entries (e.g. a gitignored `.gsd` symlink under ADR-002) (#4573).
|
|
1721
|
+
// Queued CONTEXT files under `.gsd/milestones/*` are already sheltered
|
|
1722
|
+
// in step 7 above, so they won't be swept into the stash.
|
|
1723
|
+
let stashed = false;
|
|
1724
|
+
try {
|
|
1725
|
+
const status = execFileSync("git", ["status", "--porcelain"], {
|
|
1726
|
+
cwd: originalBasePath_,
|
|
1727
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1728
|
+
encoding: "utf-8",
|
|
1729
|
+
}).trim();
|
|
1730
|
+
if (status) {
|
|
1731
|
+
execFileSync(
|
|
1732
|
+
"git",
|
|
1733
|
+
["stash", "push", "--include-untracked", "-m", `gsd: pre-merge stash for ${milestoneId}`],
|
|
1734
|
+
{ cwd: originalBasePath_, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" },
|
|
1735
|
+
);
|
|
1736
|
+
stashed = true;
|
|
1737
|
+
}
|
|
1738
|
+
} catch (err) {
|
|
1739
|
+
// Stash failure is non-fatal — proceed without stash and let the merge
|
|
1740
|
+
// report the dirty tree if it fails.
|
|
1741
|
+
logWarning("worktree", `git stash failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1762
1744
|
// 7b. Clean up stale merge state before attempting squash merge (#2912).
|
|
1763
1745
|
// A leftover MERGE_HEAD (from a previous failed merge, libgit2 native path,
|
|
1764
1746
|
// or interrupted operation) causes `git merge --squash` to refuse with
|
|
@@ -2012,21 +1994,38 @@ export function mergeMilestoneToMain(
|
|
|
2012
1994
|
// When a milestone only produced .gsd/ metadata (summaries, roadmaps) but no
|
|
2013
1995
|
// real code, the user sees "milestone complete" but nothing changed in their
|
|
2014
1996
|
// codebase. Surface this so the caller can warn the user.
|
|
1997
|
+
//
|
|
1998
|
+
// Bug #4385 fix: use `git diff-tree --root` instead of `git diff HEAD~1 HEAD`.
|
|
1999
|
+
// `HEAD~1` does not exist on initial commits and is unreliable on shallow clones
|
|
2000
|
+
// and merge commits. `diff-tree --root` handles all three cases correctly.
|
|
2001
|
+
// The empty-tree hash (4b825dc…) is the universal fallback for refs that don't exist.
|
|
2002
|
+
const GIT_EMPTY_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
2015
2003
|
let codeFilesChanged = false;
|
|
2016
2004
|
if (!nothingToCommit) {
|
|
2017
2005
|
try {
|
|
2018
|
-
const
|
|
2019
|
-
|
|
2020
|
-
"HEAD
|
|
2021
|
-
"
|
|
2022
|
-
);
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
);
|
|
2006
|
+
const diffTreeOutput = execFileSync(
|
|
2007
|
+
"git",
|
|
2008
|
+
["diff-tree", "--root", "--no-commit-id", "-r", "--name-only", "HEAD"],
|
|
2009
|
+
{ cwd: originalBasePath_, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" },
|
|
2010
|
+
).trim();
|
|
2011
|
+
const mergedFiles = diffTreeOutput ? diffTreeOutput.split("\n").filter(Boolean) : [];
|
|
2012
|
+
codeFilesChanged = mergedFiles.some((f) => !f.startsWith(".gsd/"));
|
|
2026
2013
|
} catch (e) {
|
|
2027
|
-
//
|
|
2028
|
-
|
|
2029
|
-
|
|
2014
|
+
// diff-tree failed (e.g. unborn HEAD in a brand-new repo) — fall back to
|
|
2015
|
+
// comparing against the empty tree so initial-commit repos still report changes.
|
|
2016
|
+
try {
|
|
2017
|
+
const fallbackOutput = execFileSync(
|
|
2018
|
+
"git",
|
|
2019
|
+
["diff", "--name-only", GIT_EMPTY_TREE, "HEAD"],
|
|
2020
|
+
{ cwd: originalBasePath_, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" },
|
|
2021
|
+
).trim();
|
|
2022
|
+
const fallbackFiles = fallbackOutput ? fallbackOutput.split("\n").filter(Boolean) : [];
|
|
2023
|
+
codeFilesChanged = fallbackFiles.some((f) => !f.startsWith(".gsd/"));
|
|
2024
|
+
} catch {
|
|
2025
|
+
// Truly unable to determine — assume code was changed to avoid silent data loss
|
|
2026
|
+
logWarning("worktree", `diff-tree and empty-tree fallback both failed (assuming code changed): ${(e as Error).message}`);
|
|
2027
|
+
codeFilesChanged = true;
|
|
2028
|
+
}
|
|
2030
2029
|
}
|
|
2031
2030
|
}
|
|
2032
2031
|
|