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
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
* Structural tests for slice-level parallel orchestrator.
|
|
3
|
-
* Verifies the orchestrator module exists and has the correct shape,
|
|
4
|
-
* env var usage, and preference gating.
|
|
5
|
-
*/
|
|
1
|
+
// GSD-2 — Slice parallel orchestrator behavior tests.
|
|
6
2
|
|
|
7
3
|
import { describe, it } from "node:test";
|
|
8
4
|
import assert from "node:assert/strict";
|
|
9
5
|
import { execFileSync, spawn } from "node:child_process";
|
|
10
6
|
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
11
|
-
import { join
|
|
7
|
+
import { join } from "node:path";
|
|
12
8
|
import { tmpdir } from "node:os";
|
|
13
|
-
import { fileURLToPath } from "node:url";
|
|
14
|
-
import { restoreSliceState, SLICE_WORKER_AUTO_ARGS } from "../slice-parallel-orchestrator.ts";
|
|
15
9
|
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
import { deriveState } from "../state.js";
|
|
11
|
+
import { validatePreferences } from "../preferences-validation.ts";
|
|
12
|
+
import {
|
|
13
|
+
_buildSliceWorkerEnvForTest,
|
|
14
|
+
_resolveSliceParallelMaxWorkersForTest,
|
|
15
|
+
restoreSliceState,
|
|
16
|
+
SLICE_WORKER_AUTO_ARGS,
|
|
17
|
+
} from "../slice-parallel-orchestrator.ts";
|
|
18
18
|
|
|
19
19
|
function readLinuxProcessStartFingerprint(pid: number): string | null {
|
|
20
20
|
try {
|
|
@@ -83,81 +83,31 @@ function writeSliceOrchestratorState(
|
|
|
83
83
|
);
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
describe("slice
|
|
87
|
-
it("
|
|
88
|
-
|
|
89
|
-
assert.
|
|
90
|
-
source.includes("GSD_SLICE_LOCK"),
|
|
91
|
-
"Orchestrator must use GSD_SLICE_LOCK env var to isolate slice workers",
|
|
92
|
-
);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it("orchestrator sets GSD_PARALLEL_WORKER=1 to prevent nesting", () => {
|
|
96
|
-
const source = readFileSync(join(gsdDir, "slice-parallel-orchestrator.ts"), "utf-8");
|
|
97
|
-
assert.ok(
|
|
98
|
-
source.includes("GSD_PARALLEL_WORKER"),
|
|
99
|
-
"Orchestrator must set GSD_PARALLEL_WORKER to prevent nested parallel",
|
|
100
|
-
);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it("slice workers use headless auto instead of print-mode slash commands", () => {
|
|
104
|
-
const args: readonly string[] = SLICE_WORKER_AUTO_ARGS;
|
|
105
|
-
assert.deepEqual([...args], ["headless", "--json", "auto"]);
|
|
106
|
-
assert.equal(args.includes("--print"), false);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it("maxWorkers default is 2", () => {
|
|
110
|
-
const source = readFileSync(join(gsdDir, "slice-parallel-orchestrator.ts"), "utf-8");
|
|
111
|
-
// Check that default max workers is 2 (in opts.maxWorkers ?? 2 or similar)
|
|
112
|
-
assert.ok(
|
|
113
|
-
source.includes("maxWorkers") && source.includes("2"),
|
|
114
|
-
"Default maxWorkers should be 2",
|
|
115
|
-
);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it("orchestrator imports GSD_MILESTONE_LOCK for milestone isolation", () => {
|
|
119
|
-
const source = readFileSync(join(gsdDir, "slice-parallel-orchestrator.ts"), "utf-8");
|
|
120
|
-
assert.ok(
|
|
121
|
-
source.includes("GSD_MILESTONE_LOCK"),
|
|
122
|
-
"Orchestrator must also pass GSD_MILESTONE_LOCK for milestone context",
|
|
123
|
-
);
|
|
86
|
+
describe("slice worker launch contract", () => {
|
|
87
|
+
it("uses headless auto instead of print-mode slash commands", () => {
|
|
88
|
+
assert.deepEqual([...SLICE_WORKER_AUTO_ARGS], ["headless", "--json", "auto"]);
|
|
89
|
+
assert.equal(SLICE_WORKER_AUTO_ARGS.includes("--print" as never), false);
|
|
124
90
|
});
|
|
125
91
|
|
|
126
|
-
it("
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
"
|
|
92
|
+
it("builds isolated worker environment", () => {
|
|
93
|
+
const env = _buildSliceWorkerEnvForTest(
|
|
94
|
+
"/repo",
|
|
95
|
+
"M001",
|
|
96
|
+
"S02",
|
|
97
|
+
"worker-token",
|
|
98
|
+
{ PATH: "/bin" } as NodeJS.ProcessEnv,
|
|
132
99
|
);
|
|
133
|
-
});
|
|
134
100
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
assert.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
"stopSliceParallel must validate recovered worker identity before signaling a PID",
|
|
141
|
-
);
|
|
101
|
+
assert.equal(env.GSD_SLICE_LOCK, "S02");
|
|
102
|
+
assert.equal(env.GSD_MILESTONE_LOCK, "M001");
|
|
103
|
+
assert.equal(env.GSD_PROJECT_ROOT, "/repo");
|
|
104
|
+
assert.equal(env.GSD_PARALLEL_WORKER, "1");
|
|
105
|
+
assert.equal(env.GSD_SLICE_WORKER_TOKEN, "worker-token");
|
|
142
106
|
});
|
|
143
107
|
|
|
144
|
-
it("
|
|
145
|
-
|
|
146
|
-
assert.
|
|
147
|
-
source.includes("workerToken") &&
|
|
148
|
-
source.includes("processStartFingerprint") &&
|
|
149
|
-
source.includes("GSD_SLICE_WORKER_TOKEN"),
|
|
150
|
-
"Orchestrator must persist stable worker identity metadata for recovered workers",
|
|
151
|
-
);
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
it("spawn failures remove stale worker state and worktree", () => {
|
|
155
|
-
const source = readFileSync(join(gsdDir, "slice-parallel-orchestrator.ts"), "utf-8");
|
|
156
|
-
assert.ok(
|
|
157
|
-
source.includes("sliceState.workers.delete(slice.id)") &&
|
|
158
|
-
source.includes("removeWorktree(basePath, wtName, { deleteBranch: true, force: true })"),
|
|
159
|
-
"Failed slice worker spawns must remove stale worker state and clean up the worktree",
|
|
160
|
-
);
|
|
108
|
+
it("defaults to two workers unless explicitly configured", () => {
|
|
109
|
+
assert.equal(_resolveSliceParallelMaxWorkersForTest(), 2);
|
|
110
|
+
assert.equal(_resolveSliceParallelMaxWorkersForTest(4), 4);
|
|
161
111
|
});
|
|
162
112
|
});
|
|
163
113
|
|
|
@@ -217,36 +167,47 @@ describe("slice-parallel-orchestrator recovery identity", () => {
|
|
|
217
167
|
});
|
|
218
168
|
});
|
|
219
169
|
|
|
220
|
-
describe("slice_parallel preference gating", () => {
|
|
221
|
-
it("
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
assert.ok(
|
|
232
|
-
source.includes('"slice_parallel"'),
|
|
233
|
-
'KNOWN_PREFERENCE_KEYS should include "slice_parallel"',
|
|
234
|
-
);
|
|
170
|
+
describe("slice_parallel preference and state gating", () => {
|
|
171
|
+
it("validates slice_parallel preferences", () => {
|
|
172
|
+
const result = validatePreferences({
|
|
173
|
+
slice_parallel: { enabled: true, max_workers: 3 },
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
assert.equal(result.errors.length, 0);
|
|
177
|
+
assert.deepEqual(result.preferences.slice_parallel, {
|
|
178
|
+
enabled: true,
|
|
179
|
+
max_workers: 3,
|
|
180
|
+
});
|
|
235
181
|
});
|
|
236
182
|
|
|
237
|
-
it("
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
183
|
+
it("derives the locked slice for parallel workers", async () => {
|
|
184
|
+
const basePath = makeTempProject();
|
|
185
|
+
const oldWorker = process.env.GSD_PARALLEL_WORKER;
|
|
186
|
+
const oldSlice = process.env.GSD_SLICE_LOCK;
|
|
187
|
+
try {
|
|
188
|
+
const msDir = join(basePath, ".gsd", "milestones", "M001");
|
|
189
|
+
mkdirSync(msDir, { recursive: true });
|
|
190
|
+
writeFileSync(
|
|
191
|
+
join(msDir, "M001-ROADMAP.md"),
|
|
192
|
+
[
|
|
193
|
+
"# M001",
|
|
194
|
+
"",
|
|
195
|
+
"## Slices",
|
|
196
|
+
"- [ ] **S01: First** `risk:low` `depends:[]`",
|
|
197
|
+
"- [ ] **S02: Second** `risk:low` `depends:[]`",
|
|
198
|
+
].join("\n"),
|
|
199
|
+
);
|
|
200
|
+
process.env.GSD_PARALLEL_WORKER = "1";
|
|
201
|
+
process.env.GSD_SLICE_LOCK = "S02";
|
|
244
202
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
203
|
+
const state = await deriveState(basePath);
|
|
204
|
+
assert.equal(state.activeSlice?.id, "S02");
|
|
205
|
+
} finally {
|
|
206
|
+
if (oldWorker === undefined) delete process.env.GSD_PARALLEL_WORKER;
|
|
207
|
+
else process.env.GSD_PARALLEL_WORKER = oldWorker;
|
|
208
|
+
if (oldSlice === undefined) delete process.env.GSD_SLICE_LOCK;
|
|
209
|
+
else process.env.GSD_SLICE_LOCK = oldSlice;
|
|
210
|
+
rmSync(basePath, { recursive: true, force: true });
|
|
211
|
+
}
|
|
251
212
|
});
|
|
252
213
|
});
|
|
@@ -1,51 +1,124 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Regression test for #3697 — set slice sequence on insert
|
|
3
|
-
*
|
|
4
|
-
* All three insertSlice call sites must pass a sequence value so slices
|
|
5
|
-
* are ordered correctly instead of defaulting to 0.
|
|
2
|
+
* Regression test for #3697 — set slice sequence on insert.
|
|
6
3
|
*/
|
|
7
4
|
|
|
8
|
-
import { describe, test } from
|
|
9
|
-
import assert from
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
5
|
+
import { describe, test, afterEach } from "node:test";
|
|
6
|
+
import assert from "node:assert/strict";
|
|
7
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { tmpdir } from "node:os";
|
|
10
|
+
|
|
11
|
+
import { handlePlanMilestone } from "../tools/plan-milestone.ts";
|
|
12
|
+
import { handleReassessRoadmap } from "../tools/reassess-roadmap.ts";
|
|
13
|
+
import { migrateHierarchyToDb } from "../md-importer.ts";
|
|
14
|
+
import {
|
|
15
|
+
closeDatabase,
|
|
16
|
+
getMilestoneSlices,
|
|
17
|
+
insertMilestone,
|
|
18
|
+
insertSlice,
|
|
19
|
+
openDatabase,
|
|
20
|
+
} from "../gsd-db.ts";
|
|
21
|
+
|
|
22
|
+
let tempBase: string | null = null;
|
|
23
|
+
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
closeDatabase();
|
|
26
|
+
if (tempBase) rmSync(tempBase, { recursive: true, force: true });
|
|
27
|
+
tempBase = null;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
function makeBase(name: string): string {
|
|
31
|
+
tempBase = mkdtempSync(join(tmpdir(), name));
|
|
32
|
+
mkdirSync(join(tempBase, ".gsd", "milestones"), { recursive: true });
|
|
33
|
+
openDatabase(join(tempBase, ".gsd", "gsd.db"));
|
|
34
|
+
return tempBase;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function slice(sliceId: string, title: string) {
|
|
38
|
+
return {
|
|
39
|
+
sliceId,
|
|
40
|
+
title,
|
|
41
|
+
risk: "low",
|
|
42
|
+
depends: [],
|
|
43
|
+
demo: `${title} demo`,
|
|
44
|
+
goal: `${title} goal`,
|
|
45
|
+
successCriteria: `${title} success`,
|
|
46
|
+
proofLevel: "unit",
|
|
47
|
+
integrationClosure: "covered",
|
|
48
|
+
observabilityImpact: "none",
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
describe("slice sequence on insert (#3697)", () => {
|
|
53
|
+
test("plan milestone persists slices in agent-provided order", async () => {
|
|
54
|
+
const base = makeBase("gsd-sequence-plan-");
|
|
55
|
+
|
|
56
|
+
const result = await handlePlanMilestone({
|
|
57
|
+
milestoneId: "M001",
|
|
58
|
+
title: "Sequence",
|
|
59
|
+
vision: "Preserve slice order",
|
|
60
|
+
slices: [slice("S01", "First"), slice("S02", "Second"), slice("S03", "Third")],
|
|
61
|
+
}, base);
|
|
62
|
+
|
|
63
|
+
assert.ok(!("error" in result), JSON.stringify(result));
|
|
64
|
+
assert.deepEqual(
|
|
65
|
+
getMilestoneSlices("M001").map((row) => [row.id, row.sequence]),
|
|
66
|
+
[["S01", 1], ["S02", 2], ["S03", 3]],
|
|
67
|
+
);
|
|
36
68
|
});
|
|
37
69
|
|
|
38
|
-
test(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
70
|
+
test("reassess roadmap appends new slices after existing slices", async () => {
|
|
71
|
+
const base = makeBase("gsd-sequence-reassess-");
|
|
72
|
+
insertMilestone({ id: "M001", title: "Sequence", status: "active", depends_on: [] });
|
|
73
|
+
insertSlice({ id: "S01", milestoneId: "M001", title: "Done", status: "complete", risk: "low", depends: [], demo: "", sequence: 1 });
|
|
74
|
+
insertSlice({ id: "S02", milestoneId: "M001", title: "Existing", status: "pending", risk: "low", depends: [], demo: "", sequence: 2 });
|
|
75
|
+
|
|
76
|
+
const result = await handleReassessRoadmap({
|
|
77
|
+
milestoneId: "M001",
|
|
78
|
+
completedSliceId: "S01",
|
|
79
|
+
verdict: "pass",
|
|
80
|
+
assessment: "Add follow-up slices.",
|
|
81
|
+
sliceChanges: {
|
|
82
|
+
modified: [],
|
|
83
|
+
added: [
|
|
84
|
+
{ sliceId: "S03", title: "Added 1", risk: "low", depends: [], demo: "" },
|
|
85
|
+
{ sliceId: "S04", title: "Added 2", risk: "low", depends: [], demo: "" },
|
|
86
|
+
],
|
|
87
|
+
removed: [],
|
|
88
|
+
},
|
|
89
|
+
}, base);
|
|
90
|
+
|
|
91
|
+
assert.ok(!("error" in result), JSON.stringify(result));
|
|
92
|
+
assert.deepEqual(
|
|
93
|
+
getMilestoneSlices("M001").map((row) => [row.id, row.sequence]),
|
|
94
|
+
[["S01", 1], ["S02", 2], ["S03", 3], ["S04", 4]],
|
|
95
|
+
);
|
|
43
96
|
});
|
|
44
97
|
|
|
45
|
-
test(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
98
|
+
test("markdown importer preserves roadmap order in sequence values", () => {
|
|
99
|
+
const base = makeBase("gsd-sequence-import-");
|
|
100
|
+
const milestoneDir = join(base, ".gsd", "milestones", "M001");
|
|
101
|
+
mkdirSync(milestoneDir, { recursive: true });
|
|
102
|
+
writeFileSync(
|
|
103
|
+
join(milestoneDir, "M001-ROADMAP.md"),
|
|
104
|
+
[
|
|
105
|
+
"# M001: Imported",
|
|
106
|
+
"",
|
|
107
|
+
"## Slices",
|
|
108
|
+
"- [ ] **S01: First** `risk:low`",
|
|
109
|
+
" Demo: first.",
|
|
110
|
+
"- [ ] **S02: Second** `risk:low`",
|
|
111
|
+
" Demo: second.",
|
|
112
|
+
].join("\n"),
|
|
113
|
+
"utf-8",
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
const result = migrateHierarchyToDb(base);
|
|
117
|
+
|
|
118
|
+
assert.equal(result.slices, 2);
|
|
119
|
+
assert.deepEqual(
|
|
120
|
+
getMilestoneSlices("M001").map((row) => [row.id, row.sequence]),
|
|
121
|
+
[["S01", 1], ["S02", 2]],
|
|
122
|
+
);
|
|
50
123
|
});
|
|
51
124
|
});
|
|
@@ -1,34 +1,33 @@
|
|
|
1
|
+
// GSD-2 — Guided smart entry complete-state behavior tests.
|
|
2
|
+
|
|
1
3
|
import test from "node:test";
|
|
2
4
|
import assert from "node:assert/strict";
|
|
3
|
-
import { mkdtempSync, mkdirSync, rmSync, writeFileSync
|
|
5
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
4
6
|
import { join } from "node:path";
|
|
5
7
|
import { tmpdir } from "node:os";
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
import { deriveState } from "../state.js";
|
|
10
|
+
|
|
11
|
+
function writeCompleteMilestone(base: string): void {
|
|
12
|
+
const milestoneDir = join(base, ".gsd", "milestones", "M001");
|
|
13
|
+
mkdirSync(milestoneDir, { recursive: true });
|
|
14
|
+
writeFileSync(
|
|
15
|
+
join(milestoneDir, "M001-ROADMAP.md"),
|
|
16
|
+
[
|
|
17
|
+
"# M001: Complete Milestone",
|
|
18
|
+
"",
|
|
19
|
+
"## Slices",
|
|
20
|
+
"- [x] **S01: Done slice** `risk:low` `depends:[]`",
|
|
21
|
+
" > Done.",
|
|
22
|
+
].join("\n"),
|
|
23
|
+
);
|
|
24
|
+
writeFileSync(join(milestoneDir, "M001-SUMMARY.md"), "# M001 Summary\n\nComplete.");
|
|
25
|
+
}
|
|
8
26
|
|
|
9
27
|
test("deriveState reports the last completed milestone when all milestone slices are done", async () => {
|
|
10
28
|
const base = mkdtempSync(join(tmpdir(), "gsd-smart-entry-complete-"));
|
|
11
|
-
|
|
12
29
|
try {
|
|
13
|
-
|
|
14
|
-
mkdirSync(milestoneDir, { recursive: true });
|
|
15
|
-
|
|
16
|
-
writeFileSync(
|
|
17
|
-
join(milestoneDir, "M001-ROADMAP.md"),
|
|
18
|
-
[
|
|
19
|
-
"# M001: Complete Milestone",
|
|
20
|
-
"",
|
|
21
|
-
"## Slices",
|
|
22
|
-
"- [x] **S01: Done slice** `risk:low` `depends:[]`",
|
|
23
|
-
" > Done.",
|
|
24
|
-
].join("\n"),
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
writeFileSync(
|
|
28
|
-
join(milestoneDir, "M001-SUMMARY.md"),
|
|
29
|
-
"# M001 Summary\n\nComplete.",
|
|
30
|
-
);
|
|
31
|
-
|
|
30
|
+
writeCompleteMilestone(base);
|
|
32
31
|
const state = await deriveState(base);
|
|
33
32
|
assert.equal(state.phase, "complete");
|
|
34
33
|
assert.equal(state.lastCompletedMilestone?.id, "M001");
|
|
@@ -36,78 +35,3 @@ test("deriveState reports the last completed milestone when all milestone slices
|
|
|
36
35
|
rmSync(base, { recursive: true, force: true });
|
|
37
36
|
}
|
|
38
37
|
});
|
|
39
|
-
|
|
40
|
-
test("guided-flow complete branch offers a chooser for next milestone or status", () => {
|
|
41
|
-
const guidedFlowSource = readFileSync(join(import.meta.dirname, "..", "guided-flow.ts"), "utf-8");
|
|
42
|
-
const branchIdx = guidedFlowSource.indexOf('state.phase === "complete"');
|
|
43
|
-
|
|
44
|
-
assert.ok(branchIdx > -1, "guided-flow.ts should have a complete-phase smart-entry branch");
|
|
45
|
-
|
|
46
|
-
const nextBranchIdx = guidedFlowSource.indexOf('state.phase === "needs-discussion"', branchIdx);
|
|
47
|
-
const branchChunk = guidedFlowSource.slice(branchIdx, nextBranchIdx === -1 ? branchIdx + 1600 : nextBranchIdx);
|
|
48
|
-
|
|
49
|
-
assert.match(branchChunk, /showNextAction\(/, "complete branch should present a chooser");
|
|
50
|
-
assert.match(branchChunk, /id:\s*"quick_task"/, "complete branch should offer quick task before milestone planning");
|
|
51
|
-
assert.match(branchChunk, /Do a small bounded task without opening a milestone/, "quick task action should explain that it avoids milestones");
|
|
52
|
-
assert.match(branchChunk, /recommended:\s*true/, "quick task action should be the recommended complete-state action");
|
|
53
|
-
assert.match(branchChunk, /findMilestoneIds\(basePath\)/, "complete branch should compute the next milestone id");
|
|
54
|
-
assert.match(
|
|
55
|
-
branchChunk,
|
|
56
|
-
/nextMilestoneIdReserved\(milestoneIds,\s*uniqueMilestoneIds,\s*basePath\)/,
|
|
57
|
-
"complete branch should derive the next milestone id",
|
|
58
|
-
);
|
|
59
|
-
assert.match(branchChunk, /dispatchWorkflow\(pi, await prepareAndBuildDiscussPrompt\(/, "complete branch should dispatch the prepared discuss prompt");
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
test("guided-flow quick task choices prompt for text and route through /gsd quick", () => {
|
|
63
|
-
const guidedFlowSource = readFileSync(join(import.meta.dirname, "..", "guided-flow.ts"), "utf-8");
|
|
64
|
-
|
|
65
|
-
assert.match(
|
|
66
|
-
guidedFlowSource,
|
|
67
|
-
/async function runQuickTaskChoice\([\s\S]*ctx\.ui\.input\("Quick task"[\s\S]*await import\("\.\/quick\.js"\)[\s\S]*await handleQuick\(task,\s*ctx,\s*pi\)/,
|
|
68
|
-
"quick task chooser should prompt for task text and route through handleQuick",
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
const notifyOnlyPattern = /if \(choice === "quick_task"\) \{\s*ctx\.ui\.notify\("Run \/gsd quick <task>/;
|
|
72
|
-
assert.doesNotMatch(
|
|
73
|
-
guidedFlowSource,
|
|
74
|
-
notifyOnlyPattern,
|
|
75
|
-
"quick task chooser must not merely print instructions after selection",
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
const quickChoiceCalls = guidedFlowSource.match(/if \(choice === "quick_task"\) \{\s*await runQuickTaskChoice\(ctx,\s*pi\);/g) ?? [];
|
|
79
|
-
assert.equal(quickChoiceCalls.length, 3, "all guided-flow quick task choices should dispatch the helper");
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
test("dispatcher routes multi-word freeform /gsd input through /gsd do", () => {
|
|
83
|
-
const dispatcherSource = readFileSync(join(import.meta.dirname, "..", "commands", "dispatcher.ts"), "utf-8");
|
|
84
|
-
|
|
85
|
-
assert.match(
|
|
86
|
-
dispatcherSource,
|
|
87
|
-
/if\s*\(trimmed\.includes\(" "\)\)\s*\{[\s\S]*handleDo\(trimmed,\s*ctx,\s*pi\)/,
|
|
88
|
-
"dispatcher should treat multi-word unknown input as natural-language /gsd do work",
|
|
89
|
-
);
|
|
90
|
-
assert.match(
|
|
91
|
-
dispatcherSource,
|
|
92
|
-
/Unknown: \/gsd/,
|
|
93
|
-
"single-token unknown commands should still report the normal unknown-command warning",
|
|
94
|
-
);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
test("guided-flow needs-discussion skip branch opens the project DB before reserving a new milestone", () => {
|
|
98
|
-
const guidedFlowSource = readFileSync(join(import.meta.dirname, "..", "guided-flow.ts"), "utf-8");
|
|
99
|
-
const laterDbOpenIdx = guidedFlowSource.indexOf("// Ensure DB is open before querying slices (#2560).");
|
|
100
|
-
assert.ok(laterDbOpenIdx > -1, "guided-flow.ts should contain the post-draft DB-open guard");
|
|
101
|
-
|
|
102
|
-
const branchPrefix = guidedFlowSource.slice(0, laterDbOpenIdx);
|
|
103
|
-
const skipBranchIdx = branchPrefix.lastIndexOf('choice === "skip_milestone"');
|
|
104
|
-
assert.ok(skipBranchIdx > -1, "needs-discussion skip branch should be present");
|
|
105
|
-
|
|
106
|
-
const branchChunk = branchPrefix.slice(skipBranchIdx);
|
|
107
|
-
const ensureIdx = branchChunk.indexOf("ensureDbOpen(basePath)");
|
|
108
|
-
const reserveIdx = branchChunk.indexOf("nextMilestoneIdReserved");
|
|
109
|
-
|
|
110
|
-
assert.ok(ensureIdx > -1, "skip branch should open the project DB");
|
|
111
|
-
assert.ok(reserveIdx > -1, "skip branch should reserve the next milestone ID");
|
|
112
|
-
assert.ok(ensureIdx < reserveIdx, "project DB must be opened before milestone ID reservation");
|
|
113
|
-
});
|
|
@@ -1,124 +1,33 @@
|
|
|
1
|
-
|
|
1
|
+
// GSD-2 — Guided smart entry draft-state behavior tests.
|
|
2
|
+
|
|
3
|
+
import test from "node:test";
|
|
4
|
+
import assert from "node:assert/strict";
|
|
5
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
2
6
|
import { join } from "node:path";
|
|
3
7
|
import { tmpdir } from "node:os";
|
|
4
8
|
|
|
5
9
|
import { deriveState } from "../state.js";
|
|
6
10
|
import { resolveMilestoneFile } from "../paths.js";
|
|
7
|
-
import { extractSourceRegion } from "./test-helpers.ts";
|
|
8
|
-
|
|
9
|
-
let passed = 0;
|
|
10
|
-
let failed = 0;
|
|
11
11
|
|
|
12
|
-
function
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
function writeDraftOnlyMilestone(base: string): void {
|
|
13
|
+
const milestoneDir = join(base, ".gsd", "milestones", "M001");
|
|
14
|
+
mkdirSync(milestoneDir, { recursive: true });
|
|
15
|
+
writeFileSync(
|
|
16
|
+
join(milestoneDir, "M001-CONTEXT-DRAFT.md"),
|
|
17
|
+
"# M001: Test Milestone\n\n**Status:** Draft\n\nSeed material.\n",
|
|
18
|
+
);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// ─── Test: deriveState returns 'needs-discussion' for draft-only milestone ───
|
|
35
|
-
|
|
36
|
-
const state = await deriveState(tmpBase);
|
|
37
|
-
|
|
38
|
-
assert(
|
|
39
|
-
state.phase === "needs-discussion",
|
|
40
|
-
`phase should be 'needs-discussion' for draft-only milestone, got: "${state.phase}"`,
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
assert(
|
|
44
|
-
state.activeMilestone?.id === "M001",
|
|
45
|
-
`active milestone should be M001, got: "${state.activeMilestone?.id}"`,
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
// ─── Test: resolveMilestoneFile resolves CONTEXT-DRAFT ─────────────────────
|
|
49
|
-
|
|
50
|
-
const draftFile = resolveMilestoneFile(tmpBase, "M001", "CONTEXT-DRAFT");
|
|
51
|
-
|
|
52
|
-
assert(
|
|
53
|
-
draftFile !== null && draftFile !== undefined,
|
|
54
|
-
`resolveMilestoneFile should resolve CONTEXT-DRAFT, got: ${draftFile}`,
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
assert(
|
|
58
|
-
draftFile!.endsWith("M001-CONTEXT-DRAFT.md"),
|
|
59
|
-
`resolved path should end with M001-CONTEXT-DRAFT.md, got: "${draftFile}"`,
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
// ─── Test: CONTEXT.md is NOT resolved (only draft exists) ──────────────────
|
|
63
|
-
|
|
64
|
-
const contextFile = resolveMilestoneFile(tmpBase, "M001", "CONTEXT");
|
|
65
|
-
|
|
66
|
-
assert(
|
|
67
|
-
contextFile === null || contextFile === undefined,
|
|
68
|
-
`resolveMilestoneFile should NOT resolve CONTEXT when only CONTEXT-DRAFT exists, got: "${contextFile}"`,
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
// ─── Static: guided-flow.ts has 'needs-discussion' branch ─────────────────
|
|
72
|
-
|
|
73
|
-
const guidedFlowSource = readFileSync(
|
|
74
|
-
join(import.meta.dirname, "..", "guided-flow.ts"),
|
|
75
|
-
"utf-8",
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
assert(
|
|
79
|
-
guidedFlowSource.includes('state.phase === "needs-discussion"'),
|
|
80
|
-
"guided-flow.ts should have 'needs-discussion' phase check in showSmartEntry",
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
// Check the branch has draft-aware menu options
|
|
84
|
-
const branchIdx = guidedFlowSource.indexOf('state.phase === "needs-discussion"');
|
|
85
|
-
const branchChunk = extractSourceRegion(guidedFlowSource, 'state.phase === "needs-discussion"');
|
|
86
|
-
|
|
87
|
-
assert(
|
|
88
|
-
branchChunk.includes("discuss_draft"),
|
|
89
|
-
"needs-discussion branch should have 'discuss_draft' option",
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
assert(
|
|
93
|
-
branchChunk.includes("discuss_fresh"),
|
|
94
|
-
"needs-discussion branch should have 'discuss_fresh' option",
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
assert(
|
|
98
|
-
branchChunk.includes("skip_milestone"),
|
|
99
|
-
"needs-discussion branch should have 'skip_milestone' option",
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
assert(
|
|
103
|
-
branchChunk.includes("CONTEXT-DRAFT"),
|
|
104
|
-
"needs-discussion branch should load CONTEXT-DRAFT via resolveMilestoneFile",
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
assert(
|
|
108
|
-
branchChunk.includes("Draft Seed") || branchChunk.includes("draftContent"),
|
|
109
|
-
"discuss_draft path should include draft content as seed in the dispatched prompt",
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
assert(
|
|
113
|
-
branchChunk.includes("return"),
|
|
114
|
-
"needs-discussion branch should return early (not fall through to generic no-roadmap menu)",
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
// ─── Cleanup ──────────────────────────────────────────────────────────────
|
|
118
|
-
|
|
119
|
-
rmSync(tmpBase, { recursive: true, force: true });
|
|
120
|
-
|
|
121
|
-
// ─── Results ──────────────────────────────────────────────────────────────
|
|
122
|
-
|
|
123
|
-
console.log(`\nsmart-entry-draft: ${passed} passed, ${failed} failed`);
|
|
124
|
-
if (failed > 0) process.exit(1);
|
|
21
|
+
test("deriveState returns needs-discussion for draft-only milestone", async () => {
|
|
22
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-smart-entry-draft-"));
|
|
23
|
+
try {
|
|
24
|
+
writeDraftOnlyMilestone(base);
|
|
25
|
+
const state = await deriveState(base);
|
|
26
|
+
assert.equal(state.phase, "needs-discussion");
|
|
27
|
+
assert.equal(state.activeMilestone?.id, "M001");
|
|
28
|
+
assert.match(resolveMilestoneFile(base, "M001", "CONTEXT-DRAFT") ?? "", /M001-CONTEXT-DRAFT\.md$/);
|
|
29
|
+
assert.equal(resolveMilestoneFile(base, "M001", "CONTEXT"), null);
|
|
30
|
+
} finally {
|
|
31
|
+
rmSync(base, { recursive: true, force: true });
|
|
32
|
+
}
|
|
33
|
+
});
|