gsd-pi 2.80.0-dev.3065f7bfa → 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 +32 -8
- package/dist/resources/extensions/gsd/auto/resolve.js +12 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +3 -1
- 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-post-unit.js +81 -76
- package/dist/resources/extensions/gsd/auto-start.js +41 -6
- package/dist/resources/extensions/gsd/auto-worktree.js +98 -80
- package/dist/resources/extensions/gsd/auto.js +84 -29
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +62 -13
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +20 -26
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +29 -12
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +6 -9
- package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +4 -7
- package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +6 -10
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +5 -9
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +60 -26
- package/dist/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.js +4 -0
- 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/dashboard-overlay.js +1 -1
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +53 -0
- package/dist/resources/extensions/gsd/git-service.js +37 -1
- package/dist/resources/extensions/gsd/guided-flow.js +14 -4
- package/dist/resources/extensions/gsd/init-wizard.js +4 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -4
- 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/worktree-resolver.js +22 -1
- 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 +17 -17
- 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/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 +17 -17
- 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/welcome-screen.d.ts +2 -0
- package/dist/welcome-screen.js +9 -7
- package/package.json +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/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/types.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/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/chat-controller-ordering.test.ts +3 -1
- package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -1
- 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.ts +84 -8
- package/src/resources/extensions/gsd/auto/phases.ts +43 -8
- package/src/resources/extensions/gsd/auto/resolve.ts +19 -0
- package/src/resources/extensions/gsd/auto/run-unit.ts +3 -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-post-unit.ts +93 -78
- package/src/resources/extensions/gsd/auto-start.ts +56 -6
- package/src/resources/extensions/gsd/auto-worktree.ts +118 -72
- package/src/resources/extensions/gsd/auto.ts +121 -29
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +76 -12
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +20 -26
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +27 -12
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +7 -9
- package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +4 -7
- package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +6 -10
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +5 -9
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +64 -26
- package/src/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.ts +4 -0
- 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/dashboard-overlay.ts +1 -1
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +66 -0
- package/src/resources/extensions/gsd/git-service.ts +41 -2
- package/src/resources/extensions/gsd/guided-flow.ts +19 -4
- package/src/resources/extensions/gsd/init-wizard.ts +5 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -4
- 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 +15 -0
- 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 +1 -217
- 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/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.test.ts +140 -0
- 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/crash-handler-secondary.test.ts +35 -31
- 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/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 -59
- 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/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/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/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 +113 -0
- 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-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-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 -90
- 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/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 +61 -1
- 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/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/token-profile.test.ts +84 -309
- 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 +6 -101
- 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-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-main-branch.test.ts +20 -18
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +36 -0
- 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/worktree-resolver.ts +34 -1
- 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/{O2WvnXROue6l7nAp_4dhC → G68KoLv5claox_Dyd4pZn}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{O2WvnXROue6l7nAp_4dhC → G68KoLv5claox_Dyd4pZn}/_ssgManifest.js +0 -0
|
@@ -11,99 +11,15 @@
|
|
|
11
11
|
import test from "node:test";
|
|
12
12
|
import assert from "node:assert/strict";
|
|
13
13
|
import { readFileSync, mkdtempSync, mkdirSync, writeFileSync, existsSync, rmSync, realpathSync } from "node:fs";
|
|
14
|
-
import { join
|
|
14
|
+
import { join } from "node:path";
|
|
15
15
|
import { tmpdir } from "node:os";
|
|
16
|
-
import {
|
|
16
|
+
import { AutoSession } from "../auto/session.ts";
|
|
17
|
+
import { runPreDispatch } from "../auto/phases.ts";
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// ─── Source-level checks ──────────────────────────────────────────────────────
|
|
21
|
-
|
|
22
|
-
test("auto/phases.ts milestone transition block calls rebuildState", () => {
|
|
23
|
-
const phasesSrc = readFileSync(
|
|
24
|
-
join(__dirname, "..", "auto", "phases.ts"),
|
|
25
|
-
"utf-8",
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
// rebuildState must be called within the milestone transition block
|
|
29
|
-
assert.ok(
|
|
30
|
-
phasesSrc.includes("deps.rebuildState(s.basePath)"),
|
|
31
|
-
"auto/phases.ts should call deps.rebuildState(s.basePath) during milestone transition",
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
// The rebuildState call must appear AFTER the pruneQueueOrder call
|
|
35
|
-
// (i.e. after all transition cleanup is done)
|
|
36
|
-
const pruneIdx = phasesSrc.indexOf("deps.pruneQueueOrder(s.basePath, pendingIds)");
|
|
37
|
-
const rebuildIdx = phasesSrc.indexOf("deps.rebuildState(s.basePath)");
|
|
38
|
-
assert.ok(pruneIdx > 0, "pruneQueueOrder should exist in phases.ts");
|
|
39
|
-
assert.ok(rebuildIdx > 0, "rebuildState should exist in phases.ts");
|
|
40
|
-
assert.ok(
|
|
41
|
-
rebuildIdx > pruneIdx,
|
|
42
|
-
"rebuildState should be called after pruneQueueOrder in the milestone transition block",
|
|
43
|
-
);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
test("auto/phases.ts milestone transition block resets completed-units.json", () => {
|
|
47
|
-
const phasesSrc = readFileSync(
|
|
48
|
-
join(__dirname, "..", "auto", "phases.ts"),
|
|
49
|
-
"utf-8",
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
// completed-units.json must be archived and cleared during milestone transition
|
|
53
|
-
const transitionStart = phasesSrc.indexOf("Milestone transition");
|
|
54
|
-
assert.ok(transitionStart > 0, "Milestone transition block should exist");
|
|
55
|
-
|
|
56
|
-
// The old file is archived before being cleared (#2313)
|
|
57
|
-
const archiveSection = phasesSrc.indexOf("completed-units-", transitionStart);
|
|
58
|
-
assert.ok(
|
|
59
|
-
archiveSection > 0,
|
|
60
|
-
"auto/phases.ts should archive completed-units.json during milestone transition",
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
// The disk file should be cleared to an empty array
|
|
64
|
-
assert.ok(
|
|
65
|
-
phasesSrc.includes('atomicWriteSync(completedKeysPath, JSON.stringify([], null, 2))'),
|
|
66
|
-
"auto/phases.ts should write empty array to completed-units.json during milestone transition",
|
|
67
|
-
);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test("auto/loop-deps.ts LoopDeps interface includes rebuildState", () => {
|
|
71
|
-
const loopDepsSrc = readFileSync(
|
|
72
|
-
join(__dirname, "..", "auto", "loop-deps.ts"),
|
|
73
|
-
"utf-8",
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
assert.ok(
|
|
77
|
-
loopDepsSrc.includes("rebuildState: (basePath: string) => Promise<void>"),
|
|
78
|
-
"LoopDeps interface should declare rebuildState method",
|
|
79
|
-
);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
test("auto.ts buildLoopDeps wires rebuildState", () => {
|
|
83
|
-
const autoSrc = readFileSync(
|
|
84
|
-
join(__dirname, "..", "auto.ts"),
|
|
85
|
-
"utf-8",
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
// rebuildState should be in the LoopDeps object literal.
|
|
89
|
-
// Match the signature prefix so the test survives future param changes
|
|
90
|
-
// (e.g. the DECOUPLE-02 change from `()` to `(pi: ExtensionAPI)`).
|
|
91
|
-
const buildLoopDepsIdx = autoSrc.indexOf("function buildLoopDeps(");
|
|
92
|
-
assert.ok(buildLoopDepsIdx > 0, "buildLoopDeps function should exist");
|
|
93
|
-
|
|
94
|
-
const afterBuild = autoSrc.slice(buildLoopDepsIdx);
|
|
95
|
-
assert.ok(
|
|
96
|
-
afterBuild.includes("rebuildState,") || afterBuild.includes("rebuildState:"),
|
|
97
|
-
"buildLoopDeps should include rebuildState in the returned deps object",
|
|
98
|
-
);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
// ─── Functional test: completed-units.json reset ─────────────────────────────
|
|
102
|
-
|
|
103
|
-
test("completed-units.json is cleared on milestone transition (functional)", () => {
|
|
19
|
+
test("milestone transition archives completed units and rebuilds state", async () => {
|
|
104
20
|
const tempDir = realpathSync(mkdtempSync(join(tmpdir(), "gsd-cu-reset-")));
|
|
21
|
+
const calls: string[] = [];
|
|
105
22
|
try {
|
|
106
|
-
// Create .gsd directory with a populated completed-units.json
|
|
107
23
|
const gsdDir = join(tempDir, ".gsd");
|
|
108
24
|
mkdirSync(gsdDir, { recursive: true });
|
|
109
25
|
|
|
@@ -116,16 +32,81 @@ test("completed-units.json is cleared on milestone transition (functional)", ()
|
|
|
116
32
|
];
|
|
117
33
|
writeFileSync(completedKeysPath, JSON.stringify(staleEntries, null, 2));
|
|
118
34
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
35
|
+
const s = new AutoSession();
|
|
36
|
+
s.basePath = tempDir;
|
|
37
|
+
s.originalBasePath = tempDir;
|
|
38
|
+
s.currentMilestoneId = "M001";
|
|
39
|
+
s.unitDispatchCount.set("old", 1);
|
|
40
|
+
s.unitRecoveryCount.set("old", 1);
|
|
41
|
+
s.unitLifetimeDispatches.set("old", 1);
|
|
42
|
+
|
|
43
|
+
const state = {
|
|
44
|
+
phase: "planning",
|
|
45
|
+
activeMilestone: { id: "M002", title: "Next" },
|
|
46
|
+
activeSlice: null,
|
|
47
|
+
activeTask: null,
|
|
48
|
+
recentDecisions: [],
|
|
49
|
+
blockers: [],
|
|
50
|
+
nextAction: "Plan M002",
|
|
51
|
+
registry: [
|
|
52
|
+
{ id: "M001", title: "Done", status: "complete" },
|
|
53
|
+
{ id: "M002", title: "Next", status: "active" },
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const result = await runPreDispatch({
|
|
58
|
+
ctx: { ui: { notify() {} } },
|
|
59
|
+
pi: {},
|
|
60
|
+
s,
|
|
61
|
+
prefs: undefined,
|
|
62
|
+
iteration: 1,
|
|
63
|
+
flowId: "test-flow",
|
|
64
|
+
nextSeq: () => 1,
|
|
65
|
+
deps: {
|
|
66
|
+
checkResourcesStale: () => null,
|
|
67
|
+
invalidateAllCaches: () => calls.push("invalidate"),
|
|
68
|
+
preDispatchHealthGate: async () => ({ proceed: true, fixesApplied: [] }),
|
|
69
|
+
syncProjectRootToWorktree: () => {},
|
|
70
|
+
deriveState: async () => state,
|
|
71
|
+
syncCmuxSidebar: () => {},
|
|
72
|
+
preflightCleanRoot: () => ({ ok: true, stashPushed: false }),
|
|
73
|
+
postflightPopStash: () => ({ ok: true, needsManualRecovery: false }),
|
|
74
|
+
resolver: {
|
|
75
|
+
mergeAndExit: () => calls.push("merge"),
|
|
76
|
+
enterMilestone: (mid: string) => calls.push(`enter:${mid}`),
|
|
77
|
+
},
|
|
78
|
+
sendDesktopNotification: () => {},
|
|
79
|
+
logCmuxEvent: () => {},
|
|
80
|
+
getIsolationMode: () => "none",
|
|
81
|
+
captureIntegrationBranch: () => {},
|
|
82
|
+
pruneQueueOrder: (_base: string, pending: string[]) => calls.push(`prune:${pending.join(",")}`),
|
|
83
|
+
rebuildState: async () => calls.push("rebuild"),
|
|
84
|
+
setActiveMilestoneId: (_base: string, mid: string) => calls.push(`active:${mid}`),
|
|
85
|
+
reconcileMergeState: () => "clean",
|
|
86
|
+
emitJournalEvent: () => {},
|
|
87
|
+
stopAuto: async () => {},
|
|
88
|
+
pauseAuto: async () => {},
|
|
89
|
+
closeoutUnit: async () => {},
|
|
90
|
+
buildSnapshotOpts: () => ({}),
|
|
91
|
+
},
|
|
92
|
+
} as any, {
|
|
93
|
+
recentUnits: [{ key: "stale" }],
|
|
94
|
+
stuckRecoveryAttempts: 2,
|
|
95
|
+
consecutiveFinalizeTimeouts: 0,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
assert.equal(result.action, "next");
|
|
99
|
+
assert.equal(s.currentMilestoneId, "M002");
|
|
100
|
+
assert.equal(s.unitDispatchCount.size, 0);
|
|
101
|
+
assert.equal(s.unitRecoveryCount.size, 0);
|
|
102
|
+
assert.equal(s.unitLifetimeDispatches.size, 0);
|
|
103
|
+
assert.ok(existsSync(join(gsdDir, "completed-units-M001.json")));
|
|
127
104
|
const after = JSON.parse(readFileSync(completedKeysPath, "utf-8"));
|
|
128
|
-
assert.deepEqual(after, []
|
|
105
|
+
assert.deepEqual(after, []);
|
|
106
|
+
assert.ok(
|
|
107
|
+
calls.indexOf("prune:M002") < calls.indexOf("rebuild"),
|
|
108
|
+
`expected prune before rebuild, got ${calls.join(" > ")}`,
|
|
109
|
+
);
|
|
129
110
|
} finally {
|
|
130
111
|
rmSync(tempDir, { recursive: true, force: true });
|
|
131
112
|
}
|
|
@@ -1,298 +1,90 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Model UnitType Mapping —
|
|
2
|
+
* Model UnitType Mapping — behavior tests for #2865 / #2900 / ADR-011.
|
|
3
3
|
*
|
|
4
|
-
* Verifies
|
|
5
|
-
*
|
|
6
|
-
* - classifyUnitPhase (metrics.ts)
|
|
7
|
-
* - LIFECYCLE_ONLY_UNITS (auto-post-unit.ts)
|
|
8
|
-
* - unitVerb / unitPhaseLabel (auto-dashboard.ts)
|
|
9
|
-
* - resolveExpectedArtifactPath (auto-artifact-paths.ts)
|
|
10
|
-
*
|
|
11
|
-
* Uses source-level checks to avoid import resolution issues in dev.
|
|
12
|
-
*
|
|
13
|
-
* Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
4
|
+
* Verifies model routing, metrics/dashboard labels, and artifact resolution
|
|
5
|
+
* through exported runtime APIs instead of inspecting source text.
|
|
14
6
|
*/
|
|
15
7
|
|
|
16
8
|
import test from "node:test";
|
|
17
9
|
import assert from "node:assert/strict";
|
|
18
|
-
import {
|
|
19
|
-
import { join
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
...new Set([...AUTO_DISPATCH_UNIT_TYPES, "discuss-slice"]),
|
|
53
|
-
];
|
|
54
|
-
|
|
55
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
56
|
-
// #2865: discuss dispatches must NOT alias to plan unitTypes
|
|
57
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
58
|
-
|
|
59
|
-
test("#2865: no dispatchWorkflow with gsd-discuss customType uses plan-milestone", () => {
|
|
60
|
-
// Match dispatchWorkflow calls where "gsd-discuss" appears before "plan-milestone"
|
|
61
|
-
// in the same call (the 5 args are on consecutive lines).
|
|
62
|
-
const blocks = guidedFlowSrc.split(/dispatchWorkflow\(/);
|
|
63
|
-
for (const block of blocks) {
|
|
64
|
-
const callEnd = block.indexOf(");");
|
|
65
|
-
if (callEnd === -1) continue;
|
|
66
|
-
const call = block.slice(0, callEnd);
|
|
67
|
-
if (call.includes('"gsd-discuss"') && call.includes('"plan-milestone"')) {
|
|
68
|
-
assert.fail(`Discuss dispatch should not use plan-milestone: ...dispatchWorkflow(${call.slice(0, 120).trim()}...`);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
test("#2865: no dispatchWorkflow with gsd-discuss customType uses plan-slice", () => {
|
|
74
|
-
const blocks = guidedFlowSrc.split(/dispatchWorkflow\(/);
|
|
75
|
-
for (const block of blocks) {
|
|
76
|
-
const callEnd = block.indexOf(");");
|
|
77
|
-
if (callEnd === -1) continue;
|
|
78
|
-
const call = block.slice(0, callEnd);
|
|
79
|
-
if (call.includes('"gsd-discuss"') && call.includes('"plan-slice"')) {
|
|
80
|
-
assert.fail(`Discuss slice dispatch should not use plan-slice: ...dispatchWorkflow(${call.slice(0, 120).trim()}...`);
|
|
81
|
-
}
|
|
10
|
+
import { mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { tmpdir } from "node:os";
|
|
13
|
+
|
|
14
|
+
import { resolveExpectedArtifactPath } from "../auto-artifact-paths.ts";
|
|
15
|
+
import { unitPhaseLabel, unitVerb } from "../auto-dashboard.ts";
|
|
16
|
+
import { classifyUnitPhase } from "../metrics.ts";
|
|
17
|
+
import { resolveModelWithFallbacksForUnit } from "../preferences-models.ts";
|
|
18
|
+
import { KNOWN_UNIT_LABELS } from "../preferences-types.ts";
|
|
19
|
+
|
|
20
|
+
function withModelPreferences<T>(fn: () => T): T {
|
|
21
|
+
const oldHome = process.env.GSD_HOME;
|
|
22
|
+
const home = mkdtempSync(join(tmpdir(), "gsd-model-map-"));
|
|
23
|
+
try {
|
|
24
|
+
process.env.GSD_HOME = home;
|
|
25
|
+
writeFileSync(join(home, "preferences.md"), [
|
|
26
|
+
"---",
|
|
27
|
+
"models:",
|
|
28
|
+
" research: research-model",
|
|
29
|
+
" planning: planning-model",
|
|
30
|
+
" discuss: discuss-model",
|
|
31
|
+
" execution: execution-model",
|
|
32
|
+
" execution_simple: simple-model",
|
|
33
|
+
" completion: completion-model",
|
|
34
|
+
" validation: validation-model",
|
|
35
|
+
" subagent: subagent-model",
|
|
36
|
+
"---",
|
|
37
|
+
"",
|
|
38
|
+
].join("\n"));
|
|
39
|
+
return fn();
|
|
40
|
+
} finally {
|
|
41
|
+
if (oldHome === undefined) delete process.env.GSD_HOME;
|
|
42
|
+
else process.env.GSD_HOME = oldHome;
|
|
43
|
+
rmSync(home, { recursive: true, force: true });
|
|
82
44
|
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
test("#2865: no buildDiscussPrompt call dispatches with plan-milestone", () => {
|
|
86
|
-
const blocks = guidedFlowSrc.split(/dispatchWorkflow\(/);
|
|
87
|
-
for (const block of blocks) {
|
|
88
|
-
const callEnd = block.indexOf(");");
|
|
89
|
-
if (callEnd === -1) continue;
|
|
90
|
-
const call = block.slice(0, callEnd);
|
|
91
|
-
if (call.includes("buildDiscussPrompt") && call.includes('"plan-milestone"')) {
|
|
92
|
-
assert.fail(`buildDiscussPrompt dispatch should not use plan-milestone`);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
test("#2865: no buildDiscussSlicePrompt call dispatches with plan-slice", () => {
|
|
98
|
-
const blocks = guidedFlowSrc.split(/dispatchWorkflow\(/);
|
|
99
|
-
for (const block of blocks) {
|
|
100
|
-
const callEnd = block.indexOf(");");
|
|
101
|
-
if (callEnd === -1) continue;
|
|
102
|
-
const call = block.slice(0, callEnd);
|
|
103
|
-
if (call.includes("buildDiscussSlicePrompt") && call.includes('"plan-slice"')) {
|
|
104
|
-
assert.fail(`buildDiscussSlicePrompt dispatch should not use plan-slice`);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
test("#2865: no guided-discuss-milestone loadPrompt dispatches with plan-milestone", () => {
|
|
110
|
-
const blocks = guidedFlowSrc.split(/dispatchWorkflow\(/);
|
|
111
|
-
for (const block of blocks) {
|
|
112
|
-
const callEnd = block.indexOf(");");
|
|
113
|
-
if (callEnd === -1) continue;
|
|
114
|
-
const call = block.slice(0, callEnd);
|
|
115
|
-
if (call.includes("guided-discuss-milestone") && call.includes('"plan-milestone"')) {
|
|
116
|
-
assert.fail(`guided-discuss-milestone dispatch should not use plan-milestone`);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
122
|
-
// preferences-models.ts: resolveModelWithFallbacksForUnit coverage
|
|
123
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
124
|
-
|
|
125
|
-
test("resolveModelWithFallbacksForUnit handles discuss-milestone", () => {
|
|
126
|
-
assert.ok(preferencesSrc.includes('"discuss-milestone"'), "missing discuss-milestone case");
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
test("resolveModelWithFallbacksForUnit handles discuss-slice", () => {
|
|
130
|
-
assert.ok(preferencesSrc.includes('"discuss-slice"'), "missing discuss-slice case");
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
test("discuss unitTypes fall back to planning when models.discuss is unset", () => {
|
|
134
|
-
assert.ok(
|
|
135
|
-
preferencesSrc.includes("m.discuss ?? m.planning"),
|
|
136
|
-
"discuss should fall back to m.planning",
|
|
137
|
-
);
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
test("validation unitTypes fall back to planning when models.validation is unset", () => {
|
|
141
|
-
assert.ok(
|
|
142
|
-
preferencesSrc.includes("m.validation ?? m.planning"),
|
|
143
|
-
"validation should fall back to m.planning",
|
|
144
|
-
);
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
test("all auto-dispatch unitTypes have preference mapping or subagent handling", () => {
|
|
148
|
-
const unmapped: string[] = [];
|
|
149
|
-
for (const ut of ALL_KNOWN_UNIT_TYPES) {
|
|
150
|
-
if (!preferencesSrc.includes(`"${ut}"`)) {
|
|
151
|
-
unmapped.push(ut);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
assert.deepEqual(unmapped, [], `Unmapped unitTypes in preferences-models.ts: ${unmapped.join(", ")}`);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
158
|
-
// #2900: worktree-merge must map to completion phase
|
|
159
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
160
|
-
|
|
161
|
-
test("#2900: resolveModelWithFallbacksForUnit handles worktree-merge", () => {
|
|
162
|
-
assert.ok(preferencesSrc.includes('"worktree-merge"'), "missing worktree-merge case in switch");
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
166
|
-
// #2900: KNOWN_UNIT_TYPES must include all dispatched unit types
|
|
167
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
168
|
-
|
|
169
|
-
const preferenceTypesSrc = readSrc("preferences-types.ts");
|
|
170
|
-
|
|
171
|
-
test("#2900: KNOWN_UNIT_TYPES includes all auto-dispatch unit types", () => {
|
|
172
|
-
const missing: string[] = [];
|
|
173
|
-
for (const ut of ALL_KNOWN_UNIT_TYPES) {
|
|
174
|
-
if (!preferenceTypesSrc.includes(`"${ut}"`)) {
|
|
175
|
-
missing.push(ut);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
assert.deepEqual(missing, [], `Missing from KNOWN_UNIT_TYPES: ${missing.join(", ")}`);
|
|
179
|
-
});
|
|
45
|
+
}
|
|
180
46
|
|
|
181
|
-
test("
|
|
182
|
-
|
|
47
|
+
test("discuss unit types route to the discuss model bucket", () => {
|
|
48
|
+
withModelPreferences(() => {
|
|
49
|
+
assert.equal(resolveModelWithFallbacksForUnit("discuss-milestone")?.primary, "discuss-model");
|
|
50
|
+
assert.equal(resolveModelWithFallbacksForUnit("discuss-slice")?.primary, "discuss-model");
|
|
51
|
+
});
|
|
183
52
|
});
|
|
184
53
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
assert.ok(metricsSrc.includes('"discussion"'), "MetricsPhase should include discussion");
|
|
54
|
+
test("validation unit types route to the validation model bucket", () => {
|
|
55
|
+
withModelPreferences(() => {
|
|
56
|
+
assert.equal(resolveModelWithFallbacksForUnit("validate-milestone")?.primary, "validation-model");
|
|
57
|
+
assert.equal(resolveModelWithFallbacksForUnit("gate-evaluate")?.primary, "validation-model");
|
|
58
|
+
});
|
|
191
59
|
});
|
|
192
60
|
|
|
193
|
-
test("
|
|
194
|
-
|
|
195
|
-
|
|
61
|
+
test("worktree-merge routes to completion and is recognized as a unit label", () => {
|
|
62
|
+
withModelPreferences(() => {
|
|
63
|
+
assert.ok(KNOWN_UNIT_LABELS.includes("worktree-merge"));
|
|
64
|
+
assert.equal(resolveModelWithFallbacksForUnit("worktree-merge")?.primary, "completion-model");
|
|
65
|
+
});
|
|
196
66
|
});
|
|
197
67
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
assert.ok(postUnitSrc.includes('"discuss-slice"'), "discuss-slice should be lifecycle-only");
|
|
68
|
+
test("every known unit label with a dispatch phase resolves when all model buckets are configured", () => {
|
|
69
|
+
withModelPreferences(() => {
|
|
70
|
+
const missing = KNOWN_UNIT_LABELS.filter((unitType) => !resolveModelWithFallbacksForUnit(unitType));
|
|
71
|
+
assert.deepEqual(missing, []);
|
|
72
|
+
});
|
|
204
73
|
});
|
|
205
74
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
test("unitVerb handles discuss-slice", () => {
|
|
211
|
-
assert.ok(dashboardSrc.includes('"discuss-slice"'), "missing discuss-slice in dashboard");
|
|
75
|
+
test("discuss-slice has discussion metrics and dashboard labels", () => {
|
|
76
|
+
assert.equal(classifyUnitPhase("discuss-slice"), "discussion");
|
|
77
|
+
assert.equal(unitVerb("discuss-slice"), "discussing");
|
|
78
|
+
assert.equal(unitPhaseLabel("discuss-slice"), "DISCUSS");
|
|
212
79
|
});
|
|
213
80
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
223
|
-
|
|
224
|
-
// Intentional exceptions — unit types that legitimately rely on default/null
|
|
225
|
-
// behavior in a specific registry. Entries captured here reflect the current
|
|
226
|
-
// baseline at the time ADR-011 landed; adding to this allowlist for a NEW unit
|
|
227
|
-
// type requires explicit justification in the commit.
|
|
228
|
-
//
|
|
229
|
-
// Test intent: catch the case where someone adds a new unit type to
|
|
230
|
-
// KNOWN_UNIT_TYPES but forgets to wire it into one of the four registries.
|
|
231
|
-
// The allowlist freezes the baseline so pre-existing omissions do not block
|
|
232
|
-
// the test, but any brand-new addition must be either handled or justified.
|
|
233
|
-
// Deep-mode project-level units (workflow-preferences, discuss-project,
|
|
234
|
-
// discuss-requirements, research-decision, research-project) operate above
|
|
235
|
-
// the milestone/slice/task model. They do not produce slice-shaped artifacts,
|
|
236
|
-
// they do not have per-unit dashboard renderers, and they do not have
|
|
237
|
-
// post-unit hooks that mirror execute/complete patterns. They legitimately
|
|
238
|
-
// rely on default behavior in all four registries. Adding them to the
|
|
239
|
-
// allowlist with this justification.
|
|
240
|
-
const DEEP_MODE_PROJECT_UNITS = [
|
|
241
|
-
"workflow-preferences",
|
|
242
|
-
"discuss-project",
|
|
243
|
-
"discuss-requirements",
|
|
244
|
-
"research-decision",
|
|
245
|
-
"research-project",
|
|
246
|
-
];
|
|
247
|
-
|
|
248
|
-
const REGISTRY_EXCEPTIONS: Record<string, Set<string>> = {
|
|
249
|
-
// metrics.ts classifyUnitPhase uses default → "execution" for most unit types.
|
|
250
|
-
"metrics.ts": new Set([
|
|
251
|
-
"worktree-merge", "custom-step",
|
|
252
|
-
"rewrite-docs", "run-uat", "gate-evaluate", "replan-slice",
|
|
253
|
-
"reactive-execute", "validate-milestone", "complete-milestone",
|
|
254
|
-
...DEEP_MODE_PROJECT_UNITS,
|
|
255
|
-
]),
|
|
256
|
-
"auto-dashboard.ts": new Set([
|
|
257
|
-
"worktree-merge",
|
|
258
|
-
"gate-evaluate", "reactive-execute", "validate-milestone", "complete-milestone",
|
|
259
|
-
...DEEP_MODE_PROJECT_UNITS,
|
|
260
|
-
]),
|
|
261
|
-
"auto-artifact-paths.ts": new Set([
|
|
262
|
-
"rewrite-docs", "gate-evaluate", "reactive-execute", "discuss-slice", "worktree-merge",
|
|
263
|
-
...DEEP_MODE_PROJECT_UNITS,
|
|
264
|
-
]),
|
|
265
|
-
"auto-post-unit.ts": new Set([
|
|
266
|
-
"execute-task", "reactive-execute", "gate-evaluate", "worktree-merge",
|
|
267
|
-
...DEEP_MODE_PROJECT_UNITS,
|
|
268
|
-
]),
|
|
269
|
-
};
|
|
270
|
-
|
|
271
|
-
const REGISTRY_SOURCES: Array<[string, string]> = [
|
|
272
|
-
["metrics.ts", metricsSrc],
|
|
273
|
-
["auto-dashboard.ts", dashboardSrc],
|
|
274
|
-
["auto-artifact-paths.ts", artifactSrc],
|
|
275
|
-
["auto-post-unit.ts", postUnitSrc],
|
|
276
|
-
];
|
|
277
|
-
|
|
278
|
-
test("ADR-011 meta: every KNOWN_UNIT_TYPES entry appears in all 4 downstream registries", () => {
|
|
279
|
-
const missing: Array<{ registry: string; unitType: string }> = [];
|
|
280
|
-
for (const [registry, src] of REGISTRY_SOURCES) {
|
|
281
|
-
for (const ut of ALL_KNOWN_UNIT_TYPES) {
|
|
282
|
-
if (REGISTRY_EXCEPTIONS[registry]?.has(ut)) continue;
|
|
283
|
-
if (!src.includes(`"${ut}"`)) {
|
|
284
|
-
missing.push({ registry, unitType: ut });
|
|
285
|
-
}
|
|
286
|
-
}
|
|
81
|
+
test("discuss-slice resolves to the slice context artifact path", () => {
|
|
82
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-discuss-artifact-"));
|
|
83
|
+
try {
|
|
84
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01"), { recursive: true });
|
|
85
|
+
const path = resolveExpectedArtifactPath("discuss-slice", "M001/S01", base);
|
|
86
|
+
assert.equal(path, join(realpathSync(base), ".gsd", "milestones", "M001", "slices", "S01", "S01-CONTEXT.md"));
|
|
87
|
+
} finally {
|
|
88
|
+
rmSync(base, { recursive: true, force: true });
|
|
287
89
|
}
|
|
288
|
-
assert.deepEqual(
|
|
289
|
-
missing,
|
|
290
|
-
[],
|
|
291
|
-
"Each listed unit type is absent from the given registry — either add a handler or add to REGISTRY_EXCEPTIONS with justification:\n" +
|
|
292
|
-
missing.map((m) => ` ${m.registry}: "${m.unitType}"`).join("\n"),
|
|
293
|
-
);
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
test("resolveExpectedArtifactPath handles discuss-slice", () => {
|
|
297
|
-
assert.ok(artifactSrc.includes('"discuss-slice"'), "missing discuss-slice in artifact paths");
|
|
298
90
|
});
|
|
@@ -6,43 +6,50 @@
|
|
|
6
6
|
* dispatch blocks completion for needs-remediation while state derives
|
|
7
7
|
* completing-milestone, creating a permanent deadlock.
|
|
8
8
|
*
|
|
9
|
-
* This
|
|
10
|
-
*
|
|
9
|
+
* This behavior test verifies DB-backed state derivation does not route a
|
|
10
|
+
* needs-remediation validation verdict into milestone completion.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { describe, test } from 'node:test';
|
|
14
14
|
import assert from 'node:assert/strict';
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
16
|
+
import { join } from 'node:path';
|
|
17
|
+
import { tmpdir } from 'node:os';
|
|
18
|
+
import {
|
|
19
|
+
closeDatabase,
|
|
20
|
+
insertAssessment,
|
|
21
|
+
insertMilestone,
|
|
22
|
+
insertSlice,
|
|
23
|
+
openDatabase,
|
|
24
|
+
} from '../gsd-db.ts';
|
|
25
|
+
import { deriveStateFromDb } from '../state.ts';
|
|
23
26
|
|
|
24
27
|
describe('needs-remediation revalidation guard (#3670)', () => {
|
|
25
|
-
test('
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
test('needs-remediation assessment blocks completion when every slice is done', async () => {
|
|
29
|
+
const base = mkdtempSync(join(tmpdir(), 'gsd-needs-remediation-'));
|
|
30
|
+
try {
|
|
31
|
+
openDatabase(':memory:');
|
|
32
|
+
insertMilestone({ id: 'M001', title: 'Needs remediation', status: 'active' });
|
|
33
|
+
insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Done slice', status: 'complete' });
|
|
34
|
+
insertAssessment({
|
|
35
|
+
path: join(base, '.gsd', 'milestones', 'M001', 'M001-VALIDATION.md'),
|
|
36
|
+
milestoneId: 'M001',
|
|
37
|
+
status: 'needs-remediation',
|
|
38
|
+
scope: 'milestone-validation',
|
|
39
|
+
fullContent: 'Verdict: needs-remediation',
|
|
40
|
+
});
|
|
31
41
|
|
|
32
|
-
|
|
33
|
-
assert.match(source, /needsRevalidation.*=.*verdict\s*===\s*['"]needs-remediation['"]/,
|
|
34
|
-
'needsRevalidation should incorporate verdict === "needs-remediation"');
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
test('deriveStateFromDb path uses needs-remediation guard', () => {
|
|
38
|
-
assert.match(source, /!validationTerminal\s*\|\|\s*verdict\s*===\s*['"]needs-remediation['"]/,
|
|
39
|
-
'deriveStateFromDb should check !validationTerminal || verdict === "needs-remediation"');
|
|
40
|
-
});
|
|
42
|
+
const state = await deriveStateFromDb(base);
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
assert.equal(state.phase, 'blocked');
|
|
45
|
+
assert.match(state.nextAction, /remediation/i);
|
|
46
|
+
assert.ok(
|
|
47
|
+
state.blockers.some((blocker) => blocker.includes('needs-remediation')),
|
|
48
|
+
'blocked state explains the remediation verdict',
|
|
49
|
+
);
|
|
50
|
+
} finally {
|
|
51
|
+
closeDatabase();
|
|
52
|
+
rmSync(base, { recursive: true, force: true });
|
|
53
|
+
}
|
|
47
54
|
});
|
|
48
55
|
});
|