@opengsd/gsd-pi 1.2.0-dev.e8563f58 → 1.2.0-dev.fbdca60b
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/cli-model-override.d.ts +15 -0
- package/dist/cli-model-override.js +21 -0
- package/dist/cli.js +1 -18
- package/dist/loader.js +6 -4
- package/dist/register-agent-bundles.d.ts +11 -2
- package/dist/register-agent-bundles.js +18 -4
- package/dist/resource-loader.d.ts +10 -5
- package/dist/resource-loader.js +121 -6
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/ask-user-questions.js +3 -2
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +447 -215
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +33 -1
- package/dist/resources/extensions/gsd/auto/closeout.js +215 -0
- package/dist/resources/extensions/gsd/auto/dispatch-history.js +21 -6
- package/dist/resources/extensions/gsd/auto/dispatch.js +365 -0
- package/dist/resources/extensions/gsd/auto/finalize.js +347 -0
- package/dist/resources/extensions/gsd/auto/loop.js +4 -1
- package/dist/resources/extensions/gsd/auto/milestone-lease-reclaim.js +56 -0
- package/dist/resources/extensions/gsd/auto/orchestrator.js +85 -15
- package/dist/resources/extensions/gsd/auto/phase-helpers.js +146 -0
- package/dist/resources/extensions/gsd/auto/phases.js +17 -2329
- package/dist/resources/extensions/gsd/auto/pre-dispatch.js +534 -0
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto/unit-phase.js +694 -0
- package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +1 -1
- package/dist/resources/extensions/gsd/auto/worktree-safety-phase.js +125 -0
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +3 -2
- package/dist/resources/extensions/gsd/auto-dispatch.js +11 -2
- package/dist/resources/extensions/gsd/auto-post-unit.js +18 -6
- package/dist/resources/extensions/gsd/auto-start.js +23 -3
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
- package/dist/resources/extensions/gsd/auto-verification.js +14 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +15 -2
- package/dist/resources/extensions/gsd/auto.js +45 -2
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -7
- package/dist/resources/extensions/gsd/commands/context.js +16 -2
- package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -2
- package/dist/resources/extensions/gsd/commands-workflow-templates.js +9 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +8 -3
- package/dist/resources/extensions/gsd/db/engine.js +24 -6
- package/dist/resources/extensions/gsd/db/queries.js +30 -0
- package/dist/resources/extensions/gsd/db-migration-backup.js +51 -8
- package/dist/resources/extensions/gsd/db-transaction.js +27 -23
- package/dist/resources/extensions/gsd/db-writer.js +8 -17
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
- package/dist/resources/extensions/gsd/doctor-environment.js +256 -125
- package/dist/resources/extensions/gsd/gsd-db.js +15 -20
- package/dist/resources/extensions/gsd/guided-flow.js +93 -4
- package/dist/resources/extensions/gsd/health-widget.js +87 -28
- package/dist/resources/extensions/gsd/mcp-bridge.js +10 -0
- package/dist/resources/extensions/gsd/memory-relations.js +1 -1
- package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
- package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
- package/dist/resources/extensions/gsd/milestone-settlement.js +2 -2
- package/dist/resources/extensions/gsd/notifications.js +12 -7
- package/dist/resources/extensions/gsd/projection-flush.js +7 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +3 -1
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -1
- package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
- package/dist/resources/extensions/gsd/session-lock.js +1 -1
- package/dist/resources/extensions/gsd/skill-activation.js +3 -6
- package/dist/resources/extensions/gsd/state.js +6 -2
- package/dist/resources/extensions/gsd/tool-contract.js +14 -3
- package/dist/resources/extensions/gsd/tool-surface-readiness.js +83 -31
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +2 -2
- package/dist/resources/extensions/gsd/tools/complete-task.js +65 -2
- package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -2
- package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
- package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
- package/dist/resources/extensions/gsd/unit-context-composer.js +1 -1
- package/dist/resources/extensions/gsd/unit-registry.js +34 -4
- package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
- package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
- package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
- package/dist/resources/extensions/gsd/workflow-events.js +6 -18
- package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +2 -0
- package/dist/resources/extensions/gsd/workflow-mcp-readiness-cache.js +105 -0
- package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
- package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
- package/dist/resources/extensions/gsd/worktree-safety.js +28 -26
- package/dist/resources/extensions/gsd/worktree.js +8 -1
- package/dist/resources/extensions/mcp-client/manager.js +6 -1
- package/dist/resources/skills/create-skill/SKILL.md +3 -0
- package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
- package/dist/runtime-checks.d.ts +10 -0
- package/dist/runtime-checks.js +27 -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 +7 -7
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- 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.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/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- 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-paths-manifest.json +7 -7
- package/dist/web/standalone/.next/server/chunks/{5942.js → 1128.js} +1 -1
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- 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/node_modules/node-pty/build/Makefile +1 -1
- package/package.json +3 -3
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.js +6 -4
- package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +8 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +50 -6
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +34 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +17 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +4 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/README.md +12 -3
- package/packages/mcp-server/dist/cli-runner.d.ts +40 -0
- package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -0
- package/packages/mcp-server/dist/cli-runner.js +137 -0
- package/packages/mcp-server/dist/cli-runner.js.map +1 -0
- package/packages/mcp-server/dist/cli.js +2 -53
- package/packages/mcp-server/dist/cli.js.map +1 -1
- package/packages/mcp-server/dist/pid-registry.d.ts +46 -0
- package/packages/mcp-server/dist/pid-registry.d.ts.map +1 -0
- package/packages/mcp-server/dist/pid-registry.js +459 -0
- package/packages/mcp-server/dist/pid-registry.js.map +1 -0
- package/packages/mcp-server/dist/probe-mode.d.ts +4 -0
- package/packages/mcp-server/dist/probe-mode.d.ts.map +1 -0
- package/packages/mcp-server/dist/probe-mode.js +10 -0
- package/packages/mcp-server/dist/probe-mode.js.map +1 -0
- package/packages/mcp-server/dist/stdio-watchdog.d.ts +8 -0
- package/packages/mcp-server/dist/stdio-watchdog.d.ts.map +1 -0
- package/packages/mcp-server/dist/stdio-watchdog.js +40 -0
- package/packages/mcp-server/dist/stdio-watchdog.js.map +1 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +62 -43
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +5 -5
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +43 -2
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.js +45 -17
- package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/README.md +15 -0
- package/packages/pi-tui/dist/index.d.ts +2 -2
- package/packages/pi-tui/dist/index.d.ts.map +1 -1
- package/packages/pi-tui/dist/index.js +2 -2
- package/packages/pi-tui/dist/index.js.map +1 -1
- package/packages/pi-tui/dist/terminal-image.d.ts +33 -0
- package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal-image.js +54 -2
- package/packages/pi-tui/dist/terminal-image.js.map +1 -1
- package/packages/pi-tui/dist/terminal.d.ts +12 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +70 -25
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts +15 -0
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +106 -21
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/dist/utils.d.ts.map +1 -1
- package/packages/pi-tui/dist/utils.js +110 -36
- package/packages/pi-tui/dist/utils.js.map +1 -1
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/dist/theme/theme.d.ts.map +1 -1
- package/pkg/dist/theme/theme.js +45 -17
- package/pkg/dist/theme/theme.js.map +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +7 -2
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +531 -226
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +672 -7
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +38 -1
- package/src/resources/extensions/gsd/auto/closeout.ts +309 -0
- package/src/resources/extensions/gsd/auto/dispatch-history.ts +22 -6
- package/src/resources/extensions/gsd/auto/dispatch.ts +449 -0
- package/src/resources/extensions/gsd/auto/finalize.ts +445 -0
- package/src/resources/extensions/gsd/auto/loop.ts +4 -1
- package/src/resources/extensions/gsd/auto/milestone-lease-reclaim.ts +74 -0
- package/src/resources/extensions/gsd/auto/orchestrator.ts +95 -15
- package/src/resources/extensions/gsd/auto/phase-helpers.ts +199 -0
- package/src/resources/extensions/gsd/auto/phases.ts +58 -3022
- package/src/resources/extensions/gsd/auto/pre-dispatch.ts +704 -0
- package/src/resources/extensions/gsd/auto/session.ts +3 -0
- package/src/resources/extensions/gsd/auto/unit-phase.ts +910 -0
- package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +1 -1
- package/src/resources/extensions/gsd/auto/worktree-safety-phase.ts +149 -0
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +10 -16
- package/src/resources/extensions/gsd/auto-dispatch.ts +11 -10
- package/src/resources/extensions/gsd/auto-post-unit.ts +21 -6
- package/src/resources/extensions/gsd/auto-start.ts +24 -4
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
- package/src/resources/extensions/gsd/auto-verification.ts +18 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +15 -2
- package/src/resources/extensions/gsd/auto.ts +56 -2
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +56 -6
- package/src/resources/extensions/gsd/commands/context.ts +16 -2
- package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -2
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +11 -4
- package/src/resources/extensions/gsd/crash-recovery.ts +10 -2
- package/src/resources/extensions/gsd/db/engine.ts +26 -6
- package/src/resources/extensions/gsd/db/queries.ts +29 -0
- package/src/resources/extensions/gsd/db-migration-backup.ts +56 -7
- package/src/resources/extensions/gsd/db-transaction.ts +37 -20
- package/src/resources/extensions/gsd/db-writer.ts +11 -19
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
- package/src/resources/extensions/gsd/doctor-environment.ts +267 -142
- package/src/resources/extensions/gsd/gsd-db.ts +15 -19
- package/src/resources/extensions/gsd/guided-flow.ts +145 -24
- package/src/resources/extensions/gsd/health-widget.ts +91 -27
- package/src/resources/extensions/gsd/mcp-bridge.ts +39 -0
- package/src/resources/extensions/gsd/memory-relations.ts +1 -1
- package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
- package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
- package/src/resources/extensions/gsd/milestone-settlement.ts +2 -2
- package/src/resources/extensions/gsd/notifications.ts +13 -6
- package/src/resources/extensions/gsd/projection-flush.ts +20 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +3 -1
- package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -1
- package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
- package/src/resources/extensions/gsd/session-lock.ts +1 -1
- package/src/resources/extensions/gsd/skill-activation.ts +3 -6
- package/src/resources/extensions/gsd/state.ts +7 -1
- package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-blocked-remediation-message.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +206 -22
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +76 -12
- package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +77 -1
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
- package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +169 -1
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +141 -5
- package/src/resources/extensions/gsd/tests/db-migration-backup.test.ts +68 -19
- package/src/resources/extensions/gsd/tests/db-transaction.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/dist-redirect.mjs +8 -0
- package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +117 -91
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +18 -6
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-environment-async.test.ts +104 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +47 -16
- package/src/resources/extensions/gsd/tests/mcp-readiness-preflight.test.ts +205 -0
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +6 -5
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/notifications.test.ts +64 -9
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +10 -2
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -4
- package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +31 -81
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +26 -2
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +170 -48
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -17
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +184 -10
- package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp-readiness-cache.test.ts +119 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +65 -2
- package/src/resources/extensions/gsd/tests/workflow-phase-contract-matrix.test.ts +332 -0
- package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-safety-phase.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +72 -0
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
- package/src/resources/extensions/gsd/tool-contract.ts +38 -3
- package/src/resources/extensions/gsd/tool-surface-readiness.ts +126 -19
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
- package/src/resources/extensions/gsd/tools/complete-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/complete-task.ts +90 -2
- package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
- package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
- package/src/resources/extensions/gsd/unit-context-composer.ts +1 -1
- package/src/resources/extensions/gsd/unit-registry.ts +34 -4
- package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
- package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
- package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
- package/src/resources/extensions/gsd/workflow-events.ts +12 -20
- package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -0
- package/src/resources/extensions/gsd/workflow-mcp-readiness-cache.ts +150 -0
- package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
- package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
- package/src/resources/extensions/gsd/worktree-safety.ts +41 -39
- package/src/resources/extensions/gsd/worktree.ts +7 -1
- package/src/resources/extensions/mcp-client/manager.ts +7 -1
- package/src/resources/skills/create-skill/SKILL.md +3 -0
- package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
- package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
- package/src/resources/skills/gsd-browser/SKILL.md +0 -41
- /package/dist/web/standalone/.next/static/{LDHRKiRBIVZmiuMjrL1Vy → 2T9IOdiiM3o3gZ4UbPi8E}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{LDHRKiRBIVZmiuMjrL1Vy → 2T9IOdiiM3o3gZ4UbPi8E}/_ssgManifest.js +0 -0
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
_dispatchWorkflowForTest,
|
|
12
12
|
resolveGuidedDispatchProjectRoot,
|
|
13
13
|
} from "../guided-flow.ts";
|
|
14
|
+
import { getRequiredWorkflowToolsForUnit } from "../unit-tool-contracts.ts";
|
|
14
15
|
|
|
15
16
|
test("guided dispatch falls back to cwd only when no project root is supplied", () => {
|
|
16
17
|
const cwd = process.cwd();
|
|
@@ -77,12 +78,8 @@ test("guided dispatch passes the explicit project root through model and compati
|
|
|
77
78
|
seen.modelRoot = projectRoot;
|
|
78
79
|
return { routing: null, appliedModel: null };
|
|
79
80
|
},
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
_requiredTools: string[],
|
|
83
|
-
options?: { projectRoot?: string },
|
|
84
|
-
) => {
|
|
85
|
-
seen.compatibilityRoot = options?.projectRoot ?? "";
|
|
81
|
+
getDispatchReadinessError: (input: { projectRoot?: string }) => {
|
|
82
|
+
seen.compatibilityRoot = input.projectRoot ?? "";
|
|
86
83
|
return null;
|
|
87
84
|
},
|
|
88
85
|
},
|
|
@@ -119,6 +116,7 @@ test("guided dispatch accepts workflow MCP tools absent from parent active tool
|
|
|
119
116
|
getProviderAuthMode: () => "externalCli",
|
|
120
117
|
},
|
|
121
118
|
ui: {
|
|
119
|
+
setStatus: () => {},
|
|
122
120
|
notify: (message: string) => {
|
|
123
121
|
notifications.push(message);
|
|
124
122
|
},
|
|
@@ -134,8 +132,22 @@ test("guided dispatch accepts workflow MCP tools absent from parent active tool
|
|
|
134
132
|
"write",
|
|
135
133
|
];
|
|
136
134
|
|
|
135
|
+
// The workflow MCP server registers its tools out of band, so the unit's
|
|
136
|
+
// required workflow tools show up in the registered tool snapshot
|
|
137
|
+
// (getAllTools) under the MCP server prefix without ever entering the parent
|
|
138
|
+
// session's active tool surface (getActiveTools). This is exactly the shape
|
|
139
|
+
// the readiness gate must accept. Derive the surface from the unit contract
|
|
140
|
+
// so this test stays correct if discuss-milestone's required tools change.
|
|
141
|
+
const registeredTools = [
|
|
142
|
+
...activeTools,
|
|
143
|
+
...getRequiredWorkflowToolsForUnit("discuss-milestone").map(
|
|
144
|
+
(tool) => `mcp__gsd-workflow__${tool}`,
|
|
145
|
+
),
|
|
146
|
+
];
|
|
147
|
+
|
|
137
148
|
const pi = {
|
|
138
149
|
getActiveTools: () => [...activeTools],
|
|
150
|
+
getAllTools: () => registeredTools.map((name) => ({ name })),
|
|
139
151
|
setActiveTools: (tools: string[]) => {
|
|
140
152
|
activeTools = [...tools];
|
|
141
153
|
},
|
|
@@ -134,6 +134,21 @@ describe("auto-worktree lifecycle", () => {
|
|
|
134
134
|
teardownAutoWorktree(tempDir, "M003");
|
|
135
135
|
});
|
|
136
136
|
|
|
137
|
+
test("isInAutoWorktree returns false when ambient cwd was deleted", (t) => {
|
|
138
|
+
const cwd = t.mock.method(process, "cwd", () => {
|
|
139
|
+
const err = new Error("process.cwd failed") as NodeJS.ErrnoException;
|
|
140
|
+
err.code = "ENOENT";
|
|
141
|
+
err.syscall = "uv_cwd";
|
|
142
|
+
throw err;
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
assert.equal(isInAutoWorktree("/repo"), false);
|
|
147
|
+
} finally {
|
|
148
|
+
cwd.mock.restore();
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
|
|
137
152
|
test("symlink-resolved auto worktree is detected after module state reset", () => {
|
|
138
153
|
tempDir = createTempRepo();
|
|
139
154
|
const savedGsdHome = process.env.GSD_HOME;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Verify the non-blocking runEnvironmentChecksAsync is behaviourally
|
|
3
|
+
// identical to the synchronous runEnvironmentChecks (the health-widget render
|
|
4
|
+
// path was moved onto the async variant for performance), and that the single-
|
|
5
|
+
// scan checkPortConflicts still detects a real in-use port.
|
|
6
|
+
|
|
7
|
+
import test, { type TestContext } from "node:test";
|
|
8
|
+
import assert from "node:assert/strict";
|
|
9
|
+
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
10
|
+
import { join, dirname } from "node:path";
|
|
11
|
+
import { tmpdir } from "node:os";
|
|
12
|
+
import { createServer } from "node:net";
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
runEnvironmentChecks,
|
|
16
|
+
runEnvironmentChecksAsync,
|
|
17
|
+
type EnvironmentCheckResult,
|
|
18
|
+
} from "../../doctor-environment.ts";
|
|
19
|
+
|
|
20
|
+
function makeProject(t: TestContext, files: Record<string, string>): string {
|
|
21
|
+
const dir = mkdtempSync(join(tmpdir(), "gsd-env-async-"));
|
|
22
|
+
t.after(() => {
|
|
23
|
+
try {
|
|
24
|
+
rmSync(dir, { recursive: true, force: true });
|
|
25
|
+
} catch {
|
|
26
|
+
/* ignore */
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
for (const [name, content] of Object.entries(files)) {
|
|
30
|
+
const filePath = join(dir, name);
|
|
31
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
32
|
+
writeFileSync(filePath, content);
|
|
33
|
+
}
|
|
34
|
+
return dir;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Stable, order-independent signature of a check-result set for comparison.
|
|
38
|
+
function normalize(results: EnvironmentCheckResult[]): string[] {
|
|
39
|
+
return results.map((r) => `${r.name}|${r.status}|${r.message}|${r.detail ?? ""}`).sort();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
test("runEnvironmentChecksAsync returns the same results as runEnvironmentChecks", async (t) => {
|
|
43
|
+
const dir = makeProject(t, {
|
|
44
|
+
"package.json": JSON.stringify({
|
|
45
|
+
name: "fixture",
|
|
46
|
+
engines: { node: ">=18" },
|
|
47
|
+
scripts: { dev: "vite --port 4321", build: "tsc" },
|
|
48
|
+
devDependencies: { typescript: "^5.0.0" },
|
|
49
|
+
}),
|
|
50
|
+
".env.example": "API_KEY=\n",
|
|
51
|
+
Dockerfile: "FROM node:20\n",
|
|
52
|
+
});
|
|
53
|
+
mkdirSync(join(dir, "node_modules"), { recursive: true });
|
|
54
|
+
|
|
55
|
+
const sync = runEnvironmentChecks(dir);
|
|
56
|
+
const asyncResults = await runEnvironmentChecksAsync(dir);
|
|
57
|
+
|
|
58
|
+
assert.deepEqual(
|
|
59
|
+
normalize(asyncResults),
|
|
60
|
+
normalize(sync),
|
|
61
|
+
"async checks must produce the identical result set as the sync checks",
|
|
62
|
+
);
|
|
63
|
+
// Sanity: the fixture is rich enough that the suite actually produced checks.
|
|
64
|
+
assert.ok(sync.length > 0, "expected the fixture to yield environment checks");
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("runEnvironmentChecksAsync matches sync on a bare directory (no package.json)", async (t) => {
|
|
68
|
+
const dir = makeProject(t, {});
|
|
69
|
+
const sync = runEnvironmentChecks(dir);
|
|
70
|
+
const asyncResults = await runEnvironmentChecksAsync(dir);
|
|
71
|
+
assert.deepEqual(normalize(asyncResults), normalize(sync));
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test(
|
|
75
|
+
"single-scan port check detects a real in-use port, identically sync and async",
|
|
76
|
+
{ skip: process.platform === "win32" ? "lsof-based port check is macOS/Linux only" : false },
|
|
77
|
+
async (t) => {
|
|
78
|
+
// Bind a real listener, then reference its port from package.json scripts so
|
|
79
|
+
// collectPortsToCheck picks it up. The server stays up across both check runs.
|
|
80
|
+
const server = createServer();
|
|
81
|
+
const port = await new Promise<number>((resolve, reject) => {
|
|
82
|
+
server.once("error", reject);
|
|
83
|
+
server.listen(0, "127.0.0.1", () => {
|
|
84
|
+
const addr = server.address();
|
|
85
|
+
resolve(typeof addr === "object" && addr ? addr.port : 0);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
t.after(() => new Promise<void>((resolve) => server.close(() => resolve())));
|
|
89
|
+
assert.ok(port >= 1024 && port <= 65535, "ephemeral port should be in the checked range");
|
|
90
|
+
|
|
91
|
+
const dir = makeProject(t, {
|
|
92
|
+
"package.json": JSON.stringify({ name: "fixture", scripts: { dev: `serve --port ${port}` } }),
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const syncConflicts = runEnvironmentChecks(dir).filter((r) => r.name === "port_conflict");
|
|
96
|
+
const asyncConflicts = (await runEnvironmentChecksAsync(dir)).filter((r) => r.name === "port_conflict");
|
|
97
|
+
|
|
98
|
+
// Equivalence holds regardless of whether lsof is present on the runner.
|
|
99
|
+
assert.deepEqual(normalize(asyncConflicts), normalize(syncConflicts), "sync and async must agree on port conflicts");
|
|
100
|
+
// On macOS/Linux lsof is standard, so the listener must be reported and named.
|
|
101
|
+
assert.equal(syncConflicts.length, 1, "expected exactly one port conflict for the in-use port");
|
|
102
|
+
assert.match(syncConflicts[0]!.message, new RegExp(`\\b${port}\\b`), "conflict message must name the in-use port");
|
|
103
|
+
},
|
|
104
|
+
);
|
|
@@ -317,6 +317,24 @@ test('(k2) run-uat prompt references gsd_uat_result_save, not direct write', ()
|
|
|
317
317
|
);
|
|
318
318
|
});
|
|
319
319
|
|
|
320
|
+
test('(k3) run-uat prompt warns that .gsd glob misses can be symlink traversal artifacts', async () => {
|
|
321
|
+
const base = createFixtureBase();
|
|
322
|
+
try {
|
|
323
|
+
const uatRel = '.gsd/milestones/M001/slices/S01/S01-UAT.md';
|
|
324
|
+
const uatContent = makeUatContent('runtime-executable');
|
|
325
|
+
writeSliceFile(base, 'M001', 'S01', 'UAT', uatContent);
|
|
326
|
+
|
|
327
|
+
const prompt = await buildRunUatPrompt('M001', 'S01', uatRel, uatContent, base);
|
|
328
|
+
|
|
329
|
+
assert.match(prompt, /\.gsd\/\*\*/);
|
|
330
|
+
assert.match(prompt, /symlink-backed/i);
|
|
331
|
+
assert.match(prompt, /do not infer that the GSD harness is missing/i);
|
|
332
|
+
assert.match(prompt, /use the preloaded UAT context/i);
|
|
333
|
+
} finally {
|
|
334
|
+
cleanup(base);
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
|
|
320
338
|
test('(l) dispatch preconditions via resolveSliceFile', () => {
|
|
321
339
|
const base = createFixtureBase();
|
|
322
340
|
const uatContent = makeUatContent('artifact-driven');
|
|
@@ -15,12 +15,27 @@ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
|
15
15
|
import { tmpdir } from "node:os";
|
|
16
16
|
import { join } from "node:path";
|
|
17
17
|
|
|
18
|
+
/** Create a temp project root with a git repo for phase-function tests. */
|
|
19
|
+
function makeTestBase(prefix: string): string {
|
|
20
|
+
const base = mkdtempSync(join(tmpdir(), prefix));
|
|
21
|
+
execFileSync("git", ["init", "--initial-branch=main"], { cwd: base, stdio: "ignore" });
|
|
22
|
+
execFileSync("git", ["config", "user.email", "test@test.com"], { cwd: base, stdio: "ignore" });
|
|
23
|
+
execFileSync("git", ["config", "user.name", "Test"], { cwd: base, stdio: "ignore" });
|
|
24
|
+
writeFileSync(join(base, "README.md"), "# test\n");
|
|
25
|
+
execFileSync("git", ["add", "README.md"], { cwd: base, stdio: "ignore" });
|
|
26
|
+
execFileSync("git", ["commit", "-m", "chore: seed"], { cwd: base, stdio: "ignore" });
|
|
27
|
+
return base;
|
|
28
|
+
}
|
|
29
|
+
|
|
18
30
|
import type { JournalEntry } from "../journal.js";
|
|
19
31
|
import type { LoopDeps } from "../auto/loop-deps.js";
|
|
20
32
|
import { WorktreeStateProjection } from "../worktree-state-projection.js";
|
|
21
33
|
import type { IterationContext, LoopState, PreDispatchData, IterationData } from "../auto/types.js";
|
|
22
34
|
import type { SessionLockStatus } from "../session-lock.js";
|
|
23
|
-
import { runDispatch
|
|
35
|
+
import { runDispatch } from "../auto/dispatch.js";
|
|
36
|
+
import { runUnitPhase } from "../auto/unit-phase.js";
|
|
37
|
+
import { runPreDispatch } from "../auto/pre-dispatch.js";
|
|
38
|
+
import { runFinalize } from "../auto/finalize.js";
|
|
24
39
|
import { readUnitRuntimeRecord } from "../unit-runtime.js";
|
|
25
40
|
import { ModelPolicyDispatchBlockedError } from "../auto-model-selection.js";
|
|
26
41
|
import {
|
|
@@ -182,7 +197,7 @@ function makeSession() {
|
|
|
182
197
|
verbose: false,
|
|
183
198
|
stepMode: false,
|
|
184
199
|
paused: false,
|
|
185
|
-
basePath: "
|
|
200
|
+
basePath: makeTestBase("gsd-journal-session-"),
|
|
186
201
|
originalBasePath: "",
|
|
187
202
|
currentMilestoneId: "M001",
|
|
188
203
|
currentUnit: null,
|
|
@@ -296,10 +311,18 @@ test("runDispatch emits dispatch-stop when dispatch returns stop action", async
|
|
|
296
311
|
assert.equal(stopEvents[0].flowId, ic.flowId);
|
|
297
312
|
});
|
|
298
313
|
|
|
299
|
-
test("runDispatch checks prior-slice completion against the project root in worktree mode", async () => {
|
|
314
|
+
test("runDispatch checks prior-slice completion against the project root in worktree mode", async (t) => {
|
|
300
315
|
const capture = createEventCapture();
|
|
301
316
|
const guardCalls: Array<{ fn: string; args: unknown[] }> = [];
|
|
317
|
+
const projectRoot = makeTestBase("gsd-wt-prior-slice-");
|
|
318
|
+
const milestoneId = "M029-xoklo9";
|
|
319
|
+
const worktreeRoot = join(projectRoot, ".gsd", "worktrees", milestoneId);
|
|
320
|
+
execFileSync("git", ["worktree", "add", "-b", `auto/${milestoneId}`, worktreeRoot], { cwd: projectRoot, stdio: "ignore" });
|
|
321
|
+
t.after(() => rmSync(projectRoot, { recursive: true, force: true }));
|
|
322
|
+
|
|
302
323
|
const deps = makeMockDeps(capture, {
|
|
324
|
+
getIsolationMode: () => "worktree",
|
|
325
|
+
autoWorktreeBranch: (mid: string) => `auto/${mid}`,
|
|
303
326
|
getMainBranch: (basePath: string) => {
|
|
304
327
|
guardCalls.push({ fn: "getMainBranch", args: [basePath] });
|
|
305
328
|
return "main";
|
|
@@ -320,19 +343,21 @@ test("runDispatch checks prior-slice completion against the project root in work
|
|
|
320
343
|
const ic = makeIC(deps, {
|
|
321
344
|
s: {
|
|
322
345
|
...makeSession(),
|
|
323
|
-
basePath:
|
|
324
|
-
originalBasePath:
|
|
346
|
+
basePath: worktreeRoot,
|
|
347
|
+
originalBasePath: projectRoot,
|
|
348
|
+
canonicalProjectRoot: projectRoot,
|
|
349
|
+
currentMilestoneId: milestoneId,
|
|
325
350
|
} as any,
|
|
326
351
|
});
|
|
327
352
|
const preData: PreDispatchData = {
|
|
328
353
|
state: {
|
|
329
354
|
phase: "executing",
|
|
330
|
-
activeMilestone: { id:
|
|
355
|
+
activeMilestone: { id: milestoneId, title: "Test", status: "active" },
|
|
331
356
|
activeSlice: { id: "S01", title: "Slice 1" },
|
|
332
|
-
registry: [{ id:
|
|
357
|
+
registry: [{ id: milestoneId, status: "active" }],
|
|
333
358
|
blockers: [],
|
|
334
359
|
} as any,
|
|
335
|
-
mid:
|
|
360
|
+
mid: milestoneId,
|
|
336
361
|
midTitle: "Test Milestone",
|
|
337
362
|
};
|
|
338
363
|
|
|
@@ -342,12 +367,12 @@ test("runDispatch checks prior-slice completion against the project root in work
|
|
|
342
367
|
consecutiveFinalizeTimeouts: 0,
|
|
343
368
|
});
|
|
344
369
|
|
|
345
|
-
assert.equal(result.action, "next");
|
|
370
|
+
assert.equal(result.action, "next", "dispatch must proceed under worktree isolation");
|
|
346
371
|
assert.deepEqual(guardCalls, [
|
|
347
|
-
{ fn: "getMainBranch", args: [
|
|
372
|
+
{ fn: "getMainBranch", args: [projectRoot] },
|
|
348
373
|
{
|
|
349
374
|
fn: "getPriorSliceCompletionBlocker",
|
|
350
|
-
args: [
|
|
375
|
+
args: [projectRoot, "main", "execute-task", "M001/S01/T01"],
|
|
351
376
|
},
|
|
352
377
|
]);
|
|
353
378
|
});
|
|
@@ -434,6 +459,9 @@ test("runDispatch pauses when execute-task artifacts exist but DB status is stil
|
|
|
434
459
|
const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
435
460
|
const tasksDir = join(sliceDir, "tasks");
|
|
436
461
|
mkdirSync(tasksDir, { recursive: true });
|
|
462
|
+
execFileSync("git", ["init", "--initial-branch=main"], { cwd: base, stdio: "ignore" });
|
|
463
|
+
execFileSync("git", ["config", "user.email", "test@test.com"], { cwd: base, stdio: "ignore" });
|
|
464
|
+
execFileSync("git", ["config", "user.name", "Test"], { cwd: base, stdio: "ignore" });
|
|
437
465
|
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
438
466
|
insertMilestone({ id: "M001", title: "Test", status: "active" });
|
|
439
467
|
insertSlice({ id: "S01", milestoneId: "M001", title: "Slice", status: "in_progress" });
|
|
@@ -517,6 +545,9 @@ test("runDispatch pauses at Level 2 when execute-task artifacts exist but DB sta
|
|
|
517
545
|
const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
518
546
|
const tasksDir = join(sliceDir, "tasks");
|
|
519
547
|
mkdirSync(tasksDir, { recursive: true });
|
|
548
|
+
execFileSync("git", ["init", "--initial-branch=main"], { cwd: base, stdio: "ignore" });
|
|
549
|
+
execFileSync("git", ["config", "user.email", "test@test.com"], { cwd: base, stdio: "ignore" });
|
|
550
|
+
execFileSync("git", ["config", "user.name", "Test"], { cwd: base, stdio: "ignore" });
|
|
520
551
|
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
521
552
|
insertMilestone({ id: "M001", title: "Test", status: "active" });
|
|
522
553
|
insertSlice({ id: "S01", milestoneId: "M001", title: "Slice", status: "in_progress" });
|
|
@@ -888,7 +919,7 @@ test("runUnitPhase increments unitDispatchCount for repeated artifact-missing re
|
|
|
888
919
|
|
|
889
920
|
test("runUnitPhase pre-dispatch model validation failures do not emit unit-start or dispatch runtime state", async (t) => {
|
|
890
921
|
const capture = createEventCapture();
|
|
891
|
-
const base =
|
|
922
|
+
const base = makeTestBase(`gsd-pre-dispatch-block-${randomUUID()}`);
|
|
892
923
|
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
893
924
|
|
|
894
925
|
const deps = makeMockDeps(capture, {
|
|
@@ -1084,7 +1115,7 @@ test("terminal event is emitted on blocked state", async () => {
|
|
|
1084
1115
|
});
|
|
1085
1116
|
|
|
1086
1117
|
test("#4671: plan-v2 missing CONTEXT.md reaches dispatch recovery instead of pausing", async () => {
|
|
1087
|
-
const basePath =
|
|
1118
|
+
const basePath = makeTestBase("gsd-4671-predispatch-");
|
|
1088
1119
|
mkdirSync(join(basePath, ".gsd", "milestones", "M001", "slices", "S01", "tasks"), { recursive: true });
|
|
1089
1120
|
openDatabase(join(basePath, ".gsd", "gsd.db"));
|
|
1090
1121
|
try {
|
|
@@ -1141,7 +1172,7 @@ test("#4671: plan-v2 missing CONTEXT.md reaches dispatch recovery instead of pau
|
|
|
1141
1172
|
});
|
|
1142
1173
|
|
|
1143
1174
|
test("plan-v2 empty graph rederives state before pausing", async () => {
|
|
1144
|
-
const basePath =
|
|
1175
|
+
const basePath = makeTestBase("gsd-plan-v2-empty-graph-");
|
|
1145
1176
|
mkdirSync(join(basePath, ".gsd", "milestones", "M001"), { recursive: true });
|
|
1146
1177
|
writeFileSync(
|
|
1147
1178
|
join(basePath, ".gsd", "milestones", "M001", "M001-CONTEXT.md"),
|
|
@@ -1204,7 +1235,7 @@ test("plan-v2 empty graph rederives state before pausing", async () => {
|
|
|
1204
1235
|
});
|
|
1205
1236
|
|
|
1206
1237
|
test("plan-v2 empty graph pauses after one failed rederive", async () => {
|
|
1207
|
-
const basePath =
|
|
1238
|
+
const basePath = makeTestBase("gsd-plan-v2-empty-graph-pause-");
|
|
1208
1239
|
mkdirSync(join(basePath, ".gsd", "milestones", "M001"), { recursive: true });
|
|
1209
1240
|
writeFileSync(
|
|
1210
1241
|
join(basePath, ".gsd", "milestones", "M001", "M001-CONTEXT.md"),
|
|
@@ -1394,7 +1425,7 @@ test("session-failed cancellations close out and emit unit-end before hard stop"
|
|
|
1394
1425
|
test("runFinalize pauses and emits unit-end when pre-verification times out", async () => {
|
|
1395
1426
|
const capture = createEventCapture();
|
|
1396
1427
|
let pauseCalls = 0;
|
|
1397
|
-
const basePath =
|
|
1428
|
+
const basePath = makeTestBase("gsd-finalize-timeout-");
|
|
1398
1429
|
|
|
1399
1430
|
const deps = makeMockDeps(capture, {
|
|
1400
1431
|
pauseAuto: async () => { pauseCalls++; },
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Tests for the MCP readiness preflight gate in dispatchWorkflow.
|
|
3
|
+
|
|
4
|
+
import { describe, test, mock } from "node:test";
|
|
5
|
+
import assert from "node:assert/strict";
|
|
6
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { createRequire } from "node:module";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { pathToFileURL } from "node:url";
|
|
11
|
+
|
|
12
|
+
import { _awaitWorkflowMcpReadinessForTest as awaitWorkflowMcpReadiness } from "../guided-flow.ts";
|
|
13
|
+
import { clearMcpConfigCache } from "../../mcp-client/manager.ts";
|
|
14
|
+
import { clearWorkflowMcpProbeCache } from "../workflow-mcp-readiness-cache.ts";
|
|
15
|
+
|
|
16
|
+
function makeCtx(opts: { authMode?: string; baseUrl?: string; systemPrompt?: string } = {}) {
|
|
17
|
+
const { authMode = "externalCli", baseUrl = "local://pipe", systemPrompt = "" } = opts;
|
|
18
|
+
return {
|
|
19
|
+
model: { provider: "anthropic", baseUrl },
|
|
20
|
+
modelRegistry: {
|
|
21
|
+
getProviderAuthMode: mock.fn(() => authMode),
|
|
22
|
+
},
|
|
23
|
+
getSystemPrompt: mock.fn(() => systemPrompt),
|
|
24
|
+
ui: {
|
|
25
|
+
setStatus: mock.fn(),
|
|
26
|
+
notify: mock.fn(),
|
|
27
|
+
},
|
|
28
|
+
} as any;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function makePi(tools: string[] | (() => string[])) {
|
|
32
|
+
const getTools = typeof tools === "function" ? tools : () => tools;
|
|
33
|
+
return {
|
|
34
|
+
getActiveTools: getTools,
|
|
35
|
+
getAllTools: () => getTools().map((name: string) => ({ name })),
|
|
36
|
+
} as any;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
describe("awaitWorkflowMcpReadiness", () => {
|
|
40
|
+
test("returns null (ready) when not using MCP transport", async () => {
|
|
41
|
+
clearWorkflowMcpProbeCache();
|
|
42
|
+
const ctx = makeCtx({ authMode: "native", baseUrl: "https://api.anthropic.com" });
|
|
43
|
+
const pi = makePi([]);
|
|
44
|
+
assert.equal(await awaitWorkflowMcpReadiness(pi, ctx, "/fake/path"), null);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("returns null (ready) when provider has no auth mode", async () => {
|
|
48
|
+
const ctx = {
|
|
49
|
+
model: undefined,
|
|
50
|
+
modelRegistry: { getProviderAuthMode: mock.fn(() => undefined) },
|
|
51
|
+
ui: { setStatus: mock.fn(), notify: mock.fn() },
|
|
52
|
+
} as any;
|
|
53
|
+
const pi = makePi([]);
|
|
54
|
+
assert.equal(await awaitWorkflowMcpReadiness(pi, ctx, "/fake/path"), null);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("returns null (ready) when MCP tools are already registered", async () => {
|
|
58
|
+
const ctx = makeCtx();
|
|
59
|
+
const pi = makePi(["read", "bash", "mcp__gsd-workflow__ask_user_questions", "mcp__gsd-workflow__gsd_plan_slice"]);
|
|
60
|
+
assert.equal(await awaitWorkflowMcpReadiness(pi, ctx, "/fake/path"), null);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("returns null (ready) when host system prompt advertises workflow MCP tools", async () => {
|
|
64
|
+
const originalCommand = process.env.GSD_WORKFLOW_MCP_COMMAND;
|
|
65
|
+
const ctx = makeCtx({
|
|
66
|
+
systemPrompt: "Available tools: read, bash, mcp__gsd-workflow__ask_user_questions",
|
|
67
|
+
});
|
|
68
|
+
const pi = makePi(["read", "bash"]);
|
|
69
|
+
try {
|
|
70
|
+
process.env.GSD_WORKFLOW_MCP_COMMAND = "node";
|
|
71
|
+
assert.equal(await awaitWorkflowMcpReadiness(pi, ctx, "/fake/path"), null);
|
|
72
|
+
} finally {
|
|
73
|
+
if (originalCommand === undefined) {
|
|
74
|
+
delete process.env.GSD_WORKFLOW_MCP_COMMAND;
|
|
75
|
+
} else {
|
|
76
|
+
process.env.GSD_WORKFLOW_MCP_COMMAND = originalCommand;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("treats a successful direct probe as readiness when session tools are absent", async () => {
|
|
82
|
+
const previousGsdHome = process.env.GSD_HOME;
|
|
83
|
+
const projectDir = mkdtempSync(join(tmpdir(), "gsd-guided-mcp-probe-project-"));
|
|
84
|
+
const gsdHomeDir = mkdtempSync(join(tmpdir(), "gsd-guided-mcp-probe-home-"));
|
|
85
|
+
try {
|
|
86
|
+
process.env.GSD_HOME = gsdHomeDir;
|
|
87
|
+
mkdirSync(join(projectDir, ".gsd"), { recursive: true });
|
|
88
|
+
|
|
89
|
+
const require = createRequire(import.meta.url);
|
|
90
|
+
const mcpModuleUrl = pathToFileURL(require.resolve("@modelcontextprotocol/sdk/server/mcp.js")).href;
|
|
91
|
+
const stdioModuleUrl = pathToFileURL(require.resolve("@modelcontextprotocol/sdk/server/stdio.js")).href;
|
|
92
|
+
const serverPath = join(projectDir, "fake-workflow-mcp-server.mjs");
|
|
93
|
+
writeFileSync(
|
|
94
|
+
serverPath,
|
|
95
|
+
[
|
|
96
|
+
`const { McpServer } = await import(${JSON.stringify(mcpModuleUrl)});`,
|
|
97
|
+
`const { StdioServerTransport } = await import(${JSON.stringify(stdioModuleUrl)});`,
|
|
98
|
+
'const server = new McpServer({ name: "fake", version: "1.0.0" }, { capabilities: { tools: {} } });',
|
|
99
|
+
'server.tool("gsd_status", "Probe-visible workflow tool", {}, async () => ({ content: [{ type: "text", text: "ok" }] }));',
|
|
100
|
+
'await server.connect(new StdioServerTransport());',
|
|
101
|
+
].join("\n"),
|
|
102
|
+
"utf-8",
|
|
103
|
+
);
|
|
104
|
+
writeFileSync(
|
|
105
|
+
join(projectDir, ".mcp.json"),
|
|
106
|
+
JSON.stringify({ mcpServers: { "gsd-workflow": { command: process.execPath, args: [serverPath] } } }),
|
|
107
|
+
"utf-8",
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const ctx = makeCtx();
|
|
111
|
+
const pi = makePi(["read", "bash"]);
|
|
112
|
+
|
|
113
|
+
assert.equal(
|
|
114
|
+
await awaitWorkflowMcpReadiness(pi, ctx, projectDir, { timeoutMs: 15_000, pollMs: 100 }),
|
|
115
|
+
null,
|
|
116
|
+
);
|
|
117
|
+
} finally {
|
|
118
|
+
if (previousGsdHome === undefined) {
|
|
119
|
+
delete process.env.GSD_HOME;
|
|
120
|
+
} else {
|
|
121
|
+
process.env.GSD_HOME = previousGsdHome;
|
|
122
|
+
}
|
|
123
|
+
rmSync(projectDir, { recursive: true, force: true });
|
|
124
|
+
rmSync(gsdHomeDir, { recursive: true, force: true });
|
|
125
|
+
clearMcpConfigCache();
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test("returns server and probe error when workflow MCP never becomes ready", async () => {
|
|
130
|
+
const originalCommand = process.env.GSD_WORKFLOW_MCP_COMMAND;
|
|
131
|
+
const ctx = makeCtx();
|
|
132
|
+
const pi = makePi(["read", "bash"]);
|
|
133
|
+
try {
|
|
134
|
+
process.env.GSD_WORKFLOW_MCP_COMMAND = "node";
|
|
135
|
+
const failure = await awaitWorkflowMcpReadiness(pi, ctx, "/fake/path", {
|
|
136
|
+
timeoutMs: 5,
|
|
137
|
+
pollMs: 1,
|
|
138
|
+
probe: async () => ({
|
|
139
|
+
ok: false,
|
|
140
|
+
tools: [],
|
|
141
|
+
serverName: "gsd-workflow",
|
|
142
|
+
error: "connection refused",
|
|
143
|
+
}),
|
|
144
|
+
});
|
|
145
|
+
assert.deepEqual(failure, { server: "gsd-workflow", error: "connection refused" });
|
|
146
|
+
assert.ok(ctx.ui.setStatus.mock.calls.length >= 2);
|
|
147
|
+
} finally {
|
|
148
|
+
if (originalCommand === undefined) {
|
|
149
|
+
delete process.env.GSD_WORKFLOW_MCP_COMMAND;
|
|
150
|
+
} else {
|
|
151
|
+
process.env.GSD_WORKFLOW_MCP_COMMAND = originalCommand;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test("returns null (ready) when MCP tools appear during polling", async () => {
|
|
157
|
+
const ctx = makeCtx();
|
|
158
|
+
let callCount = 0;
|
|
159
|
+
const pi = makePi(() => {
|
|
160
|
+
callCount++;
|
|
161
|
+
if (callCount >= 3) return ["mcp__gsd-workflow__gsd_plan_slice"];
|
|
162
|
+
return ["read", "bash"];
|
|
163
|
+
});
|
|
164
|
+
assert.equal(await awaitWorkflowMcpReadiness(pi, ctx, "/fake/path"), null);
|
|
165
|
+
assert.ok(callCount >= 3, `expected at least 3 tool-check calls, got ${callCount}`);
|
|
166
|
+
assert.ok(ctx.ui.setStatus.mock.calls.length >= 2);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test("requires the active unit's workflow tools, not just any MCP workflow tool", async () => {
|
|
170
|
+
const originalCommand = process.env.GSD_WORKFLOW_MCP_COMMAND;
|
|
171
|
+
const ctx = makeCtx();
|
|
172
|
+
const pi = makePi(["read", "bash", "mcp__gsd-workflow__gsd_slice_complete"]);
|
|
173
|
+
try {
|
|
174
|
+
process.env.GSD_WORKFLOW_MCP_COMMAND = "node";
|
|
175
|
+
const failure = await awaitWorkflowMcpReadiness(pi, ctx, "/fake/path", {
|
|
176
|
+
unitType: "complete-slice",
|
|
177
|
+
timeoutMs: 5,
|
|
178
|
+
pollMs: 1,
|
|
179
|
+
probe: async () => ({
|
|
180
|
+
ok: true,
|
|
181
|
+
tools: ["gsd_slice_complete"],
|
|
182
|
+
serverName: "gsd-workflow",
|
|
183
|
+
}),
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
assert.deepEqual(failure, { server: "gsd-workflow" });
|
|
187
|
+
} finally {
|
|
188
|
+
if (originalCommand === undefined) {
|
|
189
|
+
delete process.env.GSD_WORKFLOW_MCP_COMMAND;
|
|
190
|
+
} else {
|
|
191
|
+
process.env.GSD_WORKFLOW_MCP_COMMAND = originalCommand;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test("returns null when no launch config is discoverable", async () => {
|
|
197
|
+
const ctx = makeCtx();
|
|
198
|
+
const pi = makePi(["read", "bash"]);
|
|
199
|
+
const launch = (await import("../workflow-mcp.js")).detectWorkflowMcpLaunchConfig(process.cwd());
|
|
200
|
+
if (!launch) {
|
|
201
|
+
assert.equal(await awaitWorkflowMcpReadiness(pi, ctx, process.cwd()), null);
|
|
202
|
+
}
|
|
203
|
+
// When launch config IS found, the function would timeout (15s) — skip that path in tests.
|
|
204
|
+
});
|
|
205
|
+
});
|
|
@@ -58,13 +58,14 @@ describe("formatMcpStatusReport", () => {
|
|
|
58
58
|
assert.match(result, /disabled/i);
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
-
test("
|
|
61
|
+
test("labels probe-only availability separately from live connections", () => {
|
|
62
62
|
const servers: McpServerStatus[] = [
|
|
63
63
|
{ name: "gsd-workflow", transport: "stdio", connected: false, available: true, toolCount: 62, error: undefined },
|
|
64
64
|
];
|
|
65
65
|
const result = formatMcpStatusReport(servers);
|
|
66
66
|
assert.match(result, /gsd-workflow/);
|
|
67
|
-
assert.match(result, /available — 62 tools/);
|
|
67
|
+
assert.match(result, /probe available — 62 tools/);
|
|
68
|
+
assert.doesNotMatch(result, /connected — 62 tools/);
|
|
68
69
|
assert.doesNotMatch(result, /disconnected/);
|
|
69
70
|
});
|
|
70
71
|
|
|
@@ -132,7 +133,7 @@ describe("formatMcpServerDetail", () => {
|
|
|
132
133
|
assert.match(result, /disconnected/i);
|
|
133
134
|
});
|
|
134
135
|
|
|
135
|
-
test("shows available status with tool names", () => {
|
|
136
|
+
test("shows probe-available status with tool names", () => {
|
|
136
137
|
const result = formatMcpServerDetail({
|
|
137
138
|
name: "gsd-workflow",
|
|
138
139
|
transport: "stdio",
|
|
@@ -142,7 +143,7 @@ describe("formatMcpServerDetail", () => {
|
|
|
142
143
|
tools: ["gsd_milestone_status"],
|
|
143
144
|
error: undefined,
|
|
144
145
|
});
|
|
145
|
-
assert.match(result, /available/i);
|
|
146
|
+
assert.match(result, /probe available/i);
|
|
146
147
|
assert.match(result, /gsd_milestone_status/);
|
|
147
148
|
});
|
|
148
149
|
|
|
@@ -206,7 +207,7 @@ describe("handleMcpStatus", () => {
|
|
|
206
207
|
await handleMcpStatus("status", ctx as unknown as ExtensionCommandContext);
|
|
207
208
|
|
|
208
209
|
assert.match(message, /gsd-workflow/);
|
|
209
|
-
assert.match(message, /available — 1 tools/);
|
|
210
|
+
assert.match(message, /probe available — 1 tools/);
|
|
210
211
|
assert.doesNotMatch(message, /disconnected/);
|
|
211
212
|
} finally {
|
|
212
213
|
process.chdir(originalCwd);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import test from "node:test";
|
|
5
5
|
import assert from "node:assert/strict";
|
|
6
6
|
|
|
7
|
-
import { _runMilestoneMergeWithStashRestore } from "../auto/
|
|
7
|
+
import { _runMilestoneMergeWithStashRestore } from "../auto/closeout.js";
|
|
8
8
|
import type { IterationContext } from "../auto/types.js";
|
|
9
9
|
import { MergeConflictError } from "../git-service.js";
|
|
10
10
|
import type {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { describe, test } from "node:test";
|
|
11
11
|
import assert from "node:assert/strict";
|
|
12
12
|
|
|
13
|
-
import { _resolveDispatchGuardBasePath, _resolveReportBasePath } from "../auto/
|
|
13
|
+
import { _resolveDispatchGuardBasePath, _resolveReportBasePath } from "../auto/phase-helpers.ts";
|
|
14
14
|
|
|
15
15
|
describe("_resolveReportBasePath", () => {
|
|
16
16
|
test("uses originalBasePath when set (worktree scenario)", () => {
|