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
|
@@ -90,44 +90,3 @@ test("getBrowser() guard triggers closeBrowser when browser is active", async ()
|
|
|
90
90
|
assert.equal(closeCalled, true, "browser.close() should have been called");
|
|
91
91
|
assert.equal(getBrowser(), null, "browser should be null after guarded teardown");
|
|
92
92
|
});
|
|
93
|
-
|
|
94
|
-
// ─── Source code verification ───────────────────────────────────────────────
|
|
95
|
-
|
|
96
|
-
test("stopAuto finally block includes browser teardown", async () => {
|
|
97
|
-
// Verify the source code contains the browser teardown call
|
|
98
|
-
const { readFileSync } = await import("node:fs");
|
|
99
|
-
const { resolve } = await import("node:path");
|
|
100
|
-
const autoSource = readFileSync(resolve(import.meta.dirname, "..", "auto.ts"), "utf-8");
|
|
101
|
-
|
|
102
|
-
assert.ok(
|
|
103
|
-
autoSource.includes("closeBrowser"),
|
|
104
|
-
"auto.ts should reference closeBrowser for teardown in stopAuto",
|
|
105
|
-
);
|
|
106
|
-
assert.ok(
|
|
107
|
-
autoSource.includes("getBrowser"),
|
|
108
|
-
"auto.ts should check getBrowser() before calling closeBrowser",
|
|
109
|
-
);
|
|
110
|
-
assert.ok(
|
|
111
|
-
autoSource.includes("browser-tools/lifecycle"),
|
|
112
|
-
"auto.ts should import from browser-tools/lifecycle",
|
|
113
|
-
);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
test("postUnitPreVerification includes browser teardown between units", async () => {
|
|
117
|
-
const { readFileSync } = await import("node:fs");
|
|
118
|
-
const { resolve } = await import("node:path");
|
|
119
|
-
const postUnitSource = readFileSync(resolve(import.meta.dirname, "..", "auto-post-unit.ts"), "utf-8");
|
|
120
|
-
|
|
121
|
-
assert.ok(
|
|
122
|
-
postUnitSource.includes("closeBrowser"),
|
|
123
|
-
"auto-post-unit.ts should reference closeBrowser for inter-unit teardown",
|
|
124
|
-
);
|
|
125
|
-
assert.ok(
|
|
126
|
-
postUnitSource.includes("getBrowser"),
|
|
127
|
-
"auto-post-unit.ts should check getBrowser() before calling closeBrowser",
|
|
128
|
-
);
|
|
129
|
-
assert.ok(
|
|
130
|
-
postUnitSource.includes("browser-teardown"),
|
|
131
|
-
"auto-post-unit.ts should have browser-teardown debug phase",
|
|
132
|
-
);
|
|
133
|
-
});
|
|
@@ -131,9 +131,11 @@ test("postflightPopStash — restores stashed changes and emits info notificatio
|
|
|
131
131
|
run('git commit -m "simulate merge"', repo);
|
|
132
132
|
|
|
133
133
|
const postNotifications: Array<{ msg: string; level: string }> = [];
|
|
134
|
-
postflightPopStash(repo, "M004", preflight.stashMarker, (msg, level) => {
|
|
134
|
+
const postflight = postflightPopStash(repo, "M004", preflight.stashMarker, (msg, level) => {
|
|
135
135
|
postNotifications.push({ msg, level });
|
|
136
136
|
});
|
|
137
|
+
assert.equal(postflight.restored, true, "postflight must report successful restore");
|
|
138
|
+
assert.equal(postflight.needsManualRecovery, false, "successful restore must not need manual recovery");
|
|
137
139
|
|
|
138
140
|
// The stashed README.md change must be restored
|
|
139
141
|
const content = readFileSync(join(repo, "README.md"), "utf-8");
|
|
@@ -171,7 +173,8 @@ test("preflight + merge + postflight round-trip preserves uncommitted changes",
|
|
|
171
173
|
run('git commit -m "feat: add feature"', repo);
|
|
172
174
|
|
|
173
175
|
// Postflight: pop stash
|
|
174
|
-
postflightPopStash(repo, "M005", preflight.stashMarker, () => {});
|
|
176
|
+
const postflight = postflightPopStash(repo, "M005", preflight.stashMarker, () => {});
|
|
177
|
+
assert.equal(postflight.needsManualRecovery, false, "clean restore must not stop auto-mode");
|
|
175
178
|
|
|
176
179
|
// README.md must still have our local content
|
|
177
180
|
const restored = readFileSync(join(repo, "README.md"), "utf-8");
|
|
@@ -197,9 +200,12 @@ test("postflightPopStash conflict warning names the exact stash ref", () => {
|
|
|
197
200
|
run('git commit -m "simulate conflicting merge"', repo);
|
|
198
201
|
|
|
199
202
|
const notifications: Array<{ msg: string; level: string }> = [];
|
|
200
|
-
postflightPopStash(repo, "M005C", preflight.stashMarker, (msg, level) => {
|
|
203
|
+
const postflight = postflightPopStash(repo, "M005C", preflight.stashMarker, (msg, level) => {
|
|
201
204
|
notifications.push({ msg, level });
|
|
202
205
|
});
|
|
206
|
+
assert.equal(postflight.restored, false, "conflicted restore must report restored=false");
|
|
207
|
+
assert.equal(postflight.needsManualRecovery, true, "conflicted restore must require manual recovery");
|
|
208
|
+
assert.match(postflight.message, /failed after merge of milestone M005C/);
|
|
203
209
|
|
|
204
210
|
const warning = notifications.find((n) => n.level === "warning")?.msg ?? "";
|
|
205
211
|
assert.match(warning, /git stash pop stash@\{\d+\}/);
|
|
@@ -219,7 +225,8 @@ test("postflightPopStash restores the matching GSD stash, not stash@{0}", () =>
|
|
|
219
225
|
writeFileSync(join(repo, "other.txt"), "other stash\n");
|
|
220
226
|
run('git stash push --include-untracked -m "unrelated newer stash"', repo);
|
|
221
227
|
|
|
222
|
-
postflightPopStash(repo, "M006", preflight.stashMarker, () => {});
|
|
228
|
+
const postflight = postflightPopStash(repo, "M006", preflight.stashMarker, () => {});
|
|
229
|
+
assert.equal(postflight.needsManualRecovery, false, "targeted restore must not need manual recovery");
|
|
223
230
|
|
|
224
231
|
const content = readFileSync(join(repo, "README.md"), "utf-8");
|
|
225
232
|
assert.equal(content.replace(/\r\n/g, "\n"), "# target stash\n");
|
|
@@ -242,7 +249,8 @@ test("postflightPopStash restores the exact preflight marker when another same-m
|
|
|
242
249
|
writeFileSync(join(repo, "same-milestone.txt"), "newer same milestone stash\n");
|
|
243
250
|
run('git stash push --include-untracked -m "gsd-preflight-stash [gsd-preflight-stash:M007:other]"', repo);
|
|
244
251
|
|
|
245
|
-
postflightPopStash(repo, "M007", preflight.stashMarker, () => {});
|
|
252
|
+
const postflight = postflightPopStash(repo, "M007", preflight.stashMarker, () => {});
|
|
253
|
+
assert.equal(postflight.needsManualRecovery, false, "exact marker restore must not need manual recovery");
|
|
246
254
|
|
|
247
255
|
const content = readFileSync(join(repo, "README.md"), "utf-8");
|
|
248
256
|
assert.equal(content.replace(/\r\n/g, "\n"), "# target stash\n");
|
|
@@ -260,7 +268,8 @@ test("postflightPopStash falls back to milestone marker prefix when exact marker
|
|
|
260
268
|
writeFileSync(join(repo, "README.md"), "# fallback stash\n");
|
|
261
269
|
run('git stash push --include-untracked -m "gsd-preflight-stash [gsd-preflight-stash:M008:fallback]"', repo);
|
|
262
270
|
|
|
263
|
-
postflightPopStash(repo, "M008", undefined, () => {});
|
|
271
|
+
const postflight = postflightPopStash(repo, "M008", undefined, () => {});
|
|
272
|
+
assert.equal(postflight.needsManualRecovery, false, "fallback marker restore must not need manual recovery");
|
|
264
273
|
|
|
265
274
|
const content = readFileSync(join(repo, "README.md"), "utf-8");
|
|
266
275
|
assert.equal(content.replace(/\r\n/g, "\n"), "# fallback stash\n");
|
|
@@ -1,41 +1,48 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* clear-stale-autostart.test.ts — #3667
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* interrupted discussions don't permanently block future /gsd invocations.
|
|
4
|
+
* Pending auto-start entries carry a createdAt timestamp so later /gsd
|
|
5
|
+
* invocations can distinguish an in-flight discussion from a stale one.
|
|
7
6
|
*/
|
|
8
7
|
|
|
9
|
-
import { describe, test } from "node:test";
|
|
8
|
+
import { describe, test, afterEach } from "node:test";
|
|
10
9
|
import assert from "node:assert/strict";
|
|
11
|
-
import {
|
|
12
|
-
import { join
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
import { mkdtempSync, mkdirSync, realpathSync, rmSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { tmpdir } from "node:os";
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
_getPendingAutoStart,
|
|
16
|
+
clearPendingAutoStart,
|
|
17
|
+
setPendingAutoStart,
|
|
18
|
+
} from "../guided-flow.ts";
|
|
19
|
+
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
clearPendingAutoStart();
|
|
22
|
+
});
|
|
17
23
|
|
|
18
24
|
describe("clear stale pending auto-start (#3667)", () => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
test("setPendingAutoStart defaults createdAt to Date.now()", (t) => {
|
|
26
|
+
const base = realpathSync(mkdtempSync(join(tmpdir(), "gsd-pending-autostart-")));
|
|
27
|
+
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
28
|
+
mkdirSync(join(base, ".gsd"), { recursive: true });
|
|
29
|
+
const before = Date.now();
|
|
30
|
+
|
|
31
|
+
setPendingAutoStart(base, { basePath: base, milestoneId: "M001" });
|
|
32
|
+
|
|
33
|
+
const entry = _getPendingAutoStart(base);
|
|
34
|
+
assert.ok(entry);
|
|
35
|
+
assert.equal(typeof entry!.createdAt, "number");
|
|
36
|
+
assert.ok(entry!.createdAt >= before);
|
|
23
37
|
});
|
|
24
38
|
|
|
25
|
-
test("setPendingAutoStart
|
|
26
|
-
|
|
27
|
-
|
|
39
|
+
test("setPendingAutoStart preserves explicit createdAt for stale-entry checks", (t) => {
|
|
40
|
+
const base = realpathSync(mkdtempSync(join(tmpdir(), "gsd-pending-autostart-old-")));
|
|
41
|
+
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
42
|
+
mkdirSync(join(base, ".gsd"), { recursive: true });
|
|
28
43
|
|
|
29
|
-
|
|
30
|
-
assert.match(source, /30[_]?000/);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test("stale entry detection checks manifest and context files", () => {
|
|
34
|
-
assert.match(source, /DISCUSSION-MANIFEST\.json/);
|
|
35
|
-
assert.match(source, /CONTEXT\.md/);
|
|
36
|
-
});
|
|
44
|
+
setPendingAutoStart(base, { basePath: base, milestoneId: "M001", createdAt: 123 });
|
|
37
45
|
|
|
38
|
-
|
|
39
|
-
assert.match(source, /pendingAutoStartMap\.delete\(basePath\)/);
|
|
46
|
+
assert.equal(_getPendingAutoStart(base)?.createdAt, 123);
|
|
40
47
|
});
|
|
41
48
|
});
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Unit tests for cmux integration, layout, and CLI isolation.
|
|
1
3
|
import test, { describe, beforeEach, afterEach } from "node:test";
|
|
2
4
|
import assert from "node:assert/strict";
|
|
3
5
|
import * as fs from "node:fs";
|
|
@@ -7,6 +9,7 @@ import { fileURLToPath } from "node:url";
|
|
|
7
9
|
import {
|
|
8
10
|
buildCmuxProgress,
|
|
9
11
|
buildCmuxStatusLabel,
|
|
12
|
+
CmuxClient,
|
|
10
13
|
detectCmuxEnvironment,
|
|
11
14
|
markCmuxPromptShown,
|
|
12
15
|
resetCmuxPromptState,
|
|
@@ -256,60 +259,55 @@ describe("createGridLayout", () => {
|
|
|
256
259
|
});
|
|
257
260
|
|
|
258
261
|
describe("CmuxClient stdio isolation", () => {
|
|
259
|
-
test("runSync and runAsync
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
assert.ok(
|
|
275
|
-
runSyncBody.includes('stdio:'),
|
|
276
|
-
"runSync must explicitly set stdio to prevent terminal interference (see #1922)",
|
|
277
|
-
);
|
|
278
|
-
assert.ok(
|
|
279
|
-
runSyncBody.includes('"ignore"'),
|
|
280
|
-
"runSync stdio must ignore stdin to prevent stealing keyboard input from TUI",
|
|
281
|
-
);
|
|
282
|
-
|
|
283
|
-
// Extract runAsync method body
|
|
284
|
-
const runAsyncMatch = source.match(/private async runAsync\(args: string\[\]\)[^{]*\{([\s\S]*?)\n \}/);
|
|
285
|
-
assert.ok(runAsyncMatch, "runAsync method must exist");
|
|
286
|
-
const runAsyncBody = runAsyncMatch[1];
|
|
287
|
-
assert.ok(
|
|
288
|
-
runAsyncBody.includes('stdio:'),
|
|
289
|
-
"runAsync must explicitly set stdio to prevent terminal interference (see #1922)",
|
|
290
|
-
);
|
|
291
|
-
assert.ok(
|
|
292
|
-
runAsyncBody.includes('"ignore"'),
|
|
293
|
-
"runAsync stdio must ignore stdin to prevent stealing keyboard input from TUI",
|
|
294
|
-
);
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
test("isCmuxCliAvailable uses stdio ignore to prevent terminal interference", () => {
|
|
298
|
-
const cmuxIndexPath = path.resolve(
|
|
299
|
-
path.dirname(fileURLToPath(import.meta.url)),
|
|
300
|
-
"../../cmux/index.ts",
|
|
301
|
-
);
|
|
302
|
-
const source = fs.readFileSync(cmuxIndexPath, "utf-8");
|
|
303
|
-
|
|
304
|
-
// Find isCmuxCliAvailable or the cli-check function body
|
|
305
|
-
const fnMatch = source.match(/function isCmuxCliAvailable[\s\S]*?\{([\s\S]*?)\n\}/);
|
|
306
|
-
if (!fnMatch) return; // function may be inlined or renamed — skip rather than fail
|
|
307
|
-
|
|
308
|
-
const fnBody = fnMatch[1];
|
|
309
|
-
assert.ok(
|
|
310
|
-
fnBody.includes('"ignore"') || !fnBody.includes('execFileSync'),
|
|
311
|
-
"isCmuxCliAvailable must not inherit parent stdio (see #1922)",
|
|
262
|
+
test("runSync and runAsync execute the cmux CLI without inheriting test stdin", async () => {
|
|
263
|
+
const binDir = fs.mkdtempSync(path.join(tmpdir(), "cmux-bin-"));
|
|
264
|
+
const logPath = path.join(binDir, "calls.jsonl");
|
|
265
|
+
const cmuxPath = path.join(binDir, "cmux");
|
|
266
|
+
const originalPath = process.env.PATH;
|
|
267
|
+
fs.writeFileSync(
|
|
268
|
+
cmuxPath,
|
|
269
|
+
[
|
|
270
|
+
"#!/usr/bin/env node",
|
|
271
|
+
"const fs = require('node:fs');",
|
|
272
|
+
`fs.appendFileSync(${JSON.stringify(logPath)}, JSON.stringify(process.argv.slice(2)) + '\\n');`,
|
|
273
|
+
"if (process.argv.includes('--json')) process.stdout.write(JSON.stringify({surfaces:[{id:'surface-1'}]}));",
|
|
274
|
+
"else process.stdout.write('ok');",
|
|
275
|
+
].join("\n"),
|
|
276
|
+
"utf-8",
|
|
312
277
|
);
|
|
278
|
+
fs.chmodSync(cmuxPath, 0o755);
|
|
279
|
+
process.env.PATH = `${binDir}:${originalPath ?? ""}`;
|
|
280
|
+
try {
|
|
281
|
+
const client = new CmuxClient({
|
|
282
|
+
enabled: true,
|
|
283
|
+
available: true,
|
|
284
|
+
cliAvailable: true,
|
|
285
|
+
notifications: true,
|
|
286
|
+
sidebar: true,
|
|
287
|
+
splits: true,
|
|
288
|
+
browser: false,
|
|
289
|
+
workspaceId: "workspace-1",
|
|
290
|
+
surfaceId: "surface-0",
|
|
291
|
+
socketPath: "/tmp/cmux.sock",
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
client.setStatus("M001", "executing");
|
|
295
|
+
await client.listSurfaceIds();
|
|
296
|
+
|
|
297
|
+
const calls = fs.readFileSync(logPath, "utf-8").trim().split("\n").map((line) => JSON.parse(line));
|
|
298
|
+
const commandPrefixes = calls.map((call) => call.slice(0, 2));
|
|
299
|
+
assert.ok(
|
|
300
|
+
commandPrefixes.some((prefix) => JSON.stringify(prefix) === JSON.stringify(["set-status", "gsd"])),
|
|
301
|
+
"set-status command should be invoked",
|
|
302
|
+
);
|
|
303
|
+
assert.ok(
|
|
304
|
+
commandPrefixes.some((prefix) => JSON.stringify(prefix) === JSON.stringify(["list-surfaces", "--json"])),
|
|
305
|
+
"list-surfaces command should be invoked",
|
|
306
|
+
);
|
|
307
|
+
} finally {
|
|
308
|
+
process.env.PATH = originalPath;
|
|
309
|
+
fs.rmSync(binDir, { recursive: true, force: true });
|
|
310
|
+
}
|
|
313
311
|
});
|
|
314
312
|
});
|
|
315
313
|
|
|
@@ -1,65 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* cold-resume-db-reopen.test.ts — Regression test for #2940.
|
|
3
|
-
*
|
|
4
|
-
* Validates that the paused-session resume path in auto.ts opens the project
|
|
5
|
-
* database before calling rebuildState() / deriveState(), matching the fresh
|
|
6
|
-
* bootstrap path in auto-start.ts.
|
|
7
|
-
*
|
|
8
|
-
* Without this, cold resume falls back to markdown parsing which misreads
|
|
9
|
-
* done cells and redispatches wrong slices.
|
|
10
3
|
*/
|
|
11
4
|
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
// There must be a DB open call before the first rebuildState call
|
|
53
|
-
const dbOpenPatterns = [
|
|
54
|
-
"openProjectDbIfPresent(",
|
|
55
|
-
"openDatabase(",
|
|
56
|
-
"ensureDbOpen(",
|
|
57
|
-
];
|
|
58
|
-
|
|
59
|
-
const hasDbOpen = dbOpenPatterns.some(pat => preDeriveSection.includes(pat));
|
|
60
|
-
assertTrue(
|
|
61
|
-
hasDbOpen,
|
|
62
|
-
"resume path must open DB before rebuildState/deriveState (#2940)",
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
report();
|
|
5
|
+
import test from "node:test";
|
|
6
|
+
import assert from "node:assert/strict";
|
|
7
|
+
import { refreshResumeResourcesAndDb } from "../auto.ts";
|
|
8
|
+
|
|
9
|
+
test("resume refreshes managed resources and opens DB before state rebuild", async () => {
|
|
10
|
+
const calls: string[] = [];
|
|
11
|
+
|
|
12
|
+
await refreshResumeResourcesAndDb("/tmp/project", {
|
|
13
|
+
env: {
|
|
14
|
+
GSD_CODING_AGENT_DIR: "/tmp/agent",
|
|
15
|
+
GSD_PKG_ROOT: "/tmp/pkg",
|
|
16
|
+
} as NodeJS.ProcessEnv,
|
|
17
|
+
importModule: async (specifier: string) => {
|
|
18
|
+
calls.push(`import:${specifier}`);
|
|
19
|
+
if (specifier.endsWith("/dist/resource-loader.js")) {
|
|
20
|
+
return {
|
|
21
|
+
initResources: (agentDir: string) => calls.push(`initResources:${agentDir}`),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (specifier === "./prompt-loader.js") {
|
|
25
|
+
return {
|
|
26
|
+
primeCache: () => calls.push("primeCache"),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
throw new Error(`unexpected import: ${specifier}`);
|
|
30
|
+
},
|
|
31
|
+
openProjectDb: async (basePath: string) => {
|
|
32
|
+
calls.push(`openDb:${basePath}`);
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
assert.deepEqual(calls, [
|
|
37
|
+
"import:file:///tmp/pkg/dist/resource-loader.js",
|
|
38
|
+
"initResources:/tmp/agent",
|
|
39
|
+
"import:./prompt-loader.js",
|
|
40
|
+
"primeCache",
|
|
41
|
+
"openDb:/tmp/project",
|
|
42
|
+
]);
|
|
43
|
+
});
|
|
@@ -1,24 +1,31 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import {
|
|
4
|
-
import { dirname, join } from "node:path";
|
|
5
|
-
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { getStoredToolKey } from "../commands-config.ts";
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
const
|
|
5
|
+
test("stored tool key lookup skips empty api_key entries", () => {
|
|
6
|
+
const auth = {
|
|
7
|
+
getCredentialsForProvider(providerId: string) {
|
|
8
|
+
assert.equal(providerId, "tavily");
|
|
9
|
+
return [
|
|
10
|
+
{ type: "api_key", key: "" },
|
|
11
|
+
{ type: "oauth", accessToken: "oauth-token" },
|
|
12
|
+
{ type: "api_key", key: "tool-key" },
|
|
13
|
+
];
|
|
14
|
+
},
|
|
15
|
+
};
|
|
9
16
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
);
|
|
17
|
+
assert.equal(getStoredToolKey(auth as any, "tavily"), "tool-key");
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("stored tool key lookup returns undefined when only shadowing credentials exist", () => {
|
|
21
|
+
const auth = {
|
|
22
|
+
getCredentialsForProvider() {
|
|
23
|
+
return [
|
|
24
|
+
{ type: "api_key", key: "" },
|
|
25
|
+
{ type: "oauth", accessToken: "oauth-token" },
|
|
26
|
+
];
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
assert.equal(getStoredToolKey(auth as any, "brave"), undefined);
|
|
24
31
|
});
|
|
@@ -261,3 +261,34 @@ test("#4780 closer prompt: uses excerpts + lists on-demand slice SUMMARY paths",
|
|
|
261
261
|
`closer prompt length ${prompt.length} should be < raw summary size ${rawSize} + 20KB headroom`,
|
|
262
262
|
);
|
|
263
263
|
});
|
|
264
|
+
|
|
265
|
+
test("complete-milestone prompt caps repeated inlined context around 20k chars", async (t) => {
|
|
266
|
+
const base = createBase();
|
|
267
|
+
t.after(() => cleanup(base));
|
|
268
|
+
invalidateAllCaches();
|
|
269
|
+
|
|
270
|
+
writeRoadmap(base, makeRoadmap());
|
|
271
|
+
writeSummary(base, "S01", makeFatSummary("S01"));
|
|
272
|
+
writeSummary(base, "S02", makeFatSummary("S02"));
|
|
273
|
+
writeFileSync(
|
|
274
|
+
join(base, ".gsd", "milestones", "M001", "M001-CONTEXT.md"),
|
|
275
|
+
"# M001 Context\n\n" + "Large milestone context body. ".repeat(1200),
|
|
276
|
+
);
|
|
277
|
+
writeFileSync(
|
|
278
|
+
join(base, ".gsd", "KNOWLEDGE.md"),
|
|
279
|
+
"# Project Knowledge\n\n## Patterns\n\n### Test Milestone shared\n" + "Large scoped knowledge body. ".repeat(1200),
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
const prompt = await buildCompleteMilestonePrompt("M001", "Test Milestone", base);
|
|
283
|
+
const contextStart = prompt.indexOf("## Inlined Context (preloaded");
|
|
284
|
+
const contextEnd = prompt.indexOf("## Steps", contextStart);
|
|
285
|
+
assert.ok(contextStart >= 0, "prompt should include inlined context");
|
|
286
|
+
assert.ok(contextEnd > contextStart, "prompt should include steps after inlined context");
|
|
287
|
+
|
|
288
|
+
const inlinedContext = prompt.slice(contextStart, contextEnd);
|
|
289
|
+
assert.ok(
|
|
290
|
+
inlinedContext.length <= 21_000,
|
|
291
|
+
`inlined context ${inlinedContext.length} chars should stay near the 20k cap`,
|
|
292
|
+
);
|
|
293
|
+
assert.match(inlinedContext, /\[\.\.\.truncated \d+ sections\]/);
|
|
294
|
+
});
|
|
@@ -547,4 +547,144 @@ describe("complete-milestone", () => {
|
|
|
547
547
|
cleanup(base);
|
|
548
548
|
}
|
|
549
549
|
});
|
|
550
|
+
|
|
551
|
+
test("verification-gate step numbers match the actual numbered verification steps", () => {
|
|
552
|
+
// Regression for step-number drift: step 1 (duplicate guard) was inserted
|
|
553
|
+
// in ea5a2cc0 and the rest renumbered, but the gate text was not updated.
|
|
554
|
+
// Re-derive the verification-step indices from the rendered prompt and
|
|
555
|
+
// assert the gate / "Important" footer reference the correct numbers.
|
|
556
|
+
const prompt = loadPromptFromWorktree("complete-milestone", {
|
|
557
|
+
workingDirectory: "/tmp/test-project",
|
|
558
|
+
milestoneId: "M001",
|
|
559
|
+
milestoneTitle: "Step Number Drift",
|
|
560
|
+
roadmapPath: ".gsd/milestones/M001/M001-ROADMAP.md",
|
|
561
|
+
inlinedContext: "context",
|
|
562
|
+
milestoneSummaryPath: ".gsd/milestones/M001/M001-SUMMARY.md",
|
|
563
|
+
skillActivation: "{{skillActivation block}}",
|
|
564
|
+
extractLearningsSteps: "{{extract learnings block}}",
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
function findStep(needle: RegExp): number {
|
|
568
|
+
const lines = prompt.split("\n");
|
|
569
|
+
for (const line of lines) {
|
|
570
|
+
const m = /^(\d+)\.\s/.exec(line);
|
|
571
|
+
if (m && needle.test(line)) return Number(m[1]);
|
|
572
|
+
}
|
|
573
|
+
throw new Error(`no numbered step matches ${needle}`);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
const codeChange = findStep(/Verify code changes/);
|
|
577
|
+
const successCriteria = findStep(/Verify every \*\*success criterion\*\*/);
|
|
578
|
+
const defOfDone = findStep(/Verify \*\*definition of done\*\*/);
|
|
579
|
+
const completeMilestone = findStep(/Persist completion through `gsd_complete_milestone`/);
|
|
580
|
+
const requirementUpdate = findStep(/gsd_requirement_update/);
|
|
581
|
+
|
|
582
|
+
// Gate clause references the verification steps.
|
|
583
|
+
const gateLine = prompt.split("\n").find(l => l.includes("Verification failure was recorded") || l.includes("verification failure was recorded"));
|
|
584
|
+
assert.ok(gateLine, "verification gate sentence is present");
|
|
585
|
+
assert.ok(
|
|
586
|
+
gateLine!.includes(`steps ${codeChange}, ${successCriteria}, or ${defOfDone}`),
|
|
587
|
+
`gate must cite verification steps ${codeChange}, ${successCriteria}, ${defOfDone}; got: ${gateLine}`,
|
|
588
|
+
);
|
|
589
|
+
// "Do NOT proceed with steps X-Y" — Y must be at least the gsd_complete_milestone step.
|
|
590
|
+
const proceedMatch = /Do NOT proceed with steps (\d+)[–-](\d+)/.exec(gateLine!);
|
|
591
|
+
assert.ok(proceedMatch, "gate must include a 'Do NOT proceed with steps X–Y' clause");
|
|
592
|
+
assert.ok(
|
|
593
|
+
Number(proceedMatch![1]) > requirementUpdate - 1 && Number(proceedMatch![2]) >= completeMilestone,
|
|
594
|
+
`'Do NOT proceed' range ${proceedMatch![1]}–${proceedMatch![2]} must cover steps from after the gate through gsd_complete_milestone (${completeMilestone})`,
|
|
595
|
+
);
|
|
596
|
+
|
|
597
|
+
// "Important" footer references the same verification steps.
|
|
598
|
+
const importantLine = prompt.split("\n").find(l => l.includes("Do NOT skip code-change"));
|
|
599
|
+
assert.ok(importantLine, "Important footer is present");
|
|
600
|
+
assert.ok(
|
|
601
|
+
importantLine!.includes(`steps ${codeChange}-${defOfDone}`) ||
|
|
602
|
+
importantLine!.includes(`steps ${codeChange}–${defOfDone}`),
|
|
603
|
+
`Important footer must cite verification range ${codeChange}-${defOfDone}; got: ${importantLine}`,
|
|
604
|
+
);
|
|
605
|
+
|
|
606
|
+
// On-demand Read ordering line cites the gsd_complete_milestone step.
|
|
607
|
+
const readOrderLine = prompt.split("\n").find(l => l.includes("On-demand Read ordering"));
|
|
608
|
+
assert.ok(readOrderLine, "On-demand Read ordering line is present");
|
|
609
|
+
assert.ok(
|
|
610
|
+
readOrderLine!.includes(`(step ${completeMilestone})`),
|
|
611
|
+
`On-demand Read ordering must cite step ${completeMilestone}; got: ${readOrderLine}`,
|
|
612
|
+
);
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
test("sanitizeCompleteMilestoneParams preserves actorName and triggerReason", async () => {
|
|
616
|
+
const { sanitizeCompleteMilestoneParams } = await import("../bootstrap/sanitize-complete-milestone.ts");
|
|
617
|
+
|
|
618
|
+
const sanitized = sanitizeCompleteMilestoneParams({
|
|
619
|
+
milestoneId: "M001",
|
|
620
|
+
title: "T",
|
|
621
|
+
oneLiner: "x",
|
|
622
|
+
narrative: "n",
|
|
623
|
+
verificationPassed: true,
|
|
624
|
+
actorName: " executor-01 ",
|
|
625
|
+
triggerReason: " milestone validation passed ",
|
|
626
|
+
} as any);
|
|
627
|
+
|
|
628
|
+
assert.strictEqual(sanitized.actorName, "executor-01");
|
|
629
|
+
assert.strictEqual(sanitized.triggerReason, "milestone validation passed");
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
test("sanitizeCompleteMilestoneParams omits blank actorName/triggerReason rather than emitting empty strings", async () => {
|
|
633
|
+
const { sanitizeCompleteMilestoneParams } = await import("../bootstrap/sanitize-complete-milestone.ts");
|
|
634
|
+
|
|
635
|
+
const sanitized = sanitizeCompleteMilestoneParams({
|
|
636
|
+
milestoneId: "M001",
|
|
637
|
+
title: "T",
|
|
638
|
+
oneLiner: "x",
|
|
639
|
+
narrative: "n",
|
|
640
|
+
verificationPassed: true,
|
|
641
|
+
// actorName/triggerReason omitted
|
|
642
|
+
} as any);
|
|
643
|
+
|
|
644
|
+
assert.strictEqual(sanitized.actorName, undefined);
|
|
645
|
+
assert.strictEqual(sanitized.triggerReason, undefined);
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
test("rendered SUMMARY.md uses placeholder text for empty enrichment fields", async () => {
|
|
649
|
+
const { handleCompleteMilestone } = await import("../tools/complete-milestone.ts");
|
|
650
|
+
const base = createFixtureBase();
|
|
651
|
+
const mid = "M001";
|
|
652
|
+
const dbPath = join(base, ".gsd", "gsd.db");
|
|
653
|
+
try {
|
|
654
|
+
openDatabase(dbPath);
|
|
655
|
+
insertMilestone({ id: mid, title: "Empty Enrichment", status: "active" });
|
|
656
|
+
insertSlice({ id: "S01", milestoneId: mid, title: "Slice", status: "complete" });
|
|
657
|
+
insertTask({ id: "T01", sliceId: "S01", milestoneId: mid, title: "Task", status: "complete" });
|
|
658
|
+
|
|
659
|
+
const result = await handleCompleteMilestone({
|
|
660
|
+
milestoneId: mid,
|
|
661
|
+
title: "Empty Enrichment",
|
|
662
|
+
oneLiner: "no enrichment",
|
|
663
|
+
narrative: "did the thing",
|
|
664
|
+
// enrichment fields intentionally empty (post-sanitizer state)
|
|
665
|
+
successCriteriaResults: "",
|
|
666
|
+
definitionOfDoneResults: "",
|
|
667
|
+
requirementOutcomes: "",
|
|
668
|
+
keyDecisions: [],
|
|
669
|
+
keyFiles: [],
|
|
670
|
+
lessonsLearned: [],
|
|
671
|
+
followUps: "",
|
|
672
|
+
deviations: "",
|
|
673
|
+
verificationPassed: true,
|
|
674
|
+
}, base);
|
|
675
|
+
|
|
676
|
+
assert.ok(!("error" in result), `handler should succeed: ${JSON.stringify(result)}`);
|
|
677
|
+
const summary = readFileSync((result as { summaryPath: string }).summaryPath, "utf-8");
|
|
678
|
+
assert.match(summary, /## Success Criteria Results\n\nNot provided\./);
|
|
679
|
+
assert.match(summary, /## Definition of Done Results\n\nNot provided\./);
|
|
680
|
+
assert.match(summary, /## Requirement Outcomes\n\nNot provided\./);
|
|
681
|
+
assert.match(summary, /## Deviations\n\nNone\./);
|
|
682
|
+
assert.match(summary, /## Follow-ups\n\nNone\./);
|
|
683
|
+
} finally {
|
|
684
|
+
try { closeDatabase(); } catch { /* */ }
|
|
685
|
+
clearPathCache();
|
|
686
|
+
clearParseCache();
|
|
687
|
+
cleanup(base);
|
|
688
|
+
}
|
|
689
|
+
});
|
|
550
690
|
});
|