@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
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
insertSlice,
|
|
22
22
|
insertTask,
|
|
23
23
|
setMilestoneQueueOrder,
|
|
24
|
+
transaction,
|
|
24
25
|
updateTaskStatus,
|
|
25
26
|
} from '../gsd-db.ts';
|
|
26
27
|
|
|
@@ -473,6 +474,31 @@ describe('derive-state-helpers', () => {
|
|
|
473
474
|
}
|
|
474
475
|
});
|
|
475
476
|
|
|
477
|
+
test('setMilestoneQueueOrder can be composed inside a transaction', async () => {
|
|
478
|
+
const base = createFixtureBase();
|
|
479
|
+
try {
|
|
480
|
+
writeFile(base, 'milestones/M001/M001-CONTEXT.md', '# M001\n\nContext.');
|
|
481
|
+
writeFile(base, 'milestones/M002/M002-CONTEXT.md', '# M002\n\nContext.');
|
|
482
|
+
|
|
483
|
+
openDatabase(':memory:');
|
|
484
|
+
insertMilestone({ id: 'M001', title: 'First', status: 'active' });
|
|
485
|
+
insertMilestone({ id: 'M002', title: 'Second', status: 'active' });
|
|
486
|
+
|
|
487
|
+
transaction(() => {
|
|
488
|
+
setMilestoneQueueOrder(['M002', 'M001']);
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
invalidateStateCache();
|
|
492
|
+
const state = await deriveStateFromDb(base);
|
|
493
|
+
|
|
494
|
+
assert.equal(state.activeMilestone?.id, 'M002', 'queue-order: nested transaction chooses M002');
|
|
495
|
+
assert.deepEqual(state.registry.map(entry => entry.id), ['M002', 'M001']);
|
|
496
|
+
} finally {
|
|
497
|
+
closeDatabase();
|
|
498
|
+
cleanup(base);
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
|
|
476
502
|
test('getActiveMilestoneId: DB lock path ignores PARKED flag projection', async () => {
|
|
477
503
|
const base = createFixtureBase();
|
|
478
504
|
const previousLock = process.env.GSD_MILESTONE_LOCK;
|
|
@@ -569,6 +595,42 @@ describe('derive-state-helpers', () => {
|
|
|
569
595
|
}
|
|
570
596
|
});
|
|
571
597
|
|
|
598
|
+
// ─── Batch slice query: multi-milestone slices loaded in one query ─────
|
|
599
|
+
test('buildRegistryAndFindActive: batched slice query preserves ordering across milestones', async () => {
|
|
600
|
+
const base = createFixtureBase();
|
|
601
|
+
try {
|
|
602
|
+
// M001 is complete so the loop advances past it.
|
|
603
|
+
writeFile(base, 'milestones/M001/M001-ROADMAP.md', ROADMAP_CONTENT);
|
|
604
|
+
writeFile(base, 'milestones/M001/M001-SUMMARY.md', '# M001 Summary\n\nDone.');
|
|
605
|
+
// M002 is a queued shell milestone with no context and no slices — should be deferred.
|
|
606
|
+
mkdirSync(join(base, '.gsd', 'milestones', 'M002'), { recursive: true });
|
|
607
|
+
// M003 is the real active milestone with slices in non-trivial sequence order.
|
|
608
|
+
writeFile(base, 'milestones/M003/M003-CONTEXT.md', '# M003: Real\n\nReal milestone.');
|
|
609
|
+
|
|
610
|
+
openDatabase(':memory:');
|
|
611
|
+
insertMilestone({ id: 'M001', title: 'Complete', status: 'complete' });
|
|
612
|
+
insertMilestone({ id: 'M002', title: 'Shell', status: 'queued' });
|
|
613
|
+
insertMilestone({ id: 'M003', title: 'Real', status: 'active' });
|
|
614
|
+
// Slices intentionally inserted with out-of-order sequences to prove ordering.
|
|
615
|
+
insertSlice({ id: 'S01', milestoneId: 'M001', title: 'M1 Second', status: 'complete', risk: 'low', depends: [], sequence: 2 });
|
|
616
|
+
insertSlice({ id: 'S02', milestoneId: 'M001', title: 'M1 First', status: 'complete', risk: 'low', depends: [], sequence: 1 });
|
|
617
|
+
insertSlice({ id: 'S03', milestoneId: 'M003', title: 'M3 Second', status: 'active', risk: 'low', depends: [], sequence: 5 });
|
|
618
|
+
insertSlice({ id: 'S04', milestoneId: 'M003', title: 'M3 First', status: 'active', risk: 'low', depends: [], sequence: 3 });
|
|
619
|
+
|
|
620
|
+
invalidateStateCache();
|
|
621
|
+
const state = await deriveStateFromDb(base);
|
|
622
|
+
|
|
623
|
+
assert.equal(state.activeMilestone?.id, 'M003', 'batched: M003 is active after complete M001 and shell M002');
|
|
624
|
+
assert.equal(state.activeSlice?.id, 'S04', 'batched: first slice by sequence is active');
|
|
625
|
+
assert.equal(state.registry.find(e => e.id === 'M001')?.status, 'complete', 'batched: M001 complete');
|
|
626
|
+
assert.equal(state.registry.find(e => e.id === 'M002')?.status, 'pending', 'batched: shell M002 deferred to pending');
|
|
627
|
+
assert.equal(state.registry.find(e => e.id === 'M003')?.status, 'active', 'batched: M003 active');
|
|
628
|
+
} finally {
|
|
629
|
+
closeDatabase();
|
|
630
|
+
cleanup(base);
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
|
|
572
634
|
// ─── Deferred queued shell: shell milestone deferred, real one promoted ──
|
|
573
635
|
test('buildRegistryAndFindActive: queued shell deferred, later real milestone becomes active (#3470)', async () => {
|
|
574
636
|
const base = createFixtureBase();
|
|
@@ -39,7 +39,11 @@ function makeDiscussPi() {
|
|
|
39
39
|
tmp,
|
|
40
40
|
pi: {
|
|
41
41
|
getActiveTools: () => ["gsd_summary_save", "bash"],
|
|
42
|
+
emitAdjustToolSet: async () => undefined,
|
|
43
|
+
emitBeforeModelSelect: async () => undefined,
|
|
44
|
+
setModel: async () => true,
|
|
42
45
|
setActiveTools: () => {},
|
|
46
|
+
setThinkingLevel: () => {},
|
|
43
47
|
sendMessage: (message: { content?: unknown }) => {
|
|
44
48
|
sent.push(message);
|
|
45
49
|
},
|
|
@@ -53,6 +57,7 @@ function makeDiscussPi() {
|
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
function makeDiscussCtx(notifications: Array<{ message: string; level?: string }> = []) {
|
|
60
|
+
const model = { provider: "anthropic", id: "claude-sonnet-4-6", api: "anthropic-messages" };
|
|
56
61
|
return {
|
|
57
62
|
hasUI: true,
|
|
58
63
|
sessionManager: {
|
|
@@ -65,8 +70,13 @@ function makeDiscussCtx(notifications: Array<{ message: string; level?: string }
|
|
|
65
70
|
setStatus: () => {},
|
|
66
71
|
},
|
|
67
72
|
waitForIdle: async () => {},
|
|
68
|
-
model
|
|
69
|
-
modelRegistry: {
|
|
73
|
+
model,
|
|
74
|
+
modelRegistry: {
|
|
75
|
+
getAvailable: () => [model],
|
|
76
|
+
getAll: () => [model],
|
|
77
|
+
getProviderAuthMode: () => "apiKey",
|
|
78
|
+
isProviderRequestReady: () => true,
|
|
79
|
+
},
|
|
70
80
|
};
|
|
71
81
|
}
|
|
72
82
|
|
|
@@ -23,6 +23,7 @@ import { recordDispatchClaim, markFailed, markCanceled } from "../db/unit-dispat
|
|
|
23
23
|
import {
|
|
24
24
|
buildDispatchKey,
|
|
25
25
|
createDispatchHistory,
|
|
26
|
+
lookupLatestLedgerError,
|
|
26
27
|
normalizeDispatchKey,
|
|
27
28
|
parseDispatchKey,
|
|
28
29
|
STUCK_WINDOW_SIZE,
|
|
@@ -157,6 +158,31 @@ test("recordDispatch attaches the latest ledger error on repeats so repeat-error
|
|
|
157
158
|
assert.match(verdict?.reason ?? "", /Same error repeated/);
|
|
158
159
|
});
|
|
159
160
|
|
|
161
|
+
test("lookupLatestLedgerError matches the bare unit id, not the compound key", (t) => {
|
|
162
|
+
const f = makeLedgerFixture(t);
|
|
163
|
+
const dispatchId = f.claim("execute-task", "M001/S01/T01");
|
|
164
|
+
markFailed(dispatchId, { errorSummary: "boom: deterministic failure" });
|
|
165
|
+
|
|
166
|
+
// The ledger keys rows by the bare unit id with the unit type in its own
|
|
167
|
+
// column. The shared lookup (also used by dispatch.ts's runDispatch path)
|
|
168
|
+
// must use the bare id; a compound `unitType/unitId` value misses entirely,
|
|
169
|
+
// which previously silently dropped repeat-error detection on that path.
|
|
170
|
+
assert.equal(
|
|
171
|
+
lookupLatestLedgerError("execute-task", "M001/S01/T01"),
|
|
172
|
+
"boom: deterministic failure",
|
|
173
|
+
);
|
|
174
|
+
assert.equal(
|
|
175
|
+
lookupLatestLedgerError("execute-task", "execute-task/M001/S01/T01"),
|
|
176
|
+
undefined,
|
|
177
|
+
"a compound key must not match the bare-id ledger row",
|
|
178
|
+
);
|
|
179
|
+
assert.equal(
|
|
180
|
+
lookupLatestLedgerError("plan-slice", "M001/S01/T01"),
|
|
181
|
+
undefined,
|
|
182
|
+
"a different unit type on the same id must not be attached",
|
|
183
|
+
);
|
|
184
|
+
});
|
|
185
|
+
|
|
160
186
|
test("recordDispatch never attaches another unit type's ledger error for the same unit id", (t) => {
|
|
161
187
|
const f = makeLedgerFixture(t);
|
|
162
188
|
const dispatchId = f.claim("plan-slice", "M001/S01");
|
|
@@ -262,6 +288,35 @@ test("#482 regression: a re-dispatch loop spanning a session restart is detected
|
|
|
262
288
|
assert.match(verdict?.reason ?? "", /execute-task:M001\/S01\/T01 derived 3 consecutive times/);
|
|
263
289
|
});
|
|
264
290
|
|
|
291
|
+
test("rehydrate mirrors recordDispatch error attachment so repeat-error detection fires after the next dispatch", (t) => {
|
|
292
|
+
const f = makeLedgerFixture(t);
|
|
293
|
+
// Session 1: two failed dispatches for the same unit, same error summary.
|
|
294
|
+
for (let i = 0; i < 2; i++) {
|
|
295
|
+
const id = f.claim("execute-task", "M001/S01/T01");
|
|
296
|
+
markFailed(id, { errorSummary: "boom: deterministic failure" });
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Session 2: fresh history rehydrates from the ledger. Just like the live
|
|
300
|
+
// recordDispatch path, the first occurrence of a unit skips the ledger
|
|
301
|
+
// lookup; only repeats carry the error. So rehydration alone does not trip
|
|
302
|
+
// Rule 1 — keeping the post-restart window no more aggressive than the live
|
|
303
|
+
// one (Rule 1 has no retry-budget suppression).
|
|
304
|
+
const restarted = historyFor(f.base);
|
|
305
|
+
const count = restarted.rehydrate();
|
|
306
|
+
assert.equal(count, 2);
|
|
307
|
+
const window = restarted.getRecentWindow();
|
|
308
|
+
assert.equal(window[0].error, undefined);
|
|
309
|
+
assert.equal(window[1].error, "boom: deterministic failure");
|
|
310
|
+
assert.equal(restarted.detectStuck(), null);
|
|
311
|
+
|
|
312
|
+
// The next dispatch of the same unit attaches the error again, giving two
|
|
313
|
+
// consecutive matching errors → Rule 1 fires, exactly as in the live path.
|
|
314
|
+
restarted.recordDispatch("execute-task", "M001/S01/T01");
|
|
315
|
+
const verdict = restarted.detectStuck();
|
|
316
|
+
assert.equal(verdict?.stuck, true);
|
|
317
|
+
assert.match(verdict?.reason ?? "", /Same error repeated/);
|
|
318
|
+
});
|
|
319
|
+
|
|
265
320
|
test("rehydrate degrades to an empty window without a scope or ledger", () => {
|
|
266
321
|
const noScope = historyFor(null);
|
|
267
322
|
assert.equal(noScope.rehydrate(), 0);
|
|
@@ -7,6 +7,10 @@ const require = createRequire(import.meta.url);
|
|
|
7
7
|
const ROOT = new URL("../../../../../", import.meta.url);
|
|
8
8
|
|
|
9
9
|
export function resolve(specifier, context, nextResolve) {
|
|
10
|
+
if (specifier.startsWith('node:')) {
|
|
11
|
+
return { url: specifier, format: 'builtin', shortCircuit: true };
|
|
12
|
+
}
|
|
13
|
+
|
|
10
14
|
// 1. Redirect all workspace package bare imports to source.
|
|
11
15
|
// CI portability runs don't build any packages/ dist artifacts, so every
|
|
12
16
|
// @gsd/* specifier (including transitive ones pulled in by pi-coding-agent
|
|
@@ -100,6 +104,10 @@ export function resolve(specifier, context, nextResolve) {
|
|
|
100
104
|
}
|
|
101
105
|
|
|
102
106
|
export function load(url, context, nextLoad) {
|
|
107
|
+
if (url.startsWith('node:') || context.format === 'builtin') {
|
|
108
|
+
return { format: 'builtin', source: '', shortCircuit: true };
|
|
109
|
+
}
|
|
110
|
+
|
|
103
111
|
// jiti/CJS may still enter through stale packages/*/dist/index.js — redirect to src.
|
|
104
112
|
if (url.includes('/packages/pi-ai/dist/index.js')) {
|
|
105
113
|
url = url.replace('/dist/index.js', '/src/index.ts');
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* engine-interfaces-contract.test.ts —
|
|
3
|
-
* engine abstraction layer (S01).
|
|
2
|
+
* engine-interfaces-contract.test.ts — Runtime and type-level contract tests for
|
|
3
|
+
* the engine abstraction layer (S01).
|
|
4
4
|
*
|
|
5
|
-
* TypeScript interfaces are erased by --experimental-strip-types, so
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* TypeScript interfaces are erased by --experimental-strip-types, so shape
|
|
6
|
+
* contracts are verified by constructing values that satisfy the types and
|
|
7
|
+
* asserting on their runtime fields. Type-level assertions guard compile-time
|
|
8
|
+
* contracts; pnpm run typecheck:extensions validates those.
|
|
8
9
|
*
|
|
9
10
|
* Follows the same conventions as auto-session-encapsulation.test.ts.
|
|
10
11
|
*/
|
|
@@ -15,15 +16,21 @@ import { readFileSync } from "node:fs";
|
|
|
15
16
|
import { join, dirname } from "node:path";
|
|
16
17
|
import { fileURLToPath } from "node:url";
|
|
17
18
|
|
|
19
|
+
import type {
|
|
20
|
+
EngineState,
|
|
21
|
+
EngineDispatchAction,
|
|
22
|
+
StepContract,
|
|
23
|
+
ReconcileResult,
|
|
24
|
+
RecoveryAction,
|
|
25
|
+
CloseoutResult,
|
|
26
|
+
DisplayMetadata,
|
|
27
|
+
} from "../engine-types.js";
|
|
28
|
+
import type { WorkflowEngine } from "../workflow-engine.js";
|
|
29
|
+
import type { ExecutionPolicy } from "../execution-policy.js";
|
|
30
|
+
import type { ResolvedEngine } from "../engine-resolver.js";
|
|
31
|
+
|
|
18
32
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
19
33
|
const ENGINE_TYPES_PATH = join(__dirname, "..", "engine-types.ts");
|
|
20
|
-
const WORKFLOW_ENGINE_PATH = join(__dirname, "..", "workflow-engine.ts");
|
|
21
|
-
const EXECUTION_POLICY_PATH = join(__dirname, "..", "execution-policy.ts");
|
|
22
|
-
const ENGINE_RESOLVER_PATH = join(__dirname, "..", "engine-resolver.ts");
|
|
23
|
-
|
|
24
|
-
function readSource(path: string): string {
|
|
25
|
-
return readFileSync(path, "utf-8");
|
|
26
|
-
}
|
|
27
34
|
|
|
28
35
|
// ── Import smoke tests ──────────────────────────────────────────────────────
|
|
29
36
|
|
|
@@ -55,9 +62,10 @@ describe("Import smoke tests", () => {
|
|
|
55
62
|
|
|
56
63
|
// ── Leaf-node constraint ────────────────────────────────────────────────────
|
|
57
64
|
|
|
65
|
+
// allow-source-grep: verifies engine-types.ts is a leaf node by design
|
|
58
66
|
describe("Leaf-node constraint", () => {
|
|
59
67
|
test("engine-types.ts has zero imports from GSD modules (only node: allowed)", () => {
|
|
60
|
-
const source =
|
|
68
|
+
const source = readFileSync(ENGINE_TYPES_PATH, "utf-8");
|
|
61
69
|
const lines = source.split("\n");
|
|
62
70
|
const violations: string[] = [];
|
|
63
71
|
|
|
@@ -81,97 +89,111 @@ describe("Leaf-node constraint", () => {
|
|
|
81
89
|
// ── EngineState shape ───────────────────────────────────────────────────────
|
|
82
90
|
|
|
83
91
|
describe("EngineState shape", () => {
|
|
84
|
-
test("EngineState
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
|
|
91
|
-
"
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
92
|
+
test("EngineState accepts all required fields with correct runtime types", () => {
|
|
93
|
+
const state: EngineState = {
|
|
94
|
+
phase: "research",
|
|
95
|
+
currentMilestoneId: "M001",
|
|
96
|
+
activeSliceId: "S01",
|
|
97
|
+
activeTaskId: "T01",
|
|
98
|
+
isComplete: false,
|
|
99
|
+
raw: { arbitrary: "engine-specific-state" },
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
assert.equal(state.phase, "research");
|
|
103
|
+
assert.equal(state.currentMilestoneId, "M001");
|
|
104
|
+
assert.equal(state.activeSliceId, "S01");
|
|
105
|
+
assert.equal(state.activeTaskId, "T01");
|
|
106
|
+
assert.equal(state.isComplete, false);
|
|
107
|
+
assert.deepEqual(state.raw, { arbitrary: "engine-specific-state" });
|
|
108
|
+
});
|
|
102
109
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
test("EngineState.raw accepts unknown opaque values", () => {
|
|
111
|
+
const state: EngineState = {
|
|
112
|
+
phase: "planning",
|
|
113
|
+
currentMilestoneId: null,
|
|
114
|
+
activeSliceId: null,
|
|
115
|
+
activeTaskId: null,
|
|
116
|
+
isComplete: true,
|
|
117
|
+
raw: null,
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
assert.equal(state.raw, null);
|
|
108
121
|
});
|
|
109
122
|
});
|
|
110
123
|
|
|
111
124
|
// ── EngineDispatchAction shape ──────────────────────────────────────────────
|
|
112
125
|
|
|
113
126
|
describe("EngineDispatchAction shape", () => {
|
|
114
|
-
test("EngineDispatchAction
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
);
|
|
127
|
+
test("EngineDispatchAction supports dispatch, stop, and skip variants at runtime", () => {
|
|
128
|
+
const step: StepContract = {
|
|
129
|
+
unitType: "execute-task",
|
|
130
|
+
unitId: "M001/S01/T01",
|
|
131
|
+
prompt: "execute the task",
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const dispatchAction: EngineDispatchAction = { action: "dispatch", step };
|
|
135
|
+
assert.equal(dispatchAction.action, "dispatch");
|
|
136
|
+
assert.deepEqual(dispatchAction.step, step);
|
|
137
|
+
|
|
138
|
+
const stopAction: EngineDispatchAction = { action: "stop", reason: "blocked", level: "error" };
|
|
139
|
+
assert.equal(stopAction.action, "stop");
|
|
140
|
+
assert.equal(stopAction.reason, "blocked");
|
|
141
|
+
assert.equal(stopAction.level, "error");
|
|
142
|
+
|
|
143
|
+
const skipAction: EngineDispatchAction = { action: "skip" };
|
|
144
|
+
assert.equal(skipAction.action, "skip");
|
|
129
145
|
});
|
|
130
146
|
});
|
|
131
147
|
|
|
132
148
|
// ── WorkflowEngine interface shape ──────────────────────────────────────────
|
|
133
149
|
|
|
134
150
|
describe("WorkflowEngine interface shape", () => {
|
|
135
|
-
test("WorkflowEngine
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
151
|
+
test("WorkflowEngine accepts an object with engineId and all required methods", () => {
|
|
152
|
+
const engine: WorkflowEngine = {
|
|
153
|
+
engineId: "test-engine",
|
|
154
|
+
deriveState: async () => ({
|
|
155
|
+
phase: "test",
|
|
156
|
+
currentMilestoneId: null,
|
|
157
|
+
activeSliceId: null,
|
|
158
|
+
activeTaskId: null,
|
|
159
|
+
isComplete: false,
|
|
160
|
+
raw: null,
|
|
161
|
+
}),
|
|
162
|
+
resolveDispatch: async () => ({ action: "skip" }),
|
|
163
|
+
reconcile: async () => ({ outcome: "continue" }),
|
|
164
|
+
getDisplayMetadata: () => ({
|
|
165
|
+
engineLabel: "Test Engine",
|
|
166
|
+
currentPhase: "test",
|
|
167
|
+
progressSummary: "testing",
|
|
168
|
+
stepCount: null,
|
|
169
|
+
}),
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
assert.equal(engine.engineId, "test-engine");
|
|
173
|
+
assert.equal(typeof engine.deriveState, "function");
|
|
174
|
+
assert.equal(typeof engine.resolveDispatch, "function");
|
|
175
|
+
assert.equal(typeof engine.reconcile, "function");
|
|
176
|
+
assert.equal(typeof engine.getDisplayMetadata, "function");
|
|
152
177
|
});
|
|
153
178
|
});
|
|
154
179
|
|
|
155
180
|
// ── ExecutionPolicy interface shape ─────────────────────────────────────────
|
|
156
181
|
|
|
157
182
|
describe("ExecutionPolicy interface shape", () => {
|
|
158
|
-
test("ExecutionPolicy
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
"
|
|
163
|
-
"
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
`ExecutionPolicy must contain method: ${method}`,
|
|
173
|
-
);
|
|
174
|
-
}
|
|
183
|
+
test("ExecutionPolicy accepts an object with all required methods", () => {
|
|
184
|
+
const policy: ExecutionPolicy = {
|
|
185
|
+
prepareWorkspace: async () => {},
|
|
186
|
+
selectModel: async () => null,
|
|
187
|
+
verify: async () => "continue",
|
|
188
|
+
recover: async () => ({ outcome: "retry" } as RecoveryAction),
|
|
189
|
+
closeout: async () => ({ committed: true, artifacts: [] } as CloseoutResult),
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
assert.equal(typeof policy.prepareWorkspace, "function");
|
|
193
|
+
assert.equal(typeof policy.selectModel, "function");
|
|
194
|
+
assert.equal(typeof policy.verify, "function");
|
|
195
|
+
assert.equal(typeof policy.recover, "function");
|
|
196
|
+
assert.equal(typeof policy.closeout, "function");
|
|
175
197
|
});
|
|
176
198
|
});
|
|
177
199
|
|
|
@@ -220,12 +242,16 @@ describe("Resolver stub behavior", () => {
|
|
|
220
242
|
);
|
|
221
243
|
});
|
|
222
244
|
|
|
223
|
-
test("ResolvedEngine type is exported
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
245
|
+
test("ResolvedEngine type is exported and has the expected shape", () => {
|
|
246
|
+
// Type-level assertion: ResolvedEngine must be { engine: WorkflowEngine; policy: ExecutionPolicy }.
|
|
247
|
+
// If the export or shape changes, the typecheck step fails.
|
|
248
|
+
type _AssertResolvedEngine = ResolvedEngine extends { engine: WorkflowEngine; policy: ExecutionPolicy }
|
|
249
|
+
? true
|
|
250
|
+
: false;
|
|
251
|
+
const _assertResolvedEngine: true = {} as _AssertResolvedEngine;
|
|
252
|
+
|
|
253
|
+
// Runtime sanity check that the import path resolves.
|
|
254
|
+
assert.ok(_assertResolvedEngine === undefined || true);
|
|
229
255
|
});
|
|
230
256
|
});
|
|
231
257
|
|
|
@@ -11,7 +11,10 @@ import * as path from 'node:path';
|
|
|
11
11
|
import * as os from 'node:os';
|
|
12
12
|
import * as fs from 'node:fs';
|
|
13
13
|
import { createRequire } from 'node:module';
|
|
14
|
+
import { spawnSync } from 'node:child_process';
|
|
15
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
14
16
|
import { closeDatabase, isDbAvailable, getDecisionById, SCHEMA_VERSION, _getAdapter } from '../gsd-db.ts';
|
|
17
|
+
import { formatWorkflowDatabaseOpenFailure } from '../bootstrap/dynamic-tools.ts';
|
|
15
18
|
|
|
16
19
|
const _require = createRequire(import.meta.url);
|
|
17
20
|
|
|
@@ -288,6 +291,116 @@ function createLegacyV15Db(dbPath: string): void {
|
|
|
288
291
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
289
292
|
|
|
290
293
|
describe('ensure-db-open', () => {
|
|
294
|
+
test('formatWorkflowDatabaseOpenFailure: open failure without provider gives actionable SQLite guidance', () => {
|
|
295
|
+
const message = formatWorkflowDatabaseOpenFailure(
|
|
296
|
+
{
|
|
297
|
+
ok: false,
|
|
298
|
+
reason: 'open-failed',
|
|
299
|
+
location: {
|
|
300
|
+
projectRoot: '/tmp/example',
|
|
301
|
+
projectGsd: '/tmp/example/.gsd',
|
|
302
|
+
projectDb: '/tmp/example/.gsd/gsd.db',
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
available: false,
|
|
307
|
+
provider: null,
|
|
308
|
+
attempted: true,
|
|
309
|
+
lastError: null,
|
|
310
|
+
lastPhase: null,
|
|
311
|
+
},
|
|
312
|
+
'22.15.0',
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
assert.match(message, /\/tmp\/example\/\.gsd\/gsd\.db/);
|
|
316
|
+
assert.match(message, /No SQLite provider available/);
|
|
317
|
+
assert.match(message, /node:sqlite/);
|
|
318
|
+
assert.match(message, /better-sqlite3/);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
test('formatWorkflowDatabaseOpenFailure: old Node includes upgrade guidance', () => {
|
|
322
|
+
const message = formatWorkflowDatabaseOpenFailure(
|
|
323
|
+
{
|
|
324
|
+
ok: false,
|
|
325
|
+
reason: 'open-failed',
|
|
326
|
+
location: {
|
|
327
|
+
projectRoot: '/tmp/example',
|
|
328
|
+
projectGsd: '/tmp/example/.gsd',
|
|
329
|
+
projectDb: '/tmp/example/.gsd/gsd.db',
|
|
330
|
+
},
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
available: false,
|
|
334
|
+
provider: null,
|
|
335
|
+
attempted: true,
|
|
336
|
+
lastError: null,
|
|
337
|
+
lastPhase: null,
|
|
338
|
+
},
|
|
339
|
+
'20.11.1',
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
assert.match(message, />= 22\.0\.0/);
|
|
343
|
+
assert.match(message, /current: v20\.11\.1/);
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
test('ensureDbOpen: source-mode runtime without node:sqlite records actionable guidance', () => {
|
|
347
|
+
const loaderPath = fileURLToPath(new URL('./resolve-ts.mjs', import.meta.url));
|
|
348
|
+
const runningFromDistTest = fileURLToPath(import.meta.url).includes(`${path.sep}dist-test${path.sep}`);
|
|
349
|
+
const dynamicToolsImportUrl = pathToFileURL(
|
|
350
|
+
path.resolve(
|
|
351
|
+
runningFromDistTest
|
|
352
|
+
? 'dist-test/src/resources/extensions/gsd/bootstrap/dynamic-tools.js'
|
|
353
|
+
: 'src/resources/extensions/gsd/bootstrap/dynamic-tools.ts',
|
|
354
|
+
),
|
|
355
|
+
).href;
|
|
356
|
+
const loggerImportUrl = pathToFileURL(
|
|
357
|
+
path.resolve(
|
|
358
|
+
runningFromDistTest
|
|
359
|
+
? 'dist-test/src/resources/extensions/gsd/workflow-logger.ts'
|
|
360
|
+
: 'src/resources/extensions/gsd/workflow-logger.ts',
|
|
361
|
+
),
|
|
362
|
+
).href;
|
|
363
|
+
const script = `
|
|
364
|
+
const fs = require('node:fs');
|
|
365
|
+
const os = require('node:os');
|
|
366
|
+
const path = require('node:path');
|
|
367
|
+
(async () => {
|
|
368
|
+
const base = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-missing-sqlite-'));
|
|
369
|
+
try {
|
|
370
|
+
fs.mkdirSync(path.join(base, '.gsd'), { recursive: true });
|
|
371
|
+
const dynamicTools = await import(${JSON.stringify(dynamicToolsImportUrl)});
|
|
372
|
+
const logger = await import(${JSON.stringify(loggerImportUrl)});
|
|
373
|
+
await dynamicTools.ensureDbOpen(base);
|
|
374
|
+
const messages = logger.peekLogs().map((entry) => entry.message);
|
|
375
|
+
console.log(JSON.stringify(messages));
|
|
376
|
+
} finally {
|
|
377
|
+
fs.rmSync(base, { recursive: true, force: true });
|
|
378
|
+
}
|
|
379
|
+
})().catch((error) => {
|
|
380
|
+
console.error(error.stack || error.message || String(error));
|
|
381
|
+
process.exit(1);
|
|
382
|
+
});
|
|
383
|
+
`;
|
|
384
|
+
const result = spawnSync(
|
|
385
|
+
process.execPath,
|
|
386
|
+
[
|
|
387
|
+
'--no-experimental-sqlite',
|
|
388
|
+
'--import',
|
|
389
|
+
loaderPath,
|
|
390
|
+
'--experimental-strip-types',
|
|
391
|
+
'-e',
|
|
392
|
+
script,
|
|
393
|
+
],
|
|
394
|
+
{ cwd: process.cwd(), encoding: 'utf-8' },
|
|
395
|
+
);
|
|
396
|
+
|
|
397
|
+
assert.equal(result.status, 0, result.stderr);
|
|
398
|
+
const messages = JSON.parse(result.stdout.trim()) as string[];
|
|
399
|
+
assert.ok(messages.some((message) => /No SQLite provider available/.test(message)), result.stdout);
|
|
400
|
+
assert.ok(messages.some((message) => /node:sqlite/.test(message)), result.stdout);
|
|
401
|
+
assert.ok(messages.some((message) => /better-sqlite3/.test(message)), result.stdout);
|
|
402
|
+
});
|
|
403
|
+
|
|
291
404
|
test('ensureDbOpen: creates empty DB without importing Markdown', async () => {
|
|
292
405
|
const tmpDir = makeTmpDir();
|
|
293
406
|
const gsdDir = path.join(tmpDir, '.gsd');
|
|
@@ -41,7 +41,9 @@ import {
|
|
|
41
41
|
refreshOpenDatabaseFromDisk,
|
|
42
42
|
tryCreateMemoriesFts,
|
|
43
43
|
_isLikelyWslDrvFsPathForTest,
|
|
44
|
+
_shouldAttemptVacuumRecoveryForTest,
|
|
44
45
|
} from '../gsd-db.ts';
|
|
46
|
+
import { MigrationBackupError } from '../db-migration-backup.ts';
|
|
45
47
|
import { _resetLogs, peekLogs, setStderrLoggingEnabled } from '../workflow-logger.ts';
|
|
46
48
|
|
|
47
49
|
const _require = createRequire(import.meta.url);
|
|
@@ -539,6 +541,23 @@ describe('gsd-db', () => {
|
|
|
539
541
|
cleanup(dbPath);
|
|
540
542
|
});
|
|
541
543
|
|
|
544
|
+
test('gsd-db: migration backup errors bypass malformed-DB VACUUM recovery', () => {
|
|
545
|
+
assert.equal(
|
|
546
|
+
_shouldAttemptVacuumRecoveryForTest(
|
|
547
|
+
true,
|
|
548
|
+
new MigrationBackupError('database disk image is malformed during backup'),
|
|
549
|
+
),
|
|
550
|
+
false,
|
|
551
|
+
);
|
|
552
|
+
assert.equal(
|
|
553
|
+
_shouldAttemptVacuumRecoveryForTest(
|
|
554
|
+
true,
|
|
555
|
+
new Error('database disk image is malformed'),
|
|
556
|
+
),
|
|
557
|
+
true,
|
|
558
|
+
);
|
|
559
|
+
});
|
|
560
|
+
|
|
542
561
|
test('gsd-db: pre-v18 DB with memory_sources missing scope opens without crash (issue #4607)', () => {
|
|
543
562
|
// Regression: initSchema() ran CREATE INDEX on memories.scope and
|
|
544
563
|
// memory_sources.scope unconditionally, before the v18 migration adds those
|