gsd-pi 2.80.0-dev.42bd34838 → 2.80.0-dev.488219eb6
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/dist/claude-cli-check.d.ts +30 -0
- package/dist/claude-cli-check.js +18 -7
- package/dist/cli.js +0 -19
- package/dist/headless-query.d.ts +10 -0
- package/dist/headless-query.js +6 -4
- package/dist/loader-entrypoint.d.ts +8 -0
- package/dist/loader-entrypoint.js +27 -0
- package/dist/loader.js +2 -11
- package/dist/mcp-server.d.ts +1 -0
- package/dist/mcp-server.js +6 -3
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/claude-code-cli/readiness.js +18 -7
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +29 -0
- package/dist/resources/extensions/github-sync/sync.js +4 -1
- package/dist/resources/extensions/gsd/auto/loop.js +71 -8
- package/dist/resources/extensions/gsd/auto/phases.js +179 -99
- package/dist/resources/extensions/gsd/auto/resolve.js +12 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +10 -30
- package/dist/resources/extensions/gsd/auto/session.js +8 -0
- package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
- package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
- package/dist/resources/extensions/gsd/auto-dispatch.js +16 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +94 -76
- package/dist/resources/extensions/gsd/auto-prompts.js +90 -15
- package/dist/resources/extensions/gsd/auto-start.js +238 -12
- package/dist/resources/extensions/gsd/auto-worktree.js +209 -81
- package/dist/resources/extensions/gsd/auto.js +95 -44
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +96 -26
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +44 -37
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -10
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +6 -3
- package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +4 -1
- package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +6 -4
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +5 -3
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +298 -54
- package/dist/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.js +4 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
- package/dist/resources/extensions/gsd/clean-root-preflight.js +24 -6
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
- package/dist/resources/extensions/gsd/commands-config.js +1 -1
- package/dist/resources/extensions/gsd/commands-eval-review.js +2 -2
- package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
- package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +53 -0
- package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
- package/dist/resources/extensions/gsd/git-service.js +37 -1
- package/dist/resources/extensions/gsd/guided-flow.js +61 -32
- package/dist/resources/extensions/gsd/init-wizard.js +4 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
- package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
- package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +8 -4
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/dist/resources/extensions/gsd/slice-cadence.js +45 -2
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +15 -9
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -7
- package/dist/resources/extensions/gsd/tools/complete-task.js +1 -1
- package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +57 -5
- package/dist/resources/skills/web-quality-audit/scripts/analyze.sh +0 -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 +11 -11
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +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/page_client-reference-manifest.js +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 +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
- 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/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +3 -3
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +10 -0
- package/dist/web/standalone/.next/static/chunks/app/{page-fab3ebb85b006001.js → page-752f1e2ebdaa3e45.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-0481f1221120a7c6.js → webpack-de742b64187e13fe.js} +1 -1
- package/dist/web/standalone/server.js +1 -1
- package/dist/welcome-screen.d.ts +2 -0
- package/dist/welcome-screen.js +9 -7
- package/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +4 -1
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +5 -0
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/index.d.ts +1 -0
- package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/index.js +2 -0
- package/packages/pi-agent-core/dist/index.js.map +1 -1
- package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
- package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
- package/packages/pi-agent-core/dist/token-audit.js +221 -0
- package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
- package/packages/pi-agent-core/dist/types.d.ts +9 -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/src/agent-loop.test.ts +128 -0
- package/packages/pi-agent-core/src/agent-loop.ts +4 -1
- package/packages/pi-agent-core/src/agent.ts +8 -0
- package/packages/pi-agent-core/src/index.ts +2 -0
- package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
- package/packages/pi-agent-core/src/token-audit.ts +287 -0
- package/packages/pi-agent-core/src/types.ts +14 -0
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +35 -13
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +21 -11
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts +7 -0
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +9 -7
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +23 -14
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +48 -21
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +22 -21
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +22 -21
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -1
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +39 -25
- package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -22
- package/packages/pi-ai/src/providers/anthropic.ts +22 -9
- package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +34 -21
- package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +56 -22
- package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +24 -28
- package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +24 -28
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +18 -0
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -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 +36 -7
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +3 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.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 +8 -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 +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +3 -6
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +3 -3
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +34 -3
- 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.test.js +2 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +22 -56
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +3 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js +12 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/find.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/find.js +14 -6
- package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/grep.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/grep.js +12 -3
- package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +3 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -1
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.js +1 -0
- package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/ls.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/ls.js +10 -3
- package/packages/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js +3 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +7 -62
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js +115 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts +19 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.js +20 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js +9 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +89 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +25 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +5 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +153 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +18 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +23 -5
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
- 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 +19 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +23 -5
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +40 -7
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +3 -1
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +3 -3
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +5 -5
- package/packages/pi-coding-agent/src/core/extensions/types.ts +37 -2
- package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
- package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
- package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
- package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
- package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +22 -66
- package/packages/pi-coding-agent/src/core/tools/bash.ts +4 -1
- package/packages/pi-coding-agent/src/core/tools/edit.ts +13 -1
- package/packages/pi-coding-agent/src/core/tools/find.ts +15 -6
- package/packages/pi-coding-agent/src/core/tools/grep.ts +13 -3
- package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +4 -1
- package/packages/pi-coding-agent/src/core/tools/index.ts +8 -0
- package/packages/pi-coding-agent/src/core/tools/ls.ts +11 -3
- package/packages/pi-coding-agent/src/core/tools/read.ts +4 -1
- package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +11 -72
- package/packages/pi-coding-agent/src/core/tools/tool-target-metadata.test.ts +127 -0
- package/packages/pi-coding-agent/src/core/tools/tool-target.ts +48 -0
- package/packages/pi-coding-agent/src/core/tools/write.ts +14 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +119 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +31 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +177 -8
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +24 -5
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +17 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +21 -0
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +25 -8
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/src/resources/extensions/claude-code-cli/readiness.ts +25 -7
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +30 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +26 -0
- package/src/resources/extensions/github-sync/sync.ts +8 -1
- package/src/resources/extensions/github-sync/tests/sync-source.test.ts +6 -18
- package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -2
- package/src/resources/extensions/gsd/auto/loop.ts +84 -8
- package/src/resources/extensions/gsd/auto/phases.ts +258 -159
- package/src/resources/extensions/gsd/auto/resolve.ts +19 -0
- package/src/resources/extensions/gsd/auto/run-unit.ts +10 -29
- package/src/resources/extensions/gsd/auto/session.ts +8 -0
- package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
- package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
- package/src/resources/extensions/gsd/auto-dispatch.ts +16 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +107 -78
- package/src/resources/extensions/gsd/auto-prompts.ts +95 -14
- package/src/resources/extensions/gsd/auto-start.ts +286 -15
- package/src/resources/extensions/gsd/auto-worktree.ts +241 -72
- package/src/resources/extensions/gsd/auto.ts +132 -40
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +116 -24
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +45 -37
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +36 -10
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +8 -3
- package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +5 -1
- package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +7 -4
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +6 -3
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +347 -54
- package/src/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.ts +4 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
- package/src/resources/extensions/gsd/clean-root-preflight.ts +32 -7
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +4 -2
- package/src/resources/extensions/gsd/commands-config.ts +1 -1
- package/src/resources/extensions/gsd/commands-eval-review.ts +2 -2
- package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
- package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +66 -0
- package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
- package/src/resources/extensions/gsd/git-service.ts +41 -2
- package/src/resources/extensions/gsd/guided-flow.ts +71 -39
- package/src/resources/extensions/gsd/init-wizard.ts +5 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
- package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
- package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +8 -4
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/src/resources/extensions/gsd/slice-cadence.ts +49 -2
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +23 -9
- package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +59 -89
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +47 -172
- package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +0 -35
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +35 -9
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +361 -10
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +80 -59
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +3 -47
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +76 -18
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +54 -95
- package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +67 -26
- package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +32 -30
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +32 -128
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +20 -54
- package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +20 -30
- package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +17 -29
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +138 -0
- package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +21 -39
- package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +15 -24
- package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +44 -29
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +39 -51
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +159 -213
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +15 -32
- package/src/resources/extensions/gsd/tests/browser-teardown.test.ts +0 -41
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +15 -6
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +34 -27
- package/src/resources/extensions/gsd/tests/cmux.test.ts +51 -53
- package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +39 -61
- package/src/resources/extensions/gsd/tests/commands-config.test.ts +26 -19
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +29 -33
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +45 -108
- package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +35 -31
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +5 -1
- package/src/resources/extensions/gsd/tests/cwd-fallback-hardening.test.ts +138 -0
- package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +4 -68
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +4 -9
- package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +14 -65
- package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +44 -37
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +58 -40
- package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +25 -15
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +35 -17
- package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +16 -21
- package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +15 -82
- package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
- package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -20
- package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +18 -26
- package/src/resources/extensions/gsd/tests/init-skip-git.test.ts +9 -12
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/integration/commands-eval-review.integration.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/integration/git-locale.test.ts +31 -20
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +0 -47
- package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +60 -202
- package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +13 -56
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +5 -1
- package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/lazy-pi-tui-import.test.ts +44 -6
- package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +21 -35
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +79 -98
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +70 -278
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
- package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +37 -30
- package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +32 -28
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +24 -37
- package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +9 -24
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +91 -75
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +36 -22
- package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +36 -30
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +74 -4
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +20 -22
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +130 -32
- package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +18 -36
- package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +35 -73
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +76 -138
- package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +70 -125
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +59 -161
- package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +33 -29
- package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +22 -196
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +23 -93
- package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +50 -79
- package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +27 -13
- package/src/resources/extensions/gsd/tests/remote-questions.test.ts +151 -251
- package/src/resources/extensions/gsd/tests/resource-loader-import-path.test.ts +41 -29
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +58 -69
- package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +32 -164
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +57 -41
- package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/session-model-override.test.ts +14 -9
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +166 -0
- package/src/resources/extensions/gsd/tests/show-config-command.test.ts +44 -42
- package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +56 -24
- package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +51 -11
- package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +66 -50
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +68 -107
- package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +115 -42
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +21 -97
- package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +25 -116
- package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +21 -57
- package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +29 -76
- package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +33 -24
- package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +39 -30
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/status-db-open.test.ts +33 -47
- package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +48 -46
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +14 -102
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +78 -232
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +32 -35
- package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +84 -309
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
- package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +134 -341
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +8 -25
- package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +50 -1
- package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -99
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +43 -36
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -444
- package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +44 -189
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -57
- package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +21 -44
- package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +27 -26
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +14 -13
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -18
- package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
- package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +140 -3
- package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -13
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +14 -15
- package/src/resources/extensions/gsd/tools/complete-task.ts +1 -1
- package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
- package/src/resources/extensions/gsd/worktree-resolver.ts +83 -5
- package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +86 -40
- package/src/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
- package/dist/web/standalone/.next/static/chunks/8336.631939fb583761fa.js +0 -10
- /package/dist/web/standalone/.next/static/{tht0ltP8EIjsohPOA_WZf → G68KoLv5claox_Dyd4pZn}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{tht0ltP8EIjsohPOA_WZf → G68KoLv5claox_Dyd4pZn}/_ssgManifest.js +0 -0
|
@@ -1,38 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
* worktree-expected-warnings.test.ts — #3665
|
|
3
|
-
*
|
|
4
|
-
* Verify that auto-worktree.ts and worktree-manager.ts suppress expected
|
|
5
|
-
* ENOENT and EISDIR conditions instead of logging misleading warnings.
|
|
6
|
-
*/
|
|
1
|
+
// GSD-2 — Expected worktree condition warning suppression tests.
|
|
7
2
|
|
|
8
3
|
import { describe, test } from "node:test";
|
|
9
4
|
import assert from "node:assert/strict";
|
|
10
|
-
import {
|
|
11
|
-
import { join,
|
|
12
|
-
import {
|
|
5
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { join, resolve } from "node:path";
|
|
7
|
+
import { tmpdir } from "node:os";
|
|
13
8
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const worktreeManagerFile = join(__dirname, "..", "worktree-manager.ts");
|
|
9
|
+
import { _isExpectedWorktreeUnlinkErrorForTest } from "../auto-worktree.ts";
|
|
10
|
+
import { resolveGitDir } from "../worktree-manager.ts";
|
|
17
11
|
|
|
18
12
|
describe("worktree expected-condition warning suppression (#3665)", () => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
assert.
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
test("auto-worktree.ts checks for EISDIR before logging unlink warning", () => {
|
|
26
|
-
assert.match(autoSource, /code\s*!==\s*["']EISDIR["']/);
|
|
13
|
+
test("known unlink races are classified as expected", () => {
|
|
14
|
+
assert.equal(_isExpectedWorktreeUnlinkErrorForTest("ENOENT"), true);
|
|
15
|
+
assert.equal(_isExpectedWorktreeUnlinkErrorForTest("EISDIR"), true);
|
|
16
|
+
assert.equal(_isExpectedWorktreeUnlinkErrorForTest("EACCES"), false);
|
|
27
17
|
});
|
|
28
18
|
|
|
29
|
-
test("
|
|
30
|
-
|
|
19
|
+
test("resolveGitDir returns .git directory without reading it as a file", () => {
|
|
20
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-resolve-gitdir-"));
|
|
21
|
+
try {
|
|
22
|
+
mkdirSync(join(base, ".git"), { recursive: true });
|
|
23
|
+
assert.equal(resolveGitDir(base), join(base, ".git"));
|
|
24
|
+
} finally {
|
|
25
|
+
rmSync(base, { recursive: true, force: true });
|
|
26
|
+
}
|
|
31
27
|
});
|
|
32
28
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
test("resolveGitDir resolves worktree .git file targets", () => {
|
|
30
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-resolve-worktree-gitdir-"));
|
|
31
|
+
try {
|
|
32
|
+
mkdirSync(join(base, ".gitdir"), { recursive: true });
|
|
33
|
+
writeFileSync(join(base, ".git"), "gitdir: .gitdir\n");
|
|
34
|
+
assert.equal(resolveGitDir(base), resolve(base, ".gitdir"));
|
|
35
|
+
} finally {
|
|
36
|
+
rmSync(base, { recursive: true, force: true });
|
|
37
|
+
}
|
|
37
38
|
});
|
|
38
39
|
});
|
|
@@ -9,12 +9,13 @@
|
|
|
9
9
|
|
|
10
10
|
import { describe, test, beforeEach, afterEach } from "node:test";
|
|
11
11
|
import assert from "node:assert/strict";
|
|
12
|
-
import { existsSync, mkdtempSync, mkdirSync,
|
|
12
|
+
import { existsSync, mkdtempSync, mkdirSync, writeFileSync, rmSync, readdirSync } from "node:fs";
|
|
13
13
|
import { join } from "node:path";
|
|
14
14
|
import { tmpdir } from "node:os";
|
|
15
15
|
import { execSync } from "node:child_process";
|
|
16
16
|
|
|
17
17
|
import { PROJECT_FILES, classifyProject } from "../detection.js";
|
|
18
|
+
import { _shouldProceedWithInvalidRepoClassificationForTest } from "../auto/phases.ts";
|
|
18
19
|
|
|
19
20
|
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
20
21
|
|
|
@@ -86,19 +87,19 @@ test("PROJECT_FILES is exported and contains expected multi-ecosystem entries",
|
|
|
86
87
|
assert.ok(PROJECT_FILES.includes("Package.swift"), "includes Swift marker");
|
|
87
88
|
});
|
|
88
89
|
|
|
89
|
-
test("
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
test("invalid-repo classification only proceeds when the git marker was already confirmed", () => {
|
|
91
|
+
assert.equal(
|
|
92
|
+
_shouldProceedWithInvalidRepoClassificationForTest("missing .git", true),
|
|
93
|
+
true,
|
|
94
|
+
);
|
|
95
|
+
assert.equal(
|
|
96
|
+
_shouldProceedWithInvalidRepoClassificationForTest("missing .git", false),
|
|
97
|
+
false,
|
|
98
|
+
);
|
|
99
|
+
assert.equal(
|
|
100
|
+
_shouldProceedWithInvalidRepoClassificationForTest("permission denied", true),
|
|
101
|
+
false,
|
|
94
102
|
);
|
|
95
|
-
|
|
96
|
-
assert.match(invalidRepoBranch, /projectClassification\.reason === "missing \.git" && hasGit/);
|
|
97
|
-
assert.match(invalidRepoBranch, /project classification could not confirm \.git/);
|
|
98
|
-
assert.match(invalidRepoBranch, /ctx\.ui\.notify\(msg,\s*"error"\)/);
|
|
99
|
-
assert.match(invalidRepoBranch, /await deps\.stopAuto\(ctx,\s*pi,\s*msg\)/);
|
|
100
|
-
assert.match(invalidRepoBranch, /return \{ action: "break", reason: "worktree-invalid" \}/);
|
|
101
|
-
assert.match(invalidRepoBranch, /classified as invalid-repo/);
|
|
102
103
|
});
|
|
103
104
|
|
|
104
105
|
describe("health check with git repo", () => {
|
|
@@ -39,6 +39,7 @@ function makeDeps(
|
|
|
39
39
|
getAutoWorktreePath: () => null,
|
|
40
40
|
autoCommitCurrentBranch: () => {},
|
|
41
41
|
getCurrentBranch: () => "main",
|
|
42
|
+
checkoutBranch: () => {},
|
|
42
43
|
autoWorktreeBranch: (milestoneId: string) => `milestone/${milestoneId}`,
|
|
43
44
|
resolveMilestoneFile: (_basePath: string, milestoneId: string) =>
|
|
44
45
|
`/project/.gsd/milestones/${milestoneId}/${milestoneId}-ROADMAP.md`,
|
|
@@ -1,25 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* preference when META.json integration branch is absent.
|
|
4
|
-
*/
|
|
1
|
+
// GSD-2 — Auto-worktree main branch preference regression tests.
|
|
2
|
+
|
|
5
3
|
import { test } from "node:test";
|
|
6
4
|
import assert from "node:assert/strict";
|
|
7
|
-
import { readFileSync } from "node:fs";
|
|
8
|
-
import { join } from "node:path";
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
import { _resolveAutoWorktreeStartPointForTest } from "../auto-worktree.ts";
|
|
7
|
+
|
|
8
|
+
test("auto-worktree start point prefers milestone integration branch", () => {
|
|
9
|
+
const startPoint = _resolveAutoWorktreeStartPointForTest(
|
|
10
|
+
"release/integration",
|
|
11
|
+
"dev",
|
|
12
|
+
() => true,
|
|
14
13
|
);
|
|
15
|
-
|
|
16
|
-
assert.
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
|
|
15
|
+
assert.equal(startPoint, "release/integration");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test("auto-worktree start point uses git.main_branch only when it exists", () => {
|
|
19
|
+
assert.equal(
|
|
20
|
+
_resolveAutoWorktreeStartPointForTest(null, "dev", (branch) => branch === "dev"),
|
|
21
|
+
"dev",
|
|
19
22
|
);
|
|
20
|
-
assert.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"createAutoWorktree must validate git.main_branch exists before using it",
|
|
23
|
+
assert.equal(
|
|
24
|
+
_resolveAutoWorktreeStartPointForTest(null, "stale", () => false),
|
|
25
|
+
undefined,
|
|
24
26
|
);
|
|
25
27
|
});
|
|
@@ -79,7 +79,7 @@ async function waitFor(condition: () => boolean, label: string): Promise<void> {
|
|
|
79
79
|
assert.fail(`Timed out waiting for ${label} after ${timeoutMs}ms`);
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
test("runUnit
|
|
82
|
+
test("runUnit passes basePath as workspaceRoot without changing process cwd", async (t) => {
|
|
83
83
|
_resetPendingResolve();
|
|
84
84
|
|
|
85
85
|
const originalCwd = process.cwd();
|
|
@@ -93,13 +93,15 @@ test("runUnit changes cwd to basePath before creating a new session", async (t)
|
|
|
93
93
|
|
|
94
94
|
process.chdir(drifted);
|
|
95
95
|
|
|
96
|
+
let newSessionWorkspaceRoot: string | undefined;
|
|
96
97
|
let cwdAtNewSession: string | undefined;
|
|
97
98
|
const session = {
|
|
98
99
|
active: true,
|
|
99
100
|
basePath: base,
|
|
100
101
|
verbose: false,
|
|
101
102
|
cmdCtx: {
|
|
102
|
-
newSession: () => {
|
|
103
|
+
newSession: (options?: { workspaceRoot?: string }) => {
|
|
104
|
+
newSessionWorkspaceRoot = options?.workspaceRoot;
|
|
103
105
|
cwdAtNewSession = process.cwd();
|
|
104
106
|
return Promise.resolve({ cancelled: false });
|
|
105
107
|
},
|
|
@@ -119,10 +121,12 @@ test("runUnit changes cwd to basePath before creating a new session", async (t)
|
|
|
119
121
|
|
|
120
122
|
const result = await resultPromise;
|
|
121
123
|
assert.equal(result.status, "completed");
|
|
122
|
-
assert.equal(
|
|
124
|
+
assert.equal(newSessionWorkspaceRoot, base);
|
|
125
|
+
assert.equal(cwdAtNewSession, drifted);
|
|
126
|
+
assert.equal(process.cwd(), drifted);
|
|
123
127
|
});
|
|
124
128
|
|
|
125
|
-
test("runUnit
|
|
129
|
+
test("runUnit does not chdir or cancel when basePath is not a live directory", async (t) => {
|
|
126
130
|
_resetPendingResolve();
|
|
127
131
|
|
|
128
132
|
const originalCwd = process.cwd();
|
|
@@ -136,14 +140,14 @@ test("runUnit cancels before creating a session when basePath chdir fails", asyn
|
|
|
136
140
|
|
|
137
141
|
process.chdir(drifted);
|
|
138
142
|
|
|
139
|
-
let
|
|
143
|
+
let newSessionWorkspaceRoot: string | undefined;
|
|
140
144
|
const session = {
|
|
141
145
|
active: true,
|
|
142
146
|
basePath: base,
|
|
143
147
|
verbose: false,
|
|
144
148
|
cmdCtx: {
|
|
145
|
-
newSession: () => {
|
|
146
|
-
|
|
149
|
+
newSession: (options?: { workspaceRoot?: string }) => {
|
|
150
|
+
newSessionWorkspaceRoot = options?.workspaceRoot;
|
|
147
151
|
return Promise.resolve({ cancelled: false });
|
|
148
152
|
},
|
|
149
153
|
},
|
|
@@ -156,15 +160,14 @@ test("runUnit cancels before creating a session when basePath chdir fails", asyn
|
|
|
156
160
|
} as any;
|
|
157
161
|
const ctx = { ui: { notify: () => {} }, model: { id: "test-model" } } as any;
|
|
158
162
|
|
|
159
|
-
const
|
|
163
|
+
const resultPromise = runUnit(ctx, pi, session, "task", "T01", "prompt");
|
|
164
|
+
await waitFor(() => pi.calls.length === 1, "runUnit dispatch");
|
|
165
|
+
resolveAgentEnd({ messages: [{ role: "assistant" }] });
|
|
160
166
|
|
|
161
|
-
|
|
162
|
-
assert.equal(result.
|
|
163
|
-
assert.equal(
|
|
164
|
-
assert.
|
|
165
|
-
assert.ok(result.errorContext?.message.includes(base), "error should include the failed basePath");
|
|
166
|
-
assert.equal(newSessionCalled, false, "newSession must not run after chdir failure");
|
|
167
|
-
assert.equal(pi.calls.length, 0, "unit must not dispatch after chdir failure");
|
|
167
|
+
const result = await resultPromise;
|
|
168
|
+
assert.equal(result.status, "completed");
|
|
169
|
+
assert.equal(newSessionWorkspaceRoot, base);
|
|
170
|
+
assert.equal(process.cwd(), drifted);
|
|
168
171
|
});
|
|
169
172
|
|
|
170
173
|
test("direct dispatch redirects to the canonical milestone worktree before newSession", async (t) => {
|
|
@@ -185,12 +188,12 @@ test("direct dispatch redirects to the canonical milestone worktree before newSe
|
|
|
185
188
|
|
|
186
189
|
process.chdir(drifted);
|
|
187
190
|
|
|
188
|
-
let
|
|
191
|
+
let newSessionWorkspaceRoot: string | undefined;
|
|
189
192
|
let sentPrompt: string | undefined;
|
|
190
193
|
const ctx = {
|
|
191
194
|
ui: { notify: () => {} },
|
|
192
|
-
newSession: async () => {
|
|
193
|
-
|
|
195
|
+
newSession: async (options?: { workspaceRoot?: string }) => {
|
|
196
|
+
newSessionWorkspaceRoot = options?.workspaceRoot;
|
|
194
197
|
return { cancelled: false };
|
|
195
198
|
},
|
|
196
199
|
} as any;
|
|
@@ -202,7 +205,7 @@ test("direct dispatch redirects to the canonical milestone worktree before newSe
|
|
|
202
205
|
|
|
203
206
|
await dispatchDirectPhase(ctx, pi, "research-milestone", base);
|
|
204
207
|
|
|
205
|
-
assert.equal(
|
|
208
|
+
assert.equal(newSessionWorkspaceRoot, worktreeRoot);
|
|
206
209
|
assert.equal(process.cwd(), drifted);
|
|
207
210
|
assert.ok(sentPrompt?.includes(worktreeRoot), "prompt should name the canonical worktree root");
|
|
208
211
|
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// GSD-2 + Worktree dispatch guard: degrade empty worktrees over real project roots.
|
|
2
|
+
|
|
3
|
+
import { describe, test } from "node:test";
|
|
4
|
+
import assert from "node:assert/strict";
|
|
5
|
+
|
|
6
|
+
import { shouldDegradeEmptyWorktreeToProjectRoot } from "../auto/phases.ts";
|
|
7
|
+
import type { ProjectClassification } from "../detection.ts";
|
|
8
|
+
|
|
9
|
+
function classification(kind: ProjectClassification["kind"]): ProjectClassification {
|
|
10
|
+
return {
|
|
11
|
+
kind,
|
|
12
|
+
signals: {
|
|
13
|
+
detectedFiles: [],
|
|
14
|
+
isGitRepo: true,
|
|
15
|
+
isMonorepo: false,
|
|
16
|
+
xcodePlatforms: [],
|
|
17
|
+
hasCI: false,
|
|
18
|
+
hasTests: false,
|
|
19
|
+
verificationCommands: [],
|
|
20
|
+
},
|
|
21
|
+
trackedFiles: [],
|
|
22
|
+
untrackedFiles: [],
|
|
23
|
+
contentFiles: [],
|
|
24
|
+
markers: [],
|
|
25
|
+
reason: kind,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe("worktree project-root degradation", () => {
|
|
30
|
+
test("degrades when worktree is greenfield but project root has content", () => {
|
|
31
|
+
assert.equal(
|
|
32
|
+
shouldDegradeEmptyWorktreeToProjectRoot(
|
|
33
|
+
classification("greenfield"),
|
|
34
|
+
classification("typed-existing"),
|
|
35
|
+
),
|
|
36
|
+
true,
|
|
37
|
+
);
|
|
38
|
+
assert.equal(
|
|
39
|
+
shouldDegradeEmptyWorktreeToProjectRoot(
|
|
40
|
+
classification("greenfield"),
|
|
41
|
+
classification("untyped-existing"),
|
|
42
|
+
),
|
|
43
|
+
true,
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("keeps true greenfield worktrees in worktree mode", () => {
|
|
48
|
+
assert.equal(
|
|
49
|
+
shouldDegradeEmptyWorktreeToProjectRoot(
|
|
50
|
+
classification("greenfield"),
|
|
51
|
+
classification("greenfield"),
|
|
52
|
+
),
|
|
53
|
+
false,
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("does not degrade when project root classification is invalid", () => {
|
|
58
|
+
assert.equal(
|
|
59
|
+
shouldDegradeEmptyWorktreeToProjectRoot(
|
|
60
|
+
classification("greenfield"),
|
|
61
|
+
classification("invalid-repo"),
|
|
62
|
+
),
|
|
63
|
+
false,
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -118,6 +118,9 @@ function makeDeps(
|
|
|
118
118
|
calls.push({ fn: "getCurrentBranch", args: [basePath] });
|
|
119
119
|
return "main";
|
|
120
120
|
},
|
|
121
|
+
checkoutBranch: (basePath: string, branch: string) => {
|
|
122
|
+
calls.push({ fn: "checkoutBranch", args: [basePath, branch] });
|
|
123
|
+
},
|
|
121
124
|
autoWorktreeBranch: (milestoneId: string) => {
|
|
122
125
|
calls.push({ fn: "autoWorktreeBranch", args: [milestoneId] });
|
|
123
126
|
return `milestone/${milestoneId}`;
|
|
@@ -526,6 +529,42 @@ test("exitMilestone commits, tears down, and resets basePath", () => {
|
|
|
526
529
|
assert.equal(findCalls(deps.calls, "invalidateAllCaches").length, 1);
|
|
527
530
|
});
|
|
528
531
|
|
|
532
|
+
test("exitMilestone moves cwd to project root before teardown", (t) => {
|
|
533
|
+
const originalCwd = process.cwd();
|
|
534
|
+
const base = realpathSync(mkdtempSync(join(tmpdir(), "gsd-exit-cwd-")));
|
|
535
|
+
const wtPath = join(base, ".gsd", "worktrees", "M001");
|
|
536
|
+
mkdirSync(wtPath, { recursive: true });
|
|
537
|
+
t.after(() => {
|
|
538
|
+
process.chdir(originalCwd);
|
|
539
|
+
rmSync(base, { recursive: true, force: true });
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
process.chdir(wtPath);
|
|
543
|
+
const s = makeSession({
|
|
544
|
+
basePath: wtPath,
|
|
545
|
+
originalBasePath: base,
|
|
546
|
+
});
|
|
547
|
+
const deps = makeDeps({
|
|
548
|
+
isInAutoWorktree: () => true,
|
|
549
|
+
});
|
|
550
|
+
deps.teardownAutoWorktree = (
|
|
551
|
+
teardownBasePath: string,
|
|
552
|
+
milestoneId: string,
|
|
553
|
+
opts?: { preserveBranch?: boolean },
|
|
554
|
+
) => {
|
|
555
|
+
deps.calls.push({ fn: "teardownAutoWorktree", args: [teardownBasePath, milestoneId, opts] });
|
|
556
|
+
assert.equal(process.cwd(), base);
|
|
557
|
+
rmSync(wtPath, { recursive: true, force: true });
|
|
558
|
+
};
|
|
559
|
+
const ctx = makeNotifyCtx();
|
|
560
|
+
const resolver = new WorktreeResolver(s, deps);
|
|
561
|
+
|
|
562
|
+
resolver.exitMilestone("M001", ctx);
|
|
563
|
+
|
|
564
|
+
assert.equal(process.cwd(), base);
|
|
565
|
+
assert.equal(s.basePath, base);
|
|
566
|
+
});
|
|
567
|
+
|
|
529
568
|
test("exitMilestone is no-op when not in worktree", () => {
|
|
530
569
|
const s = makeSession();
|
|
531
570
|
const deps = makeDeps({
|
|
@@ -802,21 +841,92 @@ test("mergeAndExit in branch mode merges when on milestone branch", () => {
|
|
|
802
841
|
assert.ok(ctx.messages.some((m) => m.msg.includes("branch mode")));
|
|
803
842
|
});
|
|
804
843
|
|
|
805
|
-
test("mergeAndExit in branch mode
|
|
844
|
+
test("mergeAndExit in branch mode checks out the milestone branch and merges (#5538-followup)", () => {
|
|
845
|
+
// Regression: previously this case silently returned without merging,
|
|
846
|
+
// stranding the milestone's commits on the branch (the test12345 repro).
|
|
847
|
+
// The fix forces a checkout first; merge proceeds when checkout succeeds.
|
|
806
848
|
const s = makeSession({ basePath: "/project", originalBasePath: "/project" });
|
|
849
|
+
let currentBranch = "main";
|
|
850
|
+
const checkoutInvocations: Array<{ basePath: string; branch: string }> = [];
|
|
807
851
|
const deps = makeDeps({
|
|
808
852
|
isInAutoWorktree: () => false,
|
|
809
853
|
getIsolationMode: () => "branch",
|
|
810
|
-
getCurrentBranch: () =>
|
|
854
|
+
getCurrentBranch: () => currentBranch,
|
|
811
855
|
autoWorktreeBranch: () => "milestone/M001",
|
|
856
|
+
checkoutBranch: (basePath: string, branch: string) => {
|
|
857
|
+
checkoutInvocations.push({ basePath, branch });
|
|
858
|
+
currentBranch = branch;
|
|
859
|
+
},
|
|
812
860
|
});
|
|
813
861
|
const ctx = makeNotifyCtx();
|
|
814
862
|
const resolver = new WorktreeResolver(s, deps);
|
|
815
863
|
|
|
816
864
|
resolver.mergeAndExit("M001", ctx);
|
|
817
865
|
|
|
866
|
+
assert.equal(checkoutInvocations.length, 1, "must attempt checkout when on wrong branch");
|
|
867
|
+
assert.deepEqual(checkoutInvocations[0], { basePath: "/project", branch: "milestone/M001" });
|
|
868
|
+
assert.equal(findCalls(deps.calls, "mergeMilestoneToMain").length, 1);
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
test("mergeAndExit in branch mode throws when checkout fails", () => {
|
|
872
|
+
// Regression for the silent-skip bug: if the working tree is on the wrong
|
|
873
|
+
// branch and checkout fails, we must throw so the caller pauses auto-mode
|
|
874
|
+
// — never silently advance with the milestone unmerged.
|
|
875
|
+
const s = makeSession({ basePath: "/project", originalBasePath: "/project" });
|
|
876
|
+
const deps = makeDeps({
|
|
877
|
+
isInAutoWorktree: () => false,
|
|
878
|
+
getIsolationMode: () => "branch",
|
|
879
|
+
getCurrentBranch: () => "main",
|
|
880
|
+
autoWorktreeBranch: () => "milestone/M001",
|
|
881
|
+
checkoutBranch: () => {
|
|
882
|
+
throw new Error("dirty working tree blocks checkout");
|
|
883
|
+
},
|
|
884
|
+
});
|
|
885
|
+
const ctx = makeNotifyCtx();
|
|
886
|
+
const resolver = new WorktreeResolver(s, deps);
|
|
887
|
+
|
|
888
|
+
assert.throws(
|
|
889
|
+
() => resolver.mergeAndExit("M001", ctx),
|
|
890
|
+
/dirty working tree blocks checkout/,
|
|
891
|
+
);
|
|
892
|
+
assert.equal(
|
|
893
|
+
findCalls(deps.calls, "mergeMilestoneToMain").length,
|
|
894
|
+
0,
|
|
895
|
+
"merge must not run when checkout failed",
|
|
896
|
+
);
|
|
897
|
+
const errorNotify = ctx.messages.find((m) => m.level === "error");
|
|
898
|
+
assert.ok(errorNotify, "an error notification must be emitted");
|
|
899
|
+
assert.match(errorNotify!.msg, /milestone\/M001 failed/);
|
|
900
|
+
assert.match(errorNotify!.msg, /Resolve manually/);
|
|
901
|
+
assert.equal(
|
|
902
|
+
ctx.messages.some((m) => m.level === "warning" && m.msg.includes("Milestone merge failed")),
|
|
903
|
+
false,
|
|
904
|
+
"checkout failures with explicit recovery guidance must not emit a duplicate warning",
|
|
905
|
+
);
|
|
906
|
+
});
|
|
907
|
+
|
|
908
|
+
test("mergeAndExit in branch mode throws when checkout reports success but HEAD is still wrong", () => {
|
|
909
|
+
// Defense in depth: even if checkoutBranch returns without throwing, we
|
|
910
|
+
// re-verify and throw if HEAD didn't actually move. Prevents merging on
|
|
911
|
+
// top of the wrong branch on platforms where the checkout is a no-op.
|
|
912
|
+
const s = makeSession({ basePath: "/project", originalBasePath: "/project" });
|
|
913
|
+
const deps = makeDeps({
|
|
914
|
+
isInAutoWorktree: () => false,
|
|
915
|
+
getIsolationMode: () => "branch",
|
|
916
|
+
getCurrentBranch: () => "main", // never changes — simulates no-op checkout
|
|
917
|
+
autoWorktreeBranch: () => "milestone/M001",
|
|
918
|
+
checkoutBranch: () => {
|
|
919
|
+
// Pretend success — but getCurrentBranch will still return "main".
|
|
920
|
+
},
|
|
921
|
+
});
|
|
922
|
+
const ctx = makeNotifyCtx();
|
|
923
|
+
const resolver = new WorktreeResolver(s, deps);
|
|
924
|
+
|
|
925
|
+
assert.throws(
|
|
926
|
+
() => resolver.mergeAndExit("M001", ctx),
|
|
927
|
+
/reported success but current branch is main/,
|
|
928
|
+
);
|
|
818
929
|
assert.equal(findCalls(deps.calls, "mergeMilestoneToMain").length, 0);
|
|
819
|
-
assert.equal(ctx.messages.length, 0);
|
|
820
930
|
});
|
|
821
931
|
|
|
822
932
|
test("mergeAndExit in branch mode handles merge failure gracefully", () => {
|
|
@@ -1039,6 +1149,33 @@ test("mergeAndEnterNext enters next milestone even if merge fails", () => {
|
|
|
1039
1149
|
);
|
|
1040
1150
|
});
|
|
1041
1151
|
|
|
1152
|
+
test("mergeAndEnterNext halts after branch-mode user-notified checkout failure", () => {
|
|
1153
|
+
const s = makeSession({ basePath: "/project", originalBasePath: "/project" });
|
|
1154
|
+
const deps = makeDeps({
|
|
1155
|
+
isInAutoWorktree: () => false,
|
|
1156
|
+
getIsolationMode: () => "branch",
|
|
1157
|
+
getCurrentBranch: () => "main",
|
|
1158
|
+
autoWorktreeBranch: () => "milestone/M001",
|
|
1159
|
+
checkoutBranch: () => {
|
|
1160
|
+
throw new Error("dirty working tree blocks checkout");
|
|
1161
|
+
},
|
|
1162
|
+
});
|
|
1163
|
+
const ctx = makeNotifyCtx();
|
|
1164
|
+
const resolver = new WorktreeResolver(s, deps);
|
|
1165
|
+
|
|
1166
|
+
assert.throws(
|
|
1167
|
+
() => resolver.mergeAndEnterNext("M001", "M002", ctx),
|
|
1168
|
+
/dirty working tree blocks checkout/,
|
|
1169
|
+
);
|
|
1170
|
+
assert.equal(
|
|
1171
|
+
findCalls(deps.calls, "enterBranchModeForMilestone").length,
|
|
1172
|
+
0,
|
|
1173
|
+
"must not enter the next milestone after a user-notified branch-mode failure",
|
|
1174
|
+
);
|
|
1175
|
+
assert.equal(findCalls(deps.calls, "mergeMilestoneToMain").length, 0);
|
|
1176
|
+
assert.ok(ctx.messages.some((m) => m.level === "error" && m.msg.includes("Resolve manually")));
|
|
1177
|
+
});
|
|
1178
|
+
|
|
1042
1179
|
// ─── GitService Rebuild Atomicity ────────────────────────────────────────────
|
|
1043
1180
|
|
|
1044
1181
|
test("GitService is rebuilt with the NEW basePath after enterMilestone", () => {
|
|
@@ -1,19 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* parseable slices the same as no roadmap — offer "Create roadmap" not "Go auto".
|
|
4
|
-
*/
|
|
1
|
+
// GSD-2 — Guided roadmap slice detection regression tests.
|
|
2
|
+
|
|
5
3
|
import { test } from "node:test";
|
|
6
4
|
import assert from "node:assert/strict";
|
|
7
|
-
import { readFileSync } from "node:fs";
|
|
8
|
-
import { join } from "node:path";
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
import { _roadmapHasParseableSlicesForTest } from "../guided-flow.ts";
|
|
7
|
+
|
|
8
|
+
test("guided flow treats placeholder roadmaps with zero slices as not runnable", () => {
|
|
9
|
+
assert.equal(
|
|
10
|
+
_roadmapHasParseableSlicesForTest("# M001 Roadmap\n\nPlanning notes only.\n"),
|
|
11
|
+
false,
|
|
14
12
|
);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test("guided flow accepts roadmaps with parseable slices", () => {
|
|
16
|
+
assert.equal(
|
|
17
|
+
_roadmapHasParseableSlicesForTest([
|
|
18
|
+
"# M001 Roadmap",
|
|
19
|
+
"",
|
|
20
|
+
"## Slices",
|
|
21
|
+
"- [ ] **S01: First slice** `risk:low` `depends:[]`",
|
|
22
|
+
].join("\n")),
|
|
23
|
+
true,
|
|
18
24
|
);
|
|
19
25
|
});
|
|
@@ -32,21 +32,21 @@ export interface CompleteMilestoneParams {
|
|
|
32
32
|
oneLiner: string;
|
|
33
33
|
narrative: string;
|
|
34
34
|
verificationPassed: boolean;
|
|
35
|
-
/** @optional —
|
|
35
|
+
/** @optional — empty/omitted renders as "Not provided." */
|
|
36
36
|
successCriteriaResults?: string;
|
|
37
|
-
/** @optional —
|
|
37
|
+
/** @optional — empty/omitted renders as "Not provided." */
|
|
38
38
|
definitionOfDoneResults?: string;
|
|
39
|
-
/** @optional —
|
|
39
|
+
/** @optional — empty/omitted renders as "Not provided." */
|
|
40
40
|
requirementOutcomes?: string;
|
|
41
|
-
/** @optional —
|
|
41
|
+
/** @optional — empty/omitted renders as "(none)" */
|
|
42
42
|
keyDecisions?: string[];
|
|
43
|
-
/** @optional —
|
|
43
|
+
/** @optional — empty/omitted renders as "(none)" */
|
|
44
44
|
keyFiles?: string[];
|
|
45
|
-
/** @optional —
|
|
45
|
+
/** @optional — empty/omitted renders as "(none)" */
|
|
46
46
|
lessonsLearned?: string[];
|
|
47
|
-
/** @optional —
|
|
47
|
+
/** @optional — empty/omitted renders as "None." */
|
|
48
48
|
followUps?: string;
|
|
49
|
-
/** @optional —
|
|
49
|
+
/** @optional — empty/omitted renders as "None." */
|
|
50
50
|
deviations?: string;
|
|
51
51
|
/** Optional caller-provided identity for audit trail */
|
|
52
52
|
actorName?: string;
|
|
@@ -61,8 +61,7 @@ export interface CompleteMilestoneResult {
|
|
|
61
61
|
alreadyComplete?: boolean;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
function renderMilestoneSummaryMarkdown(params: CompleteMilestoneParams): string {
|
|
65
|
-
const now = new Date().toISOString();
|
|
64
|
+
function renderMilestoneSummaryMarkdown(params: CompleteMilestoneParams, completedAt: string): string {
|
|
66
65
|
const displayTitle = stripIdPrefix(params.title, params.milestoneId);
|
|
67
66
|
|
|
68
67
|
// Apply defaults for optional enrichment fields (#2771)
|
|
@@ -86,7 +85,7 @@ function renderMilestoneSummaryMarkdown(params: CompleteMilestoneParams): string
|
|
|
86
85
|
id: ${params.milestoneId}
|
|
87
86
|
title: "${displayTitle}"
|
|
88
87
|
status: complete
|
|
89
|
-
completed_at: ${
|
|
88
|
+
completed_at: ${completedAt}
|
|
90
89
|
key_decisions:
|
|
91
90
|
${keyDecisionsYaml}
|
|
92
91
|
key_files:
|
|
@@ -105,15 +104,15 @@ ${params.narrative}
|
|
|
105
104
|
|
|
106
105
|
## Success Criteria Results
|
|
107
106
|
|
|
108
|
-
${params.successCriteriaResults
|
|
107
|
+
${params.successCriteriaResults || "Not provided."}
|
|
109
108
|
|
|
110
109
|
## Definition of Done Results
|
|
111
110
|
|
|
112
|
-
${params.definitionOfDoneResults
|
|
111
|
+
${params.definitionOfDoneResults || "Not provided."}
|
|
113
112
|
|
|
114
113
|
## Requirement Outcomes
|
|
115
114
|
|
|
116
|
-
${params.requirementOutcomes
|
|
115
|
+
${params.requirementOutcomes || "Not provided."}
|
|
117
116
|
|
|
118
117
|
## Deviations
|
|
119
118
|
|
|
@@ -193,7 +192,7 @@ export async function handleCompleteMilestone(
|
|
|
193
192
|
}
|
|
194
193
|
|
|
195
194
|
// ── Filesystem operations (outside transaction) ─────────────────────────
|
|
196
|
-
const summaryMd = renderMilestoneSummaryMarkdown(params);
|
|
195
|
+
const summaryMd = renderMilestoneSummaryMarkdown(params, completedAt);
|
|
197
196
|
|
|
198
197
|
let summaryPath: string;
|
|
199
198
|
const milestoneDir = resolveMilestonePath(basePath, params.milestoneId);
|
|
@@ -85,7 +85,7 @@ function taskGateFieldForId(
|
|
|
85
85
|
* Normalize a list parameter that may arrive as a string (newline-delimited
|
|
86
86
|
* bullet list from the LLM) into a string array (#3361).
|
|
87
87
|
*/
|
|
88
|
-
function normalizeListParam(value: unknown): string[] {
|
|
88
|
+
export function normalizeListParam(value: unknown): string[] {
|
|
89
89
|
if (Array.isArray(value)) return value.map(String);
|
|
90
90
|
if (typeof value === "string" && value.trim()) {
|
|
91
91
|
return value.split(/\n/).map(s => s.replace(/^[\s\-*•]+/, "").trim()).filter(Boolean);
|