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,24 +1,31 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import {
|
|
4
|
-
import { dirname, join } from "node:path";
|
|
5
|
-
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { getStoredToolKey } from "../commands-config.ts";
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
const
|
|
5
|
+
test("stored tool key lookup skips empty api_key entries", () => {
|
|
6
|
+
const auth = {
|
|
7
|
+
getCredentialsForProvider(providerId: string) {
|
|
8
|
+
assert.equal(providerId, "tavily");
|
|
9
|
+
return [
|
|
10
|
+
{ type: "api_key", key: "" },
|
|
11
|
+
{ type: "oauth", accessToken: "oauth-token" },
|
|
12
|
+
{ type: "api_key", key: "tool-key" },
|
|
13
|
+
];
|
|
14
|
+
},
|
|
15
|
+
};
|
|
9
16
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
);
|
|
17
|
+
assert.equal(getStoredToolKey(auth as any, "tavily"), "tool-key");
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("stored tool key lookup returns undefined when only shadowing credentials exist", () => {
|
|
21
|
+
const auth = {
|
|
22
|
+
getCredentialsForProvider() {
|
|
23
|
+
return [
|
|
24
|
+
{ type: "api_key", key: "" },
|
|
25
|
+
{ type: "oauth", accessToken: "oauth-token" },
|
|
26
|
+
];
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
assert.equal(getStoredToolKey(auth as any, "brave"), undefined);
|
|
24
31
|
});
|
|
@@ -547,4 +547,144 @@ describe("complete-milestone", () => {
|
|
|
547
547
|
cleanup(base);
|
|
548
548
|
}
|
|
549
549
|
});
|
|
550
|
+
|
|
551
|
+
test("verification-gate step numbers match the actual numbered verification steps", () => {
|
|
552
|
+
// Regression for step-number drift: step 1 (duplicate guard) was inserted
|
|
553
|
+
// in ea5a2cc0 and the rest renumbered, but the gate text was not updated.
|
|
554
|
+
// Re-derive the verification-step indices from the rendered prompt and
|
|
555
|
+
// assert the gate / "Important" footer reference the correct numbers.
|
|
556
|
+
const prompt = loadPromptFromWorktree("complete-milestone", {
|
|
557
|
+
workingDirectory: "/tmp/test-project",
|
|
558
|
+
milestoneId: "M001",
|
|
559
|
+
milestoneTitle: "Step Number Drift",
|
|
560
|
+
roadmapPath: ".gsd/milestones/M001/M001-ROADMAP.md",
|
|
561
|
+
inlinedContext: "context",
|
|
562
|
+
milestoneSummaryPath: ".gsd/milestones/M001/M001-SUMMARY.md",
|
|
563
|
+
skillActivation: "{{skillActivation block}}",
|
|
564
|
+
extractLearningsSteps: "{{extract learnings block}}",
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
function findStep(needle: RegExp): number {
|
|
568
|
+
const lines = prompt.split("\n");
|
|
569
|
+
for (const line of lines) {
|
|
570
|
+
const m = /^(\d+)\.\s/.exec(line);
|
|
571
|
+
if (m && needle.test(line)) return Number(m[1]);
|
|
572
|
+
}
|
|
573
|
+
throw new Error(`no numbered step matches ${needle}`);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
const codeChange = findStep(/Verify code changes/);
|
|
577
|
+
const successCriteria = findStep(/Verify every \*\*success criterion\*\*/);
|
|
578
|
+
const defOfDone = findStep(/Verify \*\*definition of done\*\*/);
|
|
579
|
+
const completeMilestone = findStep(/Persist completion through `gsd_complete_milestone`/);
|
|
580
|
+
const requirementUpdate = findStep(/gsd_requirement_update/);
|
|
581
|
+
|
|
582
|
+
// Gate clause references the verification steps.
|
|
583
|
+
const gateLine = prompt.split("\n").find(l => l.includes("Verification failure was recorded") || l.includes("verification failure was recorded"));
|
|
584
|
+
assert.ok(gateLine, "verification gate sentence is present");
|
|
585
|
+
assert.ok(
|
|
586
|
+
gateLine!.includes(`steps ${codeChange}, ${successCriteria}, or ${defOfDone}`),
|
|
587
|
+
`gate must cite verification steps ${codeChange}, ${successCriteria}, ${defOfDone}; got: ${gateLine}`,
|
|
588
|
+
);
|
|
589
|
+
// "Do NOT proceed with steps X-Y" — Y must be at least the gsd_complete_milestone step.
|
|
590
|
+
const proceedMatch = /Do NOT proceed with steps (\d+)[–-](\d+)/.exec(gateLine!);
|
|
591
|
+
assert.ok(proceedMatch, "gate must include a 'Do NOT proceed with steps X–Y' clause");
|
|
592
|
+
assert.ok(
|
|
593
|
+
Number(proceedMatch![1]) > requirementUpdate - 1 && Number(proceedMatch![2]) >= completeMilestone,
|
|
594
|
+
`'Do NOT proceed' range ${proceedMatch![1]}–${proceedMatch![2]} must cover steps from after the gate through gsd_complete_milestone (${completeMilestone})`,
|
|
595
|
+
);
|
|
596
|
+
|
|
597
|
+
// "Important" footer references the same verification steps.
|
|
598
|
+
const importantLine = prompt.split("\n").find(l => l.includes("Do NOT skip code-change"));
|
|
599
|
+
assert.ok(importantLine, "Important footer is present");
|
|
600
|
+
assert.ok(
|
|
601
|
+
importantLine!.includes(`steps ${codeChange}-${defOfDone}`) ||
|
|
602
|
+
importantLine!.includes(`steps ${codeChange}–${defOfDone}`),
|
|
603
|
+
`Important footer must cite verification range ${codeChange}-${defOfDone}; got: ${importantLine}`,
|
|
604
|
+
);
|
|
605
|
+
|
|
606
|
+
// On-demand Read ordering line cites the gsd_complete_milestone step.
|
|
607
|
+
const readOrderLine = prompt.split("\n").find(l => l.includes("On-demand Read ordering"));
|
|
608
|
+
assert.ok(readOrderLine, "On-demand Read ordering line is present");
|
|
609
|
+
assert.ok(
|
|
610
|
+
readOrderLine!.includes(`(step ${completeMilestone})`),
|
|
611
|
+
`On-demand Read ordering must cite step ${completeMilestone}; got: ${readOrderLine}`,
|
|
612
|
+
);
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
test("sanitizeCompleteMilestoneParams preserves actorName and triggerReason", async () => {
|
|
616
|
+
const { sanitizeCompleteMilestoneParams } = await import("../bootstrap/sanitize-complete-milestone.ts");
|
|
617
|
+
|
|
618
|
+
const sanitized = sanitizeCompleteMilestoneParams({
|
|
619
|
+
milestoneId: "M001",
|
|
620
|
+
title: "T",
|
|
621
|
+
oneLiner: "x",
|
|
622
|
+
narrative: "n",
|
|
623
|
+
verificationPassed: true,
|
|
624
|
+
actorName: " executor-01 ",
|
|
625
|
+
triggerReason: " milestone validation passed ",
|
|
626
|
+
} as any);
|
|
627
|
+
|
|
628
|
+
assert.strictEqual(sanitized.actorName, "executor-01");
|
|
629
|
+
assert.strictEqual(sanitized.triggerReason, "milestone validation passed");
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
test("sanitizeCompleteMilestoneParams omits blank actorName/triggerReason rather than emitting empty strings", async () => {
|
|
633
|
+
const { sanitizeCompleteMilestoneParams } = await import("../bootstrap/sanitize-complete-milestone.ts");
|
|
634
|
+
|
|
635
|
+
const sanitized = sanitizeCompleteMilestoneParams({
|
|
636
|
+
milestoneId: "M001",
|
|
637
|
+
title: "T",
|
|
638
|
+
oneLiner: "x",
|
|
639
|
+
narrative: "n",
|
|
640
|
+
verificationPassed: true,
|
|
641
|
+
// actorName/triggerReason omitted
|
|
642
|
+
} as any);
|
|
643
|
+
|
|
644
|
+
assert.strictEqual(sanitized.actorName, undefined);
|
|
645
|
+
assert.strictEqual(sanitized.triggerReason, undefined);
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
test("rendered SUMMARY.md uses placeholder text for empty enrichment fields", async () => {
|
|
649
|
+
const { handleCompleteMilestone } = await import("../tools/complete-milestone.ts");
|
|
650
|
+
const base = createFixtureBase();
|
|
651
|
+
const mid = "M001";
|
|
652
|
+
const dbPath = join(base, ".gsd", "gsd.db");
|
|
653
|
+
try {
|
|
654
|
+
openDatabase(dbPath);
|
|
655
|
+
insertMilestone({ id: mid, title: "Empty Enrichment", status: "active" });
|
|
656
|
+
insertSlice({ id: "S01", milestoneId: mid, title: "Slice", status: "complete" });
|
|
657
|
+
insertTask({ id: "T01", sliceId: "S01", milestoneId: mid, title: "Task", status: "complete" });
|
|
658
|
+
|
|
659
|
+
const result = await handleCompleteMilestone({
|
|
660
|
+
milestoneId: mid,
|
|
661
|
+
title: "Empty Enrichment",
|
|
662
|
+
oneLiner: "no enrichment",
|
|
663
|
+
narrative: "did the thing",
|
|
664
|
+
// enrichment fields intentionally empty (post-sanitizer state)
|
|
665
|
+
successCriteriaResults: "",
|
|
666
|
+
definitionOfDoneResults: "",
|
|
667
|
+
requirementOutcomes: "",
|
|
668
|
+
keyDecisions: [],
|
|
669
|
+
keyFiles: [],
|
|
670
|
+
lessonsLearned: [],
|
|
671
|
+
followUps: "",
|
|
672
|
+
deviations: "",
|
|
673
|
+
verificationPassed: true,
|
|
674
|
+
}, base);
|
|
675
|
+
|
|
676
|
+
assert.ok(!("error" in result), `handler should succeed: ${JSON.stringify(result)}`);
|
|
677
|
+
const summary = readFileSync((result as { summaryPath: string }).summaryPath, "utf-8");
|
|
678
|
+
assert.match(summary, /## Success Criteria Results\n\nNot provided\./);
|
|
679
|
+
assert.match(summary, /## Definition of Done Results\n\nNot provided\./);
|
|
680
|
+
assert.match(summary, /## Requirement Outcomes\n\nNot provided\./);
|
|
681
|
+
assert.match(summary, /## Deviations\n\nNone\./);
|
|
682
|
+
assert.match(summary, /## Follow-ups\n\nNone\./);
|
|
683
|
+
} finally {
|
|
684
|
+
try { closeDatabase(); } catch { /* */ }
|
|
685
|
+
clearPathCache();
|
|
686
|
+
clearParseCache();
|
|
687
|
+
cleanup(base);
|
|
688
|
+
}
|
|
689
|
+
});
|
|
550
690
|
});
|
|
@@ -9,46 +9,42 @@
|
|
|
9
9
|
|
|
10
10
|
import { describe, test } from 'node:test';
|
|
11
11
|
import assert from 'node:assert/strict';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { dirname, join } from 'node:path';
|
|
15
|
-
|
|
16
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
-
const __dirname = dirname(__filename);
|
|
18
|
-
|
|
19
|
-
const completeTaskSrc = readFileSync(
|
|
20
|
-
join(__dirname, '..', 'tools', 'complete-task.ts'),
|
|
21
|
-
'utf-8',
|
|
22
|
-
);
|
|
23
|
-
const roadmapSlicesSrc = readFileSync(
|
|
24
|
-
join(__dirname, '..', 'roadmap-slices.ts'),
|
|
25
|
-
'utf-8',
|
|
26
|
-
);
|
|
12
|
+
import { normalizeListParam } from "../tools/complete-task.ts";
|
|
13
|
+
import { parseRoadmapSlices } from "../roadmap-slices.ts";
|
|
27
14
|
|
|
28
15
|
describe('complete-task normalizeListParam (#3692)', () => {
|
|
29
|
-
test('
|
|
30
|
-
assert.
|
|
31
|
-
|
|
16
|
+
test('normalizes newline-delimited key file strings', () => {
|
|
17
|
+
assert.deepEqual(
|
|
18
|
+
normalizeListParam("- src/app.ts\n* tests/app.test.ts\n docs/notes.md"),
|
|
19
|
+
["src/app.ts", "tests/app.test.ts", "docs/notes.md"],
|
|
20
|
+
);
|
|
32
21
|
});
|
|
33
22
|
|
|
34
|
-
test('
|
|
35
|
-
assert.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
test('normalizeListParam is applied to keyDecisions', () => {
|
|
40
|
-
assert.match(completeTaskSrc, /normalizeListParam\(params\.keyDecisions\)/,
|
|
41
|
-
'normalizeListParam should be applied to keyDecisions');
|
|
23
|
+
test('normalizes arrays and empty values', () => {
|
|
24
|
+
assert.deepEqual(normalizeListParam(["api", 42]), ["api", "42"]);
|
|
25
|
+
assert.deepEqual(normalizeListParam(" "), []);
|
|
26
|
+
assert.deepEqual(normalizeListParam(undefined), []);
|
|
42
27
|
});
|
|
43
28
|
});
|
|
44
29
|
|
|
45
30
|
describe('roadmap-slices depColumnIndex detection (#3692)', () => {
|
|
46
|
-
test('
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
31
|
+
test('parses dependencies from the dependency table column only', () => {
|
|
32
|
+
const slices = parseRoadmapSlices([
|
|
33
|
+
"## Slices",
|
|
34
|
+
"| ID | Title | Risk | Depends | Status |",
|
|
35
|
+
"| -- | ----- | ---- | ------- | ------ |",
|
|
36
|
+
"| S01 | Foundation | low | none | Done |",
|
|
37
|
+
"| S02 | Title mentions S01 but no dependency | medium | none | Pending |",
|
|
38
|
+
"| S03 | Integration | high | S01, S02 | Pending |",
|
|
39
|
+
].join("\n"));
|
|
40
|
+
|
|
41
|
+
assert.deepEqual(
|
|
42
|
+
slices.map((slice) => ({ id: slice.id, depends: slice.depends })),
|
|
43
|
+
[
|
|
44
|
+
{ id: "S01", depends: [] },
|
|
45
|
+
{ id: "S02", depends: [] },
|
|
46
|
+
{ id: "S03", depends: ["S01", "S02"] },
|
|
47
|
+
],
|
|
48
|
+
);
|
|
53
49
|
});
|
|
54
50
|
});
|
|
@@ -1,124 +1,61 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* completed-units-metrics-sync.test.ts — Regression tests for #2313.
|
|
3
|
-
*
|
|
4
|
-
* 1. completed-units.json should be archived (not wiped) on milestone transition
|
|
5
|
-
* 2. metrics.json should be in the worktree → project root sync file list
|
|
6
3
|
*/
|
|
7
4
|
|
|
8
5
|
import test from "node:test";
|
|
9
6
|
import assert from "node:assert/strict";
|
|
10
|
-
import { readFileSync, mkdtempSync, mkdirSync, writeFileSync, existsSync, cpSync } from "node:fs";
|
|
7
|
+
import { readFileSync, mkdtempSync, mkdirSync, writeFileSync, existsSync, cpSync, rmSync } from "node:fs";
|
|
11
8
|
import { join } from "node:path";
|
|
12
9
|
import { tmpdir } from "node:os";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
window.includes("cpsync") ||
|
|
39
|
-
window.includes("safecopy") ||
|
|
40
|
-
window.includes("completed-units-");
|
|
41
|
-
|
|
42
|
-
assert.ok(
|
|
43
|
-
hasArchive,
|
|
44
|
-
"completed-units.json should be archived before reset during milestone transition",
|
|
45
|
-
);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// ─── Bug 2: metrics.json should be in the sync file lists ──────────────────
|
|
49
|
-
|
|
50
|
-
test("#2313: syncStateToProjectRoot should sync metrics.json", () => {
|
|
51
|
-
const syncSrcPath = join(import.meta.dirname, "..", "auto-worktree.ts");
|
|
52
|
-
const syncSrc = readFileSync(syncSrcPath, "utf-8");
|
|
53
|
-
|
|
54
|
-
// syncStateToProjectRoot should copy metrics.json from worktree to project root
|
|
55
|
-
assert.ok(
|
|
56
|
-
syncSrc.includes("metrics.json"),
|
|
57
|
-
"auto-worktree.ts should reference metrics.json for sync",
|
|
58
|
-
);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
test("syncStateToProjectRoot should back-sync completed-units.json", () => {
|
|
62
|
-
const syncSrcPath = join(import.meta.dirname, "..", "auto-worktree.ts");
|
|
63
|
-
const syncSrc = readFileSync(syncSrcPath, "utf-8");
|
|
64
|
-
const fnIdx = syncSrc.indexOf("export function syncStateToProjectRoot(");
|
|
65
|
-
assert.ok(fnIdx !== -1, "syncStateToProjectRoot exists");
|
|
66
|
-
const fnBlock = syncSrc.slice(fnIdx, syncSrc.indexOf("// ─── Resource Staleness", fnIdx));
|
|
67
|
-
|
|
68
|
-
assert.ok(
|
|
69
|
-
fnBlock.includes('"completed-units.json"'),
|
|
70
|
-
"syncStateToProjectRoot should copy completed-units.json back to the project root",
|
|
71
|
-
);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
test("#2313: syncWorktreeStateBack should include metrics.json in ROOT_DIAGNOSTIC_FILES", () => {
|
|
75
|
-
const autoWorktreeSrcPath = join(import.meta.dirname, "..", "auto-worktree.ts");
|
|
76
|
-
const autoWorktreeSrc = readFileSync(autoWorktreeSrcPath, "utf-8");
|
|
77
|
-
|
|
78
|
-
// Find the ROOT_DIAGNOSTIC_FILES constant used for worktree copy-back.
|
|
79
|
-
const constIdx = autoWorktreeSrc.indexOf("ROOT_DIAGNOSTIC_FILES");
|
|
80
|
-
assert.ok(constIdx !== -1, "ROOT_DIAGNOSTIC_FILES constant exists");
|
|
81
|
-
|
|
82
|
-
// Get the array content
|
|
83
|
-
const arrayStart = autoWorktreeSrc.indexOf("[", constIdx);
|
|
84
|
-
const arrayEnd = autoWorktreeSrc.indexOf("]", arrayStart);
|
|
85
|
-
const rootFilesBlock = autoWorktreeSrc.slice(arrayStart, arrayEnd);
|
|
86
|
-
|
|
87
|
-
assert.ok(
|
|
88
|
-
rootFilesBlock.includes("metrics.json"),
|
|
89
|
-
"metrics.json should be in ROOT_DIAGNOSTIC_FILES list",
|
|
90
|
-
);
|
|
10
|
+
import { syncStateToProjectRoot } from "../auto-worktree.ts";
|
|
11
|
+
|
|
12
|
+
test("#2313: syncStateToProjectRoot copies metrics and completed-units to the project root", () => {
|
|
13
|
+
const root = mkdtempSync(join(tmpdir(), "gsd-sync-metrics-"));
|
|
14
|
+
const projectRoot = join(root, "project");
|
|
15
|
+
const worktree = join(root, "worktree");
|
|
16
|
+
mkdirSync(join(projectRoot, ".gsd"), { recursive: true });
|
|
17
|
+
mkdirSync(join(worktree, ".gsd"), { recursive: true });
|
|
18
|
+
writeFileSync(join(worktree, ".gsd", "metrics.json"), JSON.stringify({ tokens: 42 }));
|
|
19
|
+
writeFileSync(join(worktree, ".gsd", "completed-units.json"), JSON.stringify([{ id: "T01" }]));
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
syncStateToProjectRoot(worktree, projectRoot, "M001");
|
|
23
|
+
|
|
24
|
+
assert.deepEqual(
|
|
25
|
+
JSON.parse(readFileSync(join(projectRoot, ".gsd", "metrics.json"), "utf-8")),
|
|
26
|
+
{ tokens: 42 },
|
|
27
|
+
);
|
|
28
|
+
assert.deepEqual(
|
|
29
|
+
JSON.parse(readFileSync(join(projectRoot, ".gsd", "completed-units.json"), "utf-8")),
|
|
30
|
+
[{ id: "T01" }],
|
|
31
|
+
);
|
|
32
|
+
} finally {
|
|
33
|
+
rmSync(root, { recursive: true, force: true });
|
|
34
|
+
}
|
|
91
35
|
});
|
|
92
36
|
|
|
93
|
-
// ─── Functional test: completed-units archive ────────────────────────────────
|
|
94
|
-
|
|
95
37
|
test("#2313: functional — completed-units archive creates milestone-specific file", () => {
|
|
96
38
|
const tmpBase = mkdtempSync(join(tmpdir(), "gsd-completed-units-"));
|
|
97
39
|
const gsdDir = join(tmpBase, ".gsd");
|
|
98
40
|
mkdirSync(gsdDir, { recursive: true });
|
|
99
41
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
assert.deepEqual(archived, existing, "archived data should match original");
|
|
120
|
-
|
|
121
|
-
// Verify main file is reset
|
|
122
|
-
const current = JSON.parse(readFileSync(completedKeysPath, "utf-8"));
|
|
123
|
-
assert.deepEqual(current, [], "current completed-units should be empty after transition");
|
|
42
|
+
try {
|
|
43
|
+
const existing = [
|
|
44
|
+
{ type: "task", id: "T01" },
|
|
45
|
+
{ type: "slice", id: "S01" },
|
|
46
|
+
];
|
|
47
|
+
const completedKeysPath = join(gsdDir, "completed-units.json");
|
|
48
|
+
writeFileSync(completedKeysPath, JSON.stringify(existing, null, 2));
|
|
49
|
+
|
|
50
|
+
const milestoneId = "M001";
|
|
51
|
+
const archivePath = join(gsdDir, `completed-units-${milestoneId}.json`);
|
|
52
|
+
cpSync(completedKeysPath, archivePath);
|
|
53
|
+
writeFileSync(completedKeysPath, JSON.stringify([], null, 2));
|
|
54
|
+
|
|
55
|
+
assert.ok(existsSync(archivePath), "archive file should exist");
|
|
56
|
+
assert.deepEqual(JSON.parse(readFileSync(archivePath, "utf-8")), existing);
|
|
57
|
+
assert.deepEqual(JSON.parse(readFileSync(completedKeysPath, "utf-8")), []);
|
|
58
|
+
} finally {
|
|
59
|
+
rmSync(tmpBase, { recursive: true, force: true });
|
|
60
|
+
}
|
|
124
61
|
});
|
|
@@ -13,11 +13,8 @@ import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync } from 'node:f
|
|
|
13
13
|
import { join } from 'node:path';
|
|
14
14
|
import { tmpdir } from 'node:os';
|
|
15
15
|
import { randomUUID } from 'node:crypto';
|
|
16
|
-
import { fileURLToPath } from 'node:url';
|
|
17
|
-
import { dirname } from 'node:path';
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
const __dirname = dirname(__filename);
|
|
17
|
+
import { installEpipeGuard } from "../bootstrap/register-extension.ts";
|
|
21
18
|
|
|
22
19
|
function makeTmpBase(): string {
|
|
23
20
|
const base = join(tmpdir(), `gsd-test-${randomUUID()}`);
|
|
@@ -25,13 +22,6 @@ function makeTmpBase(): string {
|
|
|
25
22
|
return base;
|
|
26
23
|
}
|
|
27
24
|
|
|
28
|
-
// ─── register-extension source assertions ────────────────────────────────────
|
|
29
|
-
|
|
30
|
-
const registerExtSrc = readFileSync(
|
|
31
|
-
join(__dirname, '..', 'bootstrap', 'register-extension.ts'),
|
|
32
|
-
'utf-8',
|
|
33
|
-
);
|
|
34
|
-
|
|
35
25
|
describe('register-extension crash handler secondary fixes (#3348)', () => {
|
|
36
26
|
test('writeCrashLog is exported and writes a file to the crash directory', async () => {
|
|
37
27
|
// Dynamic import so GSD_HOME can be pointed at a temp dir without polluting ~/.gsd
|
|
@@ -60,30 +50,44 @@ describe('register-extension crash handler secondary fixes (#3348)', () => {
|
|
|
60
50
|
});
|
|
61
51
|
|
|
62
52
|
test('_gsdRejectionGuard is registered for unhandledRejection', () => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
'_gsdRejectionGuard handler should be defined',
|
|
67
|
-
);
|
|
68
|
-
assert.match(
|
|
69
|
-
registerExtSrc,
|
|
70
|
-
/unhandledRejection/,
|
|
71
|
-
'installEpipeGuard should register an unhandledRejection handler',
|
|
53
|
+
installEpipeGuard();
|
|
54
|
+
const listener = process.listeners("unhandledRejection").find((candidate) =>
|
|
55
|
+
candidate.name === "_gsdRejectionGuard"
|
|
72
56
|
);
|
|
57
|
+
assert.ok(listener, 'installEpipeGuard should register an unhandledRejection handler');
|
|
73
58
|
});
|
|
74
59
|
|
|
75
|
-
test('_gsdEpipeGuard
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
!registerExtSrc.includes('process.stderr.write(`[gsd] uncaught extension error (non-fatal)'),
|
|
80
|
-
'_gsdEpipeGuard should NOT log errors as non-fatal and continue',
|
|
81
|
-
);
|
|
82
|
-
assert.match(
|
|
83
|
-
registerExtSrc,
|
|
84
|
-
/process\.exit\(1\)/,
|
|
85
|
-
'_gsdEpipeGuard should call process.exit(1) for unrecoverable errors',
|
|
60
|
+
test('_gsdEpipeGuard writes a crash log and exits for unrecoverable errors', () => {
|
|
61
|
+
installEpipeGuard();
|
|
62
|
+
const listener = process.listeners("uncaughtException").find((candidate) =>
|
|
63
|
+
candidate.name === "_gsdEpipeGuard"
|
|
86
64
|
);
|
|
65
|
+
assert.ok(listener, '_gsdEpipeGuard should be registered');
|
|
66
|
+
|
|
67
|
+
const tmpHome = join(tmpdir(), `gsd-crash-exit-test-${randomUUID()}`);
|
|
68
|
+
const origHome = process.env.GSD_HOME;
|
|
69
|
+
const originalExit = process.exit;
|
|
70
|
+
let exitCode: number | string | null | undefined;
|
|
71
|
+
(process as any).exit = (code?: number | string | null | undefined): never => {
|
|
72
|
+
exitCode = code;
|
|
73
|
+
throw new Error("process.exit intercepted");
|
|
74
|
+
};
|
|
75
|
+
process.env.GSD_HOME = tmpHome;
|
|
76
|
+
try {
|
|
77
|
+
assert.throws(
|
|
78
|
+
() => listener(new Error("unrecoverable crash guard test"), "uncaughtException"),
|
|
79
|
+
/process\.exit intercepted/,
|
|
80
|
+
);
|
|
81
|
+
assert.equal(exitCode, 1);
|
|
82
|
+
const crashDir = join(tmpHome, "crash");
|
|
83
|
+
const logs = readdirSync(crashDir).filter((f) => f.endsWith(".log"));
|
|
84
|
+
assert.equal(logs.length, 1);
|
|
85
|
+
assert.match(readFileSync(join(crashDir, logs[0]), "utf-8"), /unrecoverable crash guard test/);
|
|
86
|
+
} finally {
|
|
87
|
+
(process as any).exit = originalExit;
|
|
88
|
+
process.env.GSD_HOME = origHome;
|
|
89
|
+
rmSync(tmpHome, { recursive: true, force: true });
|
|
90
|
+
}
|
|
87
91
|
});
|
|
88
92
|
|
|
89
93
|
test('writeCrashLog never throws even when directory is unwritable', async () => {
|