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
|
@@ -11,7 +11,7 @@ import { appendEvent } from "./workflow-events.js";
|
|
|
11
11
|
import { atomicWriteSync } from "./atomic-write.js";
|
|
12
12
|
import { clearParseCache } from "./files.js";
|
|
13
13
|
import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from "./parsers-legacy.js";
|
|
14
|
-
import { isDbAvailable, getTask, getSlice, getSliceTasks, getPendingGates, updateTaskStatus, updateSliceStatus } from "./gsd-db.js";
|
|
14
|
+
import { isDbAvailable, getTask, getSlice, getSliceTasks, getPendingGates, updateTaskStatus, updateSliceStatus, insertSlice } from "./gsd-db.js";
|
|
15
15
|
import { isValidationTerminal } from "./state.js";
|
|
16
16
|
import { getErrorMessage } from "./error-utils.js";
|
|
17
17
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
@@ -220,12 +220,25 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
|
|
|
220
220
|
// RESEARCH file. Without this, resolveExpectedArtifactPath returns null and
|
|
221
221
|
// the retry/escalation machinery silently re-dispatches forever.
|
|
222
222
|
//
|
|
223
|
+
// #4068: Also treat a PARALLEL-BLOCKER placeholder as a terminal completion
|
|
224
|
+
// so that timeout-recovery can write the blocker, have verifyExpectedArtifact
|
|
225
|
+
// return true, and let the dispatch loop advance past this unit. Without
|
|
226
|
+
// this, the blocker is written but verification still returns false, the unit
|
|
227
|
+
// is never cleared from unitDispatchCount, and on the next iteration the
|
|
228
|
+
// dispatch rule (which correctly skips parallel-research when PARALLEL-BLOCKER
|
|
229
|
+
// exists) returns null — leaving the loop stuck re-deriving indefinitely.
|
|
230
|
+
//
|
|
223
231
|
// NOTE: this predicate mirrors the dispatch rule at
|
|
224
232
|
// auto-dispatch.ts parallel-research-slices — keep the two in sync.
|
|
225
233
|
if (unitType === "research-slice" && unitId.endsWith("/parallel-research")) {
|
|
226
234
|
const { milestone: mid } = parseUnitId(unitId);
|
|
227
235
|
if (!mid)
|
|
228
236
|
return false;
|
|
237
|
+
// #4068: PARALLEL-BLOCKER written by timeout-recovery is a terminal state.
|
|
238
|
+
const blockerPath = resolveExpectedArtifactPath(unitType, unitId, base);
|
|
239
|
+
if (blockerPath && existsSync(blockerPath)) {
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
229
242
|
const roadmapFile = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
230
243
|
if (!roadmapFile || !existsSync(roadmapFile)) {
|
|
231
244
|
logWarning("recovery", `verify-fail ${unitType} ${unitId}: roadmap missing`);
|
|
@@ -497,6 +510,24 @@ export function writeBlockerPlaceholder(unitType, unitId, base, reason) {
|
|
|
497
510
|
logWarning("recovery", `appendEvent failed for slice recovery: ${e instanceof Error ? e.message : String(e)}`);
|
|
498
511
|
}
|
|
499
512
|
}
|
|
513
|
+
// Insert a placeholder complete slice so deriveState sees activeMilestoneSlices.length > 0
|
|
514
|
+
// and exits the pre-planning phase. Without this, activeMilestoneSlices stays empty
|
|
515
|
+
// after the blocker ROADMAP.md is written, causing deriveState to return phase:'pre-planning'
|
|
516
|
+
// indefinitely and re-dispatching plan-milestone in an infinite loop (#4378).
|
|
517
|
+
if (unitType === "plan-milestone" && mid) {
|
|
518
|
+
try {
|
|
519
|
+
insertSlice({ id: "S00-blocker", milestoneId: mid, title: "Blocker placeholder — planning failed", status: "complete", sequence: 0 });
|
|
520
|
+
}
|
|
521
|
+
catch (e) {
|
|
522
|
+
logWarning("recovery", `insertSlice placeholder failed for plan-milestone recovery: ${e instanceof Error ? e.message : String(e)}`);
|
|
523
|
+
}
|
|
524
|
+
try {
|
|
525
|
+
appendEvent(base, { cmd: "plan-milestone", params: { milestoneId: mid }, ts, actor: "system", trigger_reason: "blocker-placeholder-recovery" });
|
|
526
|
+
}
|
|
527
|
+
catch (e) {
|
|
528
|
+
logWarning("recovery", `appendEvent failed for plan-milestone recovery: ${e instanceof Error ? e.message : String(e)}`);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
500
531
|
}
|
|
501
532
|
return diagnoseExpectedArtifact(unitType, unitId, base);
|
|
502
533
|
}
|
|
@@ -30,8 +30,7 @@ import { initRoutingHistory } from "./routing-history.js";
|
|
|
30
30
|
import { restoreHookState, resetHookState } from "./post-unit-hooks.js";
|
|
31
31
|
import { resetProactiveHealing, setLevelChangeCallback } from "./doctor-proactive.js";
|
|
32
32
|
import { snapshotSkills } from "./skill-discovery.js";
|
|
33
|
-
import { isDbAvailable, getMilestone, openDatabase } from "./gsd-db.js";
|
|
34
|
-
import { hideFooter } from "./auto-dashboard.js";
|
|
33
|
+
import { isDbAvailable, getMilestone, openDatabase, getDbStatus } from "./gsd-db.js";
|
|
35
34
|
import { debugLog, enableDebug, isDebugEnabled, getDebugLogPath, } from "./debug-logger.js";
|
|
36
35
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
37
36
|
import { existsSync, mkdirSync, readdirSync, rmSync, statSync, unlinkSync, } from "node:fs";
|
|
@@ -190,8 +189,8 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
190
189
|
//
|
|
191
190
|
// Precedence:
|
|
192
191
|
// 1) Explicit session override via /gsd model (this session)
|
|
193
|
-
// 2)
|
|
194
|
-
// 3)
|
|
192
|
+
// 2) Current session model from settings/session restore (if provider ready)
|
|
193
|
+
// 3) GSD model preferences from PREFERENCES.md (validated against live auth)
|
|
195
194
|
//
|
|
196
195
|
// This preserves #3517 defaults while honoring explicit runtime model
|
|
197
196
|
// selection for subsequent /gsd runs in the same session.
|
|
@@ -224,11 +223,14 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
224
223
|
}
|
|
225
224
|
}
|
|
226
225
|
const sessionModelReady = ctx.model && ctx.modelRegistry.isProviderRequestReady(ctx.model.provider);
|
|
226
|
+
const currentSessionModel = (sessionModelReady && ctx.model)
|
|
227
|
+
? { provider: ctx.model.provider, id: ctx.model.id }
|
|
228
|
+
: null;
|
|
229
|
+
const startThinkingSnapshot = pi.getThinkingLevel();
|
|
227
230
|
const startModelSnapshot = manualSessionOverride
|
|
231
|
+
?? currentSessionModel
|
|
228
232
|
?? validatedPreferredModel
|
|
229
|
-
??
|
|
230
|
-
? { provider: ctx.model.provider, id: ctx.model.id }
|
|
231
|
-
: null);
|
|
233
|
+
?? null;
|
|
232
234
|
try {
|
|
233
235
|
// Validate GSD_PROJECT_ID early so the user gets immediate feedback
|
|
234
236
|
const customProjectId = process.env.GSD_PROJECT_ID;
|
|
@@ -244,7 +246,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
244
246
|
// the parent git root). See #2393 and related issue.
|
|
245
247
|
const hasLocalGit = existsSync(join(base, ".git"));
|
|
246
248
|
if (!hasLocalGit || isInheritedRepo(base)) {
|
|
247
|
-
const mainBranch = loadEffectiveGSDPreferences()?.preferences?.git?.main_branch || "main";
|
|
249
|
+
const mainBranch = loadEffectiveGSDPreferences(base)?.preferences?.git?.main_branch || "main";
|
|
248
250
|
nativeInit(base, mainBranch);
|
|
249
251
|
}
|
|
250
252
|
// Migrate legacy in-project .gsd/ to external state directory.
|
|
@@ -260,7 +262,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
260
262
|
// Ensure .gitignore has baseline patterns.
|
|
261
263
|
// ensureGitignore checks for git-tracked .gsd/ files and skips the
|
|
262
264
|
// ".gsd" pattern if the project intentionally tracks .gsd/ in git.
|
|
263
|
-
const gitPrefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
265
|
+
const gitPrefs = loadEffectiveGSDPreferences(base)?.preferences?.git;
|
|
264
266
|
const manageGitignore = gitPrefs?.manage_gitignore;
|
|
265
267
|
ensureGitignore(base, { manageGitignore });
|
|
266
268
|
if (manageGitignore !== false)
|
|
@@ -286,7 +288,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
286
288
|
prepareWorkflowMcpForProject(ctx, base);
|
|
287
289
|
}
|
|
288
290
|
// Initialize GitServiceImpl
|
|
289
|
-
s.gitService = new GitServiceImpl(s.basePath, loadEffectiveGSDPreferences()?.preferences?.git ?? {});
|
|
291
|
+
s.gitService = new GitServiceImpl(s.basePath, loadEffectiveGSDPreferences(base)?.preferences?.git ?? {});
|
|
290
292
|
// ── Debug mode ──
|
|
291
293
|
if (!isDebugEnabled() && process.env.GSD_DEBUG === "1") {
|
|
292
294
|
enableDebug(base);
|
|
@@ -319,7 +321,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
319
321
|
// was lost due to session ending between completion and teardown.
|
|
320
322
|
// Must run after DB open and before worktree entry.
|
|
321
323
|
try {
|
|
322
|
-
const auditResult = auditOrphanedMilestoneBranches(base, getIsolationMode());
|
|
324
|
+
const auditResult = auditOrphanedMilestoneBranches(base, getIsolationMode(base));
|
|
323
325
|
for (const msg of auditResult.recovered) {
|
|
324
326
|
ctx.ui.notify(`Orphan audit: ${msg}`, "info");
|
|
325
327
|
}
|
|
@@ -337,7 +339,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
337
339
|
let state = await deriveState(base);
|
|
338
340
|
// Stale worktree state recovery (#654)
|
|
339
341
|
if (state.activeMilestone &&
|
|
340
|
-
shouldUseWorktreeIsolation() &&
|
|
342
|
+
shouldUseWorktreeIsolation(base) &&
|
|
341
343
|
!detectWorktreeName(base)) {
|
|
342
344
|
const wtPath = getAutoWorktreePath(base, state.activeMilestone.id);
|
|
343
345
|
if (wtPath) {
|
|
@@ -352,7 +354,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
352
354
|
let hasSurvivorBranch = false;
|
|
353
355
|
if (state.activeMilestone &&
|
|
354
356
|
(state.phase === "pre-planning" || state.phase === "complete") &&
|
|
355
|
-
getIsolationMode() !== "none" &&
|
|
357
|
+
getIsolationMode(base) !== "none" &&
|
|
356
358
|
!detectWorktreeName(base) &&
|
|
357
359
|
!base.includes(`${pathSep}.gsd${pathSep}worktrees${pathSep}`)) {
|
|
358
360
|
const milestoneBranch = `milestone/${state.activeMilestone.id}`;
|
|
@@ -413,29 +415,15 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
413
415
|
}
|
|
414
416
|
const { showSmartEntry } = await import("./guided-flow.js");
|
|
415
417
|
await showSmartEntry(ctx, pi, base, { step: requestedStepMode });
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
postState.phase === "pre-planning") {
|
|
426
|
-
const contextFile = resolveMilestoneFile(base, postState.activeMilestone.id, "CONTEXT");
|
|
427
|
-
const hasContext = !!(contextFile && (await loadFile(contextFile)));
|
|
428
|
-
if (hasContext) {
|
|
429
|
-
state = postState;
|
|
430
|
-
}
|
|
431
|
-
else {
|
|
432
|
-
ctx.ui.notify("Discussion completed but no milestone context was written. Run /gsd to try the discussion again, or /gsd auto after creating the milestone manually.", "warning");
|
|
433
|
-
return releaseLockAndReturn();
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
else {
|
|
437
|
-
return releaseLockAndReturn();
|
|
438
|
-
}
|
|
418
|
+
// showSmartEntry dispatches via pi.sendMessage() which is fire-and-forget:
|
|
419
|
+
// it queues the message and returns immediately, before the LLM turn runs.
|
|
420
|
+
// Checking postState here would always see the pre-dispatch state, causing
|
|
421
|
+
// the premature "Discussion completed but..." warning (#3420).
|
|
422
|
+
//
|
|
423
|
+
// checkAutoStartAfterDiscuss (in guided-flow.ts) already handles re-entering
|
|
424
|
+
// auto-mode by calling startAutoDetached after the discussion completes.
|
|
425
|
+
// Release the lock and let the async dispatch proceed.
|
|
426
|
+
return releaseLockAndReturn();
|
|
439
427
|
}
|
|
440
428
|
// Active milestone exists but has no roadmap
|
|
441
429
|
if (state.phase === "pre-planning") {
|
|
@@ -445,15 +433,16 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
445
433
|
if (!hasContext) {
|
|
446
434
|
const { showSmartEntry } = await import("./guided-flow.js");
|
|
447
435
|
await showSmartEntry(ctx, pi, base, { step: requestedStepMode });
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
436
|
+
// showSmartEntry dispatches via pi.sendMessage() which is fire-and-forget:
|
|
437
|
+
// it queues the message and returns immediately, before the LLM turn runs.
|
|
438
|
+
// Checking postState here fires before the LLM has had a turn, so the
|
|
439
|
+
// pre-planning phase would still appear unchanged and a premature warning
|
|
440
|
+
// would be emitted (#3420).
|
|
441
|
+
//
|
|
442
|
+
// checkAutoStartAfterDiscuss (in guided-flow.ts) already handles re-entering
|
|
443
|
+
// auto-mode by calling startAutoDetached after the discussion completes.
|
|
444
|
+
// Release the lock and let the async dispatch proceed.
|
|
445
|
+
return releaseLockAndReturn();
|
|
457
446
|
}
|
|
458
447
|
}
|
|
459
448
|
// Active milestone has CONTEXT-DRAFT but no full context — needs discussion
|
|
@@ -506,13 +495,14 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
506
495
|
s.pendingQuickTasks = [];
|
|
507
496
|
s.currentUnit = null;
|
|
508
497
|
s.currentMilestoneId = state.activeMilestone?.id ?? null;
|
|
509
|
-
s.originalModelId = ctx.model?.id ?? null;
|
|
510
|
-
s.originalModelProvider = ctx.model?.provider ?? null;
|
|
498
|
+
s.originalModelId = startModelSnapshot?.id ?? ctx.model?.id ?? null;
|
|
499
|
+
s.originalModelProvider = startModelSnapshot?.provider ?? ctx.model?.provider ?? null;
|
|
500
|
+
s.originalThinkingLevel = startThinkingSnapshot ?? null;
|
|
511
501
|
// Register SIGTERM handler
|
|
512
502
|
registerSigtermHandler(base);
|
|
513
503
|
// Capture integration branch
|
|
514
504
|
if (s.currentMilestoneId) {
|
|
515
|
-
if (getIsolationMode() !== "none") {
|
|
505
|
+
if (getIsolationMode(base) !== "none") {
|
|
516
506
|
captureIntegrationBranch(base, s.currentMilestoneId);
|
|
517
507
|
}
|
|
518
508
|
setActiveMilestoneId(base, s.currentMilestoneId);
|
|
@@ -520,7 +510,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
520
510
|
// Guard against stale milestone branch when isolation:none (#3613).
|
|
521
511
|
// A prior session with isolation:branch/worktree may have left HEAD on
|
|
522
512
|
// milestone/<MID>. Auto-checkout back to the integration branch.
|
|
523
|
-
if (getIsolationMode() === "none" && nativeIsRepo(base)) {
|
|
513
|
+
if (getIsolationMode(base) === "none" && nativeIsRepo(base)) {
|
|
524
514
|
try {
|
|
525
515
|
const currentBranch = nativeGetCurrentBranch(base);
|
|
526
516
|
if (currentBranch.startsWith("milestone/")) {
|
|
@@ -548,7 +538,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
548
538
|
return symlinkRe.test(p);
|
|
549
539
|
};
|
|
550
540
|
if (s.currentMilestoneId &&
|
|
551
|
-
getIsolationMode() !== "none" &&
|
|
541
|
+
getIsolationMode(base) !== "none" &&
|
|
552
542
|
!detectWorktreeName(base) &&
|
|
553
543
|
!isUnderGsdWorktrees(base)) {
|
|
554
544
|
buildResolver().enterMilestone(s.currentMilestoneId, {
|
|
@@ -593,8 +583,21 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
593
583
|
// call returns "db_unavailable", triggering artifact-retry which
|
|
594
584
|
// re-dispatches the same task — producing an infinite loop (#2419).
|
|
595
585
|
if (existsSync(gsdDbPath) && !isDbAvailable()) {
|
|
596
|
-
|
|
597
|
-
|
|
586
|
+
const dbStatus = getDbStatus();
|
|
587
|
+
const phaseHint = dbStatus.lastPhase === "open"
|
|
588
|
+
? "The database file could not be opened"
|
|
589
|
+
: dbStatus.lastPhase === "initSchema"
|
|
590
|
+
? "The database schema could not be initialized"
|
|
591
|
+
: dbStatus.lastPhase === "vacuum-recovery"
|
|
592
|
+
? "Corruption recovery (VACUUM) failed"
|
|
593
|
+
: dbStatus.attempted
|
|
594
|
+
? "The database could not be opened (phase unknown)"
|
|
595
|
+
: "The database provider could not be loaded";
|
|
596
|
+
const errorDetail = dbStatus.lastError ? ` (${dbStatus.lastError.message})` : "";
|
|
597
|
+
const providerHint = dbStatus.provider
|
|
598
|
+
? ` Provider: ${dbStatus.provider}.`
|
|
599
|
+
: " No SQLite provider available — check Node >= 22 or install better-sqlite3.";
|
|
600
|
+
ctx.ui.notify(`SQLite database exists but failed to open: ${gsdDbPath}. ${phaseHint}${errorDetail}.${providerHint}`, "error");
|
|
598
601
|
return releaseLockAndReturn();
|
|
599
602
|
}
|
|
600
603
|
// Initialize metrics
|
|
@@ -608,6 +611,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
608
611
|
id: startModelSnapshot.id,
|
|
609
612
|
};
|
|
610
613
|
}
|
|
614
|
+
s.autoModeStartThinkingLevel = startThinkingSnapshot ?? null;
|
|
611
615
|
s.manualSessionModelOverride = manualSessionOverride ?? null;
|
|
612
616
|
// Apply worker model override from parallel orchestrator (#worker-model).
|
|
613
617
|
// GSD_WORKER_MODEL is injected by the coordinator when parallel.worker_model
|
|
@@ -628,13 +632,10 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
628
632
|
}
|
|
629
633
|
}
|
|
630
634
|
// Snapshot installed skills
|
|
631
|
-
if (resolveSkillDiscoveryMode() !== "off") {
|
|
635
|
+
if (resolveSkillDiscoveryMode(base) !== "off") {
|
|
632
636
|
snapshotSkills();
|
|
633
637
|
}
|
|
634
638
|
ctx.ui.setStatus("gsd-auto", s.stepMode ? "next" : "auto");
|
|
635
|
-
ctx.ui.setFooter(hideFooter);
|
|
636
|
-
// Hide gsd-health during AUTO — gsd-progress is the single source of truth
|
|
637
|
-
// for last-commit / cost / health signal while auto is running.
|
|
638
639
|
ctx.ui.setWidget("gsd-health", undefined);
|
|
639
640
|
const modeLabel = s.stepMode ? "Step-mode" : "Auto-mode";
|
|
640
641
|
const pendingCount = (state.registry ?? []).filter((m) => m.status !== "complete" && m.status !== "parked").length;
|
|
@@ -656,7 +657,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
656
657
|
// FlatRateContext used by selectAndApplyModel so user-declared
|
|
657
658
|
// flat-rate providers and externalCli auto-detection are respected.
|
|
658
659
|
const { isFlatRateProvider, buildFlatRateContext } = await import("./auto-model-selection.js");
|
|
659
|
-
const bannerPrefs = loadEffectiveGSDPreferences()?.preferences;
|
|
660
|
+
const bannerPrefs = loadEffectiveGSDPreferences(base)?.preferences;
|
|
660
661
|
const effectiveProvider = s.autoModeStartModel?.provider ?? ctx.model?.provider;
|
|
661
662
|
const effectivelyEnabled = routingConfig.enabled
|
|
662
663
|
&& (routingConfig.allow_flat_rate_providers
|
|
@@ -396,6 +396,39 @@ export async function runPostUnitVerification(vctx, pauseAuto) {
|
|
|
396
396
|
if (postExecBlockingFailure) {
|
|
397
397
|
result.passed = false;
|
|
398
398
|
}
|
|
399
|
+
// Emit Layer 2 verify_result event with the final, post-exec verdict so hooks
|
|
400
|
+
// see the authoritative pass/fail and the complete set of failures.
|
|
401
|
+
try {
|
|
402
|
+
const { emitVerifyResult } = await import("./hook-emitter.js");
|
|
403
|
+
const checkFailures = result.checks
|
|
404
|
+
.filter((c) => c.exitCode !== 0)
|
|
405
|
+
.map((c) => ({
|
|
406
|
+
kind: "gate",
|
|
407
|
+
message: `${c.command} exited ${c.exitCode}${c.stderr ? `: ${c.stderr.slice(0, 200)}` : ""}`,
|
|
408
|
+
}));
|
|
409
|
+
const runtimeFailures = (result.runtimeErrors ?? [])
|
|
410
|
+
.filter((e) => e.blocking)
|
|
411
|
+
.map((e) => ({
|
|
412
|
+
kind: "other",
|
|
413
|
+
message: `[${e.source}] ${e.message.slice(0, 200)}`,
|
|
414
|
+
}));
|
|
415
|
+
const postExecFailures = (postExecChecks ?? [])
|
|
416
|
+
.filter((c) => !c.passed)
|
|
417
|
+
.map((c) => ({
|
|
418
|
+
kind: "other",
|
|
419
|
+
message: `[${c.category}] ${c.target}: ${c.message}`,
|
|
420
|
+
}));
|
|
421
|
+
await emitVerifyResult({
|
|
422
|
+
passed: result.passed,
|
|
423
|
+
failures: [...checkFailures, ...runtimeFailures, ...postExecFailures],
|
|
424
|
+
unitType: s.currentUnit.type,
|
|
425
|
+
unitId: s.currentUnit.id,
|
|
426
|
+
cwd: s.basePath,
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
catch (hookErr) {
|
|
430
|
+
logWarning("engine", `verify_result hook emission failed: ${hookErr.message}`);
|
|
431
|
+
}
|
|
399
432
|
// ── Auto-fix retry logic ──
|
|
400
433
|
if (result.passed) {
|
|
401
434
|
s.verificationRetryCount.delete(s.currentUnit.id);
|
|
@@ -180,14 +180,6 @@ function clearProjectRootStateFiles(basePath, milestoneId) {
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
|
-
function isProjectGsdSymlink(basePath) {
|
|
184
|
-
try {
|
|
185
|
-
return lstatSyncFn(join(basePath, ".gsd")).isSymbolicLink();
|
|
186
|
-
}
|
|
187
|
-
catch {
|
|
188
|
-
return false;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
183
|
// ─── Build Artifact Auto-Resolve ─────────────────────────────────────────────
|
|
192
184
|
/** Patterns for machine-generated build artifacts that can be safely
|
|
193
185
|
* auto-resolved by accepting --theirs during merge. These files are
|
|
@@ -1429,50 +1421,15 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1429
1421
|
});
|
|
1430
1422
|
}
|
|
1431
1423
|
}
|
|
1432
|
-
// 7.
|
|
1433
|
-
// blocked by unrelated local changes (#2151). clearProjectRootStateFiles
|
|
1434
|
-
// only removes untracked .gsd/ files; tracked dirty files elsewhere (e.g.
|
|
1435
|
-
// .planning/work-state.json with stash conflict markers) are invisible to
|
|
1436
|
-
// that cleanup but will cause `git merge --squash` to reject.
|
|
1437
|
-
let stashed = false;
|
|
1438
|
-
try {
|
|
1439
|
-
const status = execFileSync("git", ["status", "--porcelain"], {
|
|
1440
|
-
cwd: originalBasePath_,
|
|
1441
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1442
|
-
encoding: "utf-8",
|
|
1443
|
-
}).trim();
|
|
1444
|
-
if (status) {
|
|
1445
|
-
// Use --include-untracked to stash untracked files that would block
|
|
1446
|
-
// the squash merge, but EXCLUDE .gsd/milestones/ (#2505).
|
|
1447
|
-
// --include-untracked without exclusion sweeps queued milestone
|
|
1448
|
-
// CONTEXT files into the stash. If stash pop later fails, those files
|
|
1449
|
-
// are permanently trapped in the stash entry and lost on the next
|
|
1450
|
-
// stash push or drop.
|
|
1451
|
-
//
|
|
1452
|
-
// When `.gsd` itself is a symlink, Git rejects pathspecs below it
|
|
1453
|
-
// ("beyond a symbolic link"). In that layout, exclude the whole symlink
|
|
1454
|
-
// and keep stashing real project files that could block the merge.
|
|
1455
|
-
const stashPathspecs = isProjectGsdSymlink(originalBasePath_)
|
|
1456
|
-
? [".", ":(exclude).gsd"]
|
|
1457
|
-
: [":(exclude).gsd/milestones"];
|
|
1458
|
-
execFileSync("git", [
|
|
1459
|
-
"stash", "push", "--include-untracked",
|
|
1460
|
-
"-m", `gsd: pre-merge stash for ${milestoneId}`,
|
|
1461
|
-
"--", ...stashPathspecs,
|
|
1462
|
-
], { cwd: originalBasePath_, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" });
|
|
1463
|
-
stashed = true;
|
|
1464
|
-
}
|
|
1465
|
-
}
|
|
1466
|
-
catch (err) {
|
|
1467
|
-
// Stash failure is non-fatal — proceed without stash and let the merge
|
|
1468
|
-
// report the dirty tree if it fails.
|
|
1469
|
-
logWarning("worktree", `git stash failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1470
|
-
}
|
|
1471
|
-
// 7a. Shelter queued milestone directories before the squash merge (#2505).
|
|
1424
|
+
// 7. Shelter queued milestone directories before the squash merge (#2505).
|
|
1472
1425
|
// The milestone branch may contain copies of queued milestone dirs (via
|
|
1473
1426
|
// copyPlanningArtifacts), so `git merge --squash` rejects when those same
|
|
1474
1427
|
// files exist as untracked in the working tree. Temporarily move them to
|
|
1475
1428
|
// a backup location, then restore after the merge+commit.
|
|
1429
|
+
//
|
|
1430
|
+
// MUST run BEFORE the pre-merge stash (step 7a) so `--include-untracked`
|
|
1431
|
+
// does not sweep queued CONTEXT files into the stash. If stash pop later
|
|
1432
|
+
// fails, files trapped inside the stash are permanently lost (#2505).
|
|
1476
1433
|
const milestonesDir = join(gsdRoot(originalBasePath_), "milestones");
|
|
1477
1434
|
const shelterDir = join(gsdRoot(originalBasePath_), ".milestone-shelter");
|
|
1478
1435
|
const shelteredDirs = [];
|
|
@@ -1526,6 +1483,31 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1526
1483
|
// Non-fatal — proceed with merge; untracked files may block it
|
|
1527
1484
|
logWarning("worktree", `milestone shelter operation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1528
1485
|
}
|
|
1486
|
+
// 7a. Stash pre-existing dirty files so the squash merge is not blocked by
|
|
1487
|
+
// unrelated local changes (#2151). Includes untracked files to handle
|
|
1488
|
+
// locally-added files that conflict with tracked files on the milestone
|
|
1489
|
+
// branch. Passing NO pathspec lets git skip gitignored paths silently;
|
|
1490
|
+
// adding an explicit pathspec trips a `git add`-style fatal on ignored
|
|
1491
|
+
// entries (e.g. a gitignored `.gsd` symlink under ADR-002) (#4573).
|
|
1492
|
+
// Queued CONTEXT files under `.gsd/milestones/*` are already sheltered
|
|
1493
|
+
// in step 7 above, so they won't be swept into the stash.
|
|
1494
|
+
let stashed = false;
|
|
1495
|
+
try {
|
|
1496
|
+
const status = execFileSync("git", ["status", "--porcelain"], {
|
|
1497
|
+
cwd: originalBasePath_,
|
|
1498
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1499
|
+
encoding: "utf-8",
|
|
1500
|
+
}).trim();
|
|
1501
|
+
if (status) {
|
|
1502
|
+
execFileSync("git", ["stash", "push", "--include-untracked", "-m", `gsd: pre-merge stash for ${milestoneId}`], { cwd: originalBasePath_, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" });
|
|
1503
|
+
stashed = true;
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
catch (err) {
|
|
1507
|
+
// Stash failure is non-fatal — proceed without stash and let the merge
|
|
1508
|
+
// report the dirty tree if it fails.
|
|
1509
|
+
logWarning("worktree", `git stash failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1510
|
+
}
|
|
1529
1511
|
// 7b. Clean up stale merge state before attempting squash merge (#2912).
|
|
1530
1512
|
// A leftover MERGE_HEAD (from a previous failed merge, libgit2 native path,
|
|
1531
1513
|
// or interrupted operation) causes `git merge --squash` to refuse with
|
|
@@ -1761,16 +1743,32 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1761
1743
|
// When a milestone only produced .gsd/ metadata (summaries, roadmaps) but no
|
|
1762
1744
|
// real code, the user sees "milestone complete" but nothing changed in their
|
|
1763
1745
|
// codebase. Surface this so the caller can warn the user.
|
|
1746
|
+
//
|
|
1747
|
+
// Bug #4385 fix: use `git diff-tree --root` instead of `git diff HEAD~1 HEAD`.
|
|
1748
|
+
// `HEAD~1` does not exist on initial commits and is unreliable on shallow clones
|
|
1749
|
+
// and merge commits. `diff-tree --root` handles all three cases correctly.
|
|
1750
|
+
// The empty-tree hash (4b825dc…) is the universal fallback for refs that don't exist.
|
|
1751
|
+
const GIT_EMPTY_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
1764
1752
|
let codeFilesChanged = false;
|
|
1765
1753
|
if (!nothingToCommit) {
|
|
1766
1754
|
try {
|
|
1767
|
-
const
|
|
1768
|
-
|
|
1755
|
+
const diffTreeOutput = execFileSync("git", ["diff-tree", "--root", "--no-commit-id", "-r", "--name-only", "HEAD"], { cwd: originalBasePath_, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
|
|
1756
|
+
const mergedFiles = diffTreeOutput ? diffTreeOutput.split("\n").filter(Boolean) : [];
|
|
1757
|
+
codeFilesChanged = mergedFiles.some((f) => !f.startsWith(".gsd/"));
|
|
1769
1758
|
}
|
|
1770
1759
|
catch (e) {
|
|
1771
|
-
//
|
|
1772
|
-
|
|
1773
|
-
|
|
1760
|
+
// diff-tree failed (e.g. unborn HEAD in a brand-new repo) — fall back to
|
|
1761
|
+
// comparing against the empty tree so initial-commit repos still report changes.
|
|
1762
|
+
try {
|
|
1763
|
+
const fallbackOutput = execFileSync("git", ["diff", "--name-only", GIT_EMPTY_TREE, "HEAD"], { cwd: originalBasePath_, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
|
|
1764
|
+
const fallbackFiles = fallbackOutput ? fallbackOutput.split("\n").filter(Boolean) : [];
|
|
1765
|
+
codeFilesChanged = fallbackFiles.some((f) => !f.startsWith(".gsd/"));
|
|
1766
|
+
}
|
|
1767
|
+
catch {
|
|
1768
|
+
// Truly unable to determine — assume code was changed to avoid silent data loss
|
|
1769
|
+
logWarning("worktree", `diff-tree and empty-tree fallback both failed (assuming code changed): ${e.message}`);
|
|
1770
|
+
codeFilesChanged = true;
|
|
1771
|
+
}
|
|
1774
1772
|
}
|
|
1775
1773
|
}
|
|
1776
1774
|
// 10. Auto-push if enabled
|