gsd-pi 2.79.0-dev.ece5fd8ba → 2.80.0-dev.c5f2443b3
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/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/github-sync/templates.js +55 -70
- package/dist/resources/extensions/gsd/auto/contracts.js +1 -0
- package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +53 -0
- package/dist/resources/extensions/gsd/auto/loop.js +359 -523
- package/dist/resources/extensions/gsd/auto/orchestrator.js +146 -0
- package/dist/resources/extensions/gsd/auto/phases.js +55 -6
- package/dist/resources/extensions/gsd/auto/session.js +8 -0
- package/dist/resources/extensions/gsd/auto/workflow-custom-engine-dispatch-outcome.js +12 -0
- package/dist/resources/extensions/gsd/auto/workflow-custom-engine-iteration.js +24 -0
- package/dist/resources/extensions/gsd/auto/workflow-custom-engine-reconcile-outcome.js +33 -0
- package/dist/resources/extensions/gsd/auto/workflow-custom-engine-reconcile.js +26 -0
- package/dist/resources/extensions/gsd/auto/workflow-custom-engine-retry.js +49 -0
- package/dist/resources/extensions/gsd/auto/workflow-custom-engine-verify-outcome.js +25 -0
- package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +48 -0
- package/dist/resources/extensions/gsd/auto/workflow-dispatch-ledger.js +26 -0
- package/dist/resources/extensions/gsd/auto/workflow-iteration-completion.js +10 -0
- package/dist/resources/extensions/gsd/auto/workflow-journal-reporter.js +16 -0
- package/dist/resources/extensions/gsd/auto/workflow-kernel.js +263 -0
- package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +36 -0
- package/dist/resources/extensions/gsd/auto/workflow-phase-reporter.js +9 -0
- package/dist/resources/extensions/gsd/auto/workflow-session-lock.js +35 -0
- package/dist/resources/extensions/gsd/auto/workflow-sidecar-iteration.js +24 -0
- package/dist/resources/extensions/gsd/auto/workflow-sidecar-queue.js +26 -0
- package/dist/resources/extensions/gsd/auto/workflow-turn-reporter.js +36 -0
- package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +44 -0
- package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +15 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +3 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +168 -3
- package/dist/resources/extensions/gsd/auto-recovery.js +45 -52
- package/dist/resources/extensions/gsd/auto-runtime-state.js +4 -0
- package/dist/resources/extensions/gsd/auto-verification.js +2 -11
- package/dist/resources/extensions/gsd/auto-worktree.js +87 -38
- package/dist/resources/extensions/gsd/auto.js +159 -2
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +9 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +10 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +11 -5
- package/dist/resources/extensions/gsd/commands-ship.js +23 -46
- package/dist/resources/extensions/gsd/commands-workflow-templates.js +12 -7
- package/dist/resources/extensions/gsd/component-loader.js +5 -11
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +4 -0
- package/dist/resources/extensions/gsd/db-adapter.js +47 -0
- package/dist/resources/extensions/gsd/db-base-schema.js +337 -0
- package/dist/resources/extensions/gsd/db-connection-cache.js +31 -0
- package/dist/resources/extensions/gsd/db-coordination-schema.js +104 -0
- package/dist/resources/extensions/gsd/db-decision-requirement-rows.js +71 -0
- package/dist/resources/extensions/gsd/db-gate-rows.js +16 -0
- package/dist/resources/extensions/gsd/db-lightweight-query-rows.js +29 -0
- package/dist/resources/extensions/gsd/db-memory-fts-schema.js +56 -0
- package/dist/resources/extensions/gsd/db-migration-backup.js +22 -0
- package/dist/resources/extensions/gsd/db-migration-steps.js +394 -0
- package/dist/resources/extensions/gsd/db-milestone-artifact-rows.js +35 -0
- package/dist/resources/extensions/gsd/db-open-state.js +32 -0
- package/dist/resources/extensions/gsd/db-provider.js +108 -0
- package/dist/resources/extensions/gsd/db-runtime-kv-schema.js +27 -0
- package/dist/resources/extensions/gsd/db-schema-metadata.js +23 -0
- package/dist/resources/extensions/gsd/db-task-slice-rows.js +86 -0
- package/dist/resources/extensions/gsd/db-transaction.js +63 -0
- package/dist/resources/extensions/gsd/db-verification-evidence-rows.js +3 -0
- package/dist/resources/extensions/gsd/db-verification-evidence-schema.js +19 -0
- package/dist/resources/extensions/gsd/escalation.js +2 -0
- package/dist/resources/extensions/gsd/gsd-db.js +215 -1519
- package/dist/resources/extensions/gsd/legacy-telemetry.js +70 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +2 -0
- package/dist/resources/extensions/gsd/model-router.js +9 -6
- package/dist/resources/extensions/gsd/notification-widget.js +21 -3
- package/dist/resources/extensions/gsd/post-execution-checks.js +27 -6
- package/dist/resources/extensions/gsd/pr-evidence.js +76 -0
- package/dist/resources/extensions/gsd/pre-execution-checks.js +2 -0
- package/dist/resources/extensions/gsd/process-task-path.js +61 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +9 -5
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +32 -30
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +23 -34
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +50 -96
- package/dist/resources/extensions/gsd/prompts/discuss.md +81 -181
- package/dist/resources/extensions/gsd/prompts/execute-task.md +40 -67
- package/dist/resources/extensions/gsd/prompts/forensics.md +41 -84
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +29 -39
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +30 -65
- package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +25 -52
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +36 -36
- package/dist/resources/extensions/gsd/prompts/guided-research-project.md +20 -38
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +45 -59
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +25 -87
- package/dist/resources/extensions/gsd/prompts/queue.md +46 -53
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +23 -23
- package/dist/resources/extensions/gsd/prompts/research-slice.md +23 -23
- package/dist/resources/extensions/gsd/prompts/rethink.md +10 -10
- package/dist/resources/extensions/gsd/prompts/system.md +65 -107
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +15 -15
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +24 -24
- package/dist/resources/extensions/gsd/prompts/worktree-merge.md +35 -35
- package/dist/resources/extensions/gsd/state.js +4 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +14 -9
- package/dist/resources/extensions/gsd/tools/complete-task.js +2 -0
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +6 -1
- package/dist/resources/extensions/gsd/unit-context-composer.js +1 -1
- package/dist/resources/extensions/gsd/uok/kernel.js +8 -3
- package/dist/resources/extensions/gsd/uok/plan-v2.js +2 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +13 -13
- package/dist/resources/extensions/gsd/workflow-manifest.js +2 -0
- package/dist/resources/extensions/gsd/workflow-projections.js +2 -0
- package/dist/resources/extensions/gsd/workflow-templates.js +9 -0
- package/dist/resources/extensions/shared/interview-ui.js +15 -4
- 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 +13 -13
- 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/required-server-files.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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/notifications/route.js +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 +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 +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 +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 +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 +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 +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 +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 +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/skill-health/route.js +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 +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 +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 +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 +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 +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 +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 +13 -13
- package/dist/web/standalone/.next/server/chunks/167.js +2 -0
- package/dist/web/standalone/.next/server/chunks/6897.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/package.json +1 -0
- package/dist/web/standalone/server.js +1 -1
- package/package.json +9 -2
- package/packages/contracts/dist/index.d.ts +3 -0
- package/packages/contracts/dist/index.d.ts.map +1 -0
- package/packages/contracts/dist/index.js +5 -0
- package/packages/contracts/dist/index.js.map +1 -0
- package/packages/contracts/dist/rpc.d.ts +549 -0
- package/packages/contracts/dist/rpc.d.ts.map +1 -0
- package/packages/contracts/dist/rpc.js +53 -0
- package/packages/contracts/dist/rpc.js.map +1 -0
- package/packages/contracts/dist/rpc.test.d.ts +2 -0
- package/packages/contracts/dist/rpc.test.d.ts.map +1 -0
- package/packages/contracts/dist/rpc.test.js +47 -0
- package/packages/contracts/dist/rpc.test.js.map +1 -0
- package/packages/contracts/dist/workflow.d.ts +180 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -0
- package/packages/contracts/dist/workflow.js +201 -0
- package/packages/contracts/dist/workflow.js.map +1 -0
- package/packages/contracts/package.json +39 -0
- package/packages/contracts/src/index.ts +5 -0
- package/packages/contracts/src/rpc.test.ts +72 -0
- package/packages/contracts/src/rpc.ts +286 -0
- package/packages/contracts/src/workflow.ts +213 -0
- package/packages/contracts/tsconfig.json +25 -0
- package/packages/contracts/tsconfig.tsbuildinfo +1 -0
- package/packages/daemon/package.json +3 -2
- package/packages/daemon/src/event-bridge.test.ts +2 -1
- package/packages/daemon/src/event-bridge.ts +1 -1
- package/packages/daemon/src/event-formatter.test.ts +1 -2
- package/packages/daemon/src/event-formatter.ts +1 -2
- package/packages/daemon/src/session-manager.ts +2 -2
- package/packages/daemon/src/types.ts +3 -18
- package/packages/mcp-server/dist/server.d.ts +13 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +77 -0
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/session-manager.js +1 -1
- package/packages/mcp-server/dist/session-manager.js.map +1 -1
- package/packages/mcp-server/dist/types.d.ts +3 -11
- package/packages/mcp-server/dist/types.d.ts.map +1 -1
- package/packages/mcp-server/dist/types.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +2 -40
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -2
- package/packages/mcp-server/src/mcp-server.test.ts +138 -0
- package/packages/mcp-server/src/server.ts +99 -1
- package/packages/mcp-server/src/session-manager.ts +2 -2
- package/packages/mcp-server/src/types.ts +7 -18
- package/packages/mcp-server/src/workflow-tools.ts +2 -40
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +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/modes/interactive/components/__tests__/tool-execution.test.js +14 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +20 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +6 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +9 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +31 -10
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +1 -512
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js +3 -7
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
- package/packages/pi-coding-agent/package.json +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +23 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +31 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +6 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +50 -9
- package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +3 -336
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/tui.d.ts +1 -0
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +8 -2
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/tui.ts +8 -2
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/README.md +3 -3
- package/packages/rpc-client/dist/index.d.ts +1 -1
- package/packages/rpc-client/dist/index.d.ts.map +1 -1
- package/packages/rpc-client/dist/index.js.map +1 -1
- package/packages/rpc-client/dist/rpc-client.d.ts +2 -6
- package/packages/rpc-client/dist/rpc-client.d.ts.map +1 -1
- package/packages/rpc-client/dist/rpc-client.js.map +1 -1
- package/packages/rpc-client/dist/rpc-types.d.ts +1 -565
- package/packages/rpc-client/dist/rpc-types.d.ts.map +1 -1
- package/packages/rpc-client/dist/rpc-types.js +3 -11
- package/packages/rpc-client/dist/rpc-types.js.map +1 -1
- package/packages/rpc-client/package.json +4 -1
- package/packages/rpc-client/src/index.ts +1 -1
- package/packages/rpc-client/src/rpc-client.ts +3 -6
- package/packages/rpc-client/src/rpc-types.ts +3 -398
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/extensions/github-sync/templates.ts +59 -84
- package/src/resources/extensions/github-sync/tests/templates.test.ts +10 -2
- package/src/resources/extensions/gsd/auto/contracts.ts +87 -0
- package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +72 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +10 -3
- package/src/resources/extensions/gsd/auto/loop.ts +411 -598
- package/src/resources/extensions/gsd/auto/orchestrator.ts +161 -0
- package/src/resources/extensions/gsd/auto/phases.ts +82 -8
- package/src/resources/extensions/gsd/auto/session.ts +11 -0
- package/src/resources/extensions/gsd/auto/workflow-custom-engine-dispatch-outcome.ts +28 -0
- package/src/resources/extensions/gsd/auto/workflow-custom-engine-iteration.ts +52 -0
- package/src/resources/extensions/gsd/auto/workflow-custom-engine-reconcile-outcome.ts +58 -0
- package/src/resources/extensions/gsd/auto/workflow-custom-engine-reconcile.ts +71 -0
- package/src/resources/extensions/gsd/auto/workflow-custom-engine-retry.ts +90 -0
- package/src/resources/extensions/gsd/auto/workflow-custom-engine-verify-outcome.ts +50 -0
- package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +97 -0
- package/src/resources/extensions/gsd/auto/workflow-dispatch-ledger.ts +45 -0
- package/src/resources/extensions/gsd/auto/workflow-iteration-completion.ts +26 -0
- package/src/resources/extensions/gsd/auto/workflow-journal-reporter.ts +33 -0
- package/src/resources/extensions/gsd/auto/workflow-kernel.ts +520 -0
- package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +58 -0
- package/src/resources/extensions/gsd/auto/workflow-phase-reporter.ts +22 -0
- package/src/resources/extensions/gsd/auto/workflow-session-lock.ts +68 -0
- package/src/resources/extensions/gsd/auto/workflow-sidecar-iteration.ts +46 -0
- package/src/resources/extensions/gsd/auto/workflow-sidecar-queue.ts +46 -0
- package/src/resources/extensions/gsd/auto/workflow-turn-reporter.ts +68 -0
- package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +89 -0
- package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +38 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +4 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +170 -3
- package/src/resources/extensions/gsd/auto-recovery.ts +42 -50
- package/src/resources/extensions/gsd/auto-runtime-state.ts +7 -0
- package/src/resources/extensions/gsd/auto-verification.ts +5 -1
- package/src/resources/extensions/gsd/auto-worktree.ts +85 -36
- package/src/resources/extensions/gsd/auto.ts +167 -1
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +14 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +11 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +13 -5
- package/src/resources/extensions/gsd/commands-ship.ts +24 -51
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +13 -0
- package/src/resources/extensions/gsd/component-loader.ts +5 -11
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +6 -0
- package/src/resources/extensions/gsd/db-adapter.ts +75 -0
- package/src/resources/extensions/gsd/db-base-schema.ts +368 -0
- package/src/resources/extensions/gsd/db-connection-cache.ts +45 -0
- package/src/resources/extensions/gsd/db-coordination-schema.ts +109 -0
- package/src/resources/extensions/gsd/db-decision-requirement-rows.ts +77 -0
- package/src/resources/extensions/gsd/db-gate-rows.ts +19 -0
- package/src/resources/extensions/gsd/db-lightweight-query-rows.ts +50 -0
- package/src/resources/extensions/gsd/db-memory-fts-schema.ts +66 -0
- package/src/resources/extensions/gsd/db-migration-backup.ts +34 -0
- package/src/resources/extensions/gsd/db-migration-steps.ts +434 -0
- package/src/resources/extensions/gsd/db-milestone-artifact-rows.ts +70 -0
- package/src/resources/extensions/gsd/db-open-state.ts +47 -0
- package/src/resources/extensions/gsd/db-provider.ts +148 -0
- package/src/resources/extensions/gsd/db-runtime-kv-schema.ts +30 -0
- package/src/resources/extensions/gsd/db-schema-metadata.ts +33 -0
- package/src/resources/extensions/gsd/db-task-slice-rows.ts +146 -0
- package/src/resources/extensions/gsd/db-transaction.ts +76 -0
- package/src/resources/extensions/gsd/db-verification-evidence-rows.ts +14 -0
- package/src/resources/extensions/gsd/db-verification-evidence-schema.ts +22 -0
- package/src/resources/extensions/gsd/escalation.ts +3 -1
- package/src/resources/extensions/gsd/gsd-db.ts +260 -1659
- package/src/resources/extensions/gsd/interrupted-session.ts +1 -0
- package/src/resources/extensions/gsd/legacy-telemetry.ts +99 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +4 -1
- package/src/resources/extensions/gsd/model-router.ts +10 -6
- package/src/resources/extensions/gsd/notification-widget.ts +25 -4
- package/src/resources/extensions/gsd/post-execution-checks.ts +35 -7
- package/src/resources/extensions/gsd/pr-evidence.ts +124 -0
- package/src/resources/extensions/gsd/pre-execution-checks.ts +4 -1
- package/src/resources/extensions/gsd/process-task-path.ts +81 -0
- package/src/resources/extensions/gsd/prompt-loader.ts +9 -5
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +32 -30
- package/src/resources/extensions/gsd/prompts/complete-slice.md +23 -34
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +50 -96
- package/src/resources/extensions/gsd/prompts/discuss.md +81 -181
- package/src/resources/extensions/gsd/prompts/execute-task.md +40 -67
- package/src/resources/extensions/gsd/prompts/forensics.md +41 -84
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +29 -39
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +30 -65
- package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +25 -52
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +36 -36
- package/src/resources/extensions/gsd/prompts/guided-research-project.md +20 -38
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +45 -59
- package/src/resources/extensions/gsd/prompts/plan-slice.md +25 -87
- package/src/resources/extensions/gsd/prompts/queue.md +46 -53
- package/src/resources/extensions/gsd/prompts/refine-slice.md +23 -23
- package/src/resources/extensions/gsd/prompts/research-slice.md +23 -23
- package/src/resources/extensions/gsd/prompts/rethink.md +10 -10
- package/src/resources/extensions/gsd/prompts/system.md +65 -107
- package/src/resources/extensions/gsd/prompts/triage-captures.md +15 -15
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +24 -24
- package/src/resources/extensions/gsd/prompts/worktree-merge.md +35 -35
- package/src/resources/extensions/gsd/state.ts +6 -3
- package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +353 -0
- package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/commands-eval-review.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/commands-ship-eval-warn.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/complete-milestone-prompt-rendering.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +19 -5
- package/src/resources/extensions/gsd/tests/component-loader.test.ts +2 -9
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/db-adapter.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/db-base-schema.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/db-connection-cache.test.ts +60 -0
- package/src/resources/extensions/gsd/tests/db-coordination-schema.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/db-decision-requirement-rows.test.ts +135 -0
- package/src/resources/extensions/gsd/tests/db-gate-rows.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/db-lightweight-query-rows.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/db-memory-fts-schema.test.ts +86 -0
- package/src/resources/extensions/gsd/tests/db-migration-backup.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/db-migration-steps.test.ts +159 -0
- package/src/resources/extensions/gsd/tests/db-milestone-artifact-rows.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/db-open-state.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/db-provider.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/db-runtime-kv-schema.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +115 -0
- package/src/resources/extensions/gsd/tests/db-task-slice-rows.test.ts +128 -0
- package/src/resources/extensions/gsd/tests/db-transaction.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/db-verification-evidence-schema.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/discuss-headless-rendering.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/forensics-prompt-rendering.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +95 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +43 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-requirements-prompt-rendering.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +134 -0
- package/src/resources/extensions/gsd/tests/legacy-component-format-telemetry.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/legacy-telemetry.test.ts +144 -0
- package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +40 -16
- package/src/resources/extensions/gsd/tests/model-router.test.ts +33 -12
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/notification-widget.test.ts +40 -1
- package/src/resources/extensions/gsd/tests/paused-session-via-db.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/plan-milestone-rendering.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +65 -16
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/pr-evidence.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/process-task-path.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +16 -1
- package/src/resources/extensions/gsd/tests/queue-prompt-rendering.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +32 -9
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +6 -6
- package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/workflow-custom-engine-dispatch-outcome.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/workflow-custom-engine-iteration.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/workflow-custom-engine-reconcile-outcome.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/workflow-custom-engine-reconcile.test.ts +146 -0
- package/src/resources/extensions/gsd/tests/workflow-custom-engine-retry.test.ts +136 -0
- package/src/resources/extensions/gsd/tests/workflow-custom-engine-verify-outcome.test.ts +95 -0
- package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +158 -0
- package/src/resources/extensions/gsd/tests/workflow-dispatch-ledger.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/workflow-iteration-completion.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/workflow-journal-reporter.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +607 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +20 -4
- package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/workflow-phase-reporter.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/workflow-session-lock.test.ts +135 -0
- package/src/resources/extensions/gsd/tests/workflow-sidecar-iteration.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/workflow-sidecar-queue.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/workflow-turn-reporter.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/workflow-unit-dispatch.test.ts +160 -0
- package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +17 -33
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +15 -9
- package/src/resources/extensions/gsd/tools/complete-task.ts +4 -1
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +6 -1
- package/src/resources/extensions/gsd/unit-context-composer.ts +1 -1
- package/src/resources/extensions/gsd/uok/kernel.ts +10 -3
- package/src/resources/extensions/gsd/uok/plan-v2.ts +5 -1
- package/src/resources/extensions/gsd/workflow-logger.ts +13 -13
- package/src/resources/extensions/gsd/workflow-manifest.ts +6 -15
- package/src/resources/extensions/gsd/workflow-projections.ts +5 -1
- package/src/resources/extensions/gsd/workflow-templates.ts +11 -0
- package/src/resources/extensions/shared/interview-ui.ts +18 -5
- package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +41 -0
- package/dist/web/standalone/.next/server/chunks/6336.js +0 -1
- /package/dist/web/standalone/.next/static/{TzEVJ1Lh8vbez4n4Q9TqQ → bQDK5_LtkGVS64AirQgQG}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{TzEVJ1Lh8vbez4n4Q9TqQ → bQDK5_LtkGVS64AirQgQG}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
|
|
4
|
+
import { createAutoOrchestrator } from "../auto/orchestrator.js";
|
|
5
|
+
import type { AutoOrchestratorDeps } from "../auto/contracts.js";
|
|
6
|
+
|
|
7
|
+
function makeDeps(overrides: Partial<AutoOrchestratorDeps> = {}): { deps: AutoOrchestratorDeps; calls: string[] } {
|
|
8
|
+
const calls: string[] = [];
|
|
9
|
+
|
|
10
|
+
const deps: AutoOrchestratorDeps = {
|
|
11
|
+
dispatch: {
|
|
12
|
+
async decideNextUnit() {
|
|
13
|
+
calls.push("dispatch.decide");
|
|
14
|
+
return { unitType: "execute-task", unitId: "T01", reason: "ready", preconditions: [] };
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
recovery: {
|
|
18
|
+
async classifyAndRecover() {
|
|
19
|
+
calls.push("recovery.classify");
|
|
20
|
+
return { action: "stop", reason: "fatal" };
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
worktree: {
|
|
24
|
+
async prepareForUnit() { calls.push("worktree.prepare"); },
|
|
25
|
+
async syncAfterUnit() { calls.push("worktree.sync"); },
|
|
26
|
+
async cleanupOnStop() { calls.push("worktree.cleanup"); },
|
|
27
|
+
},
|
|
28
|
+
health: {
|
|
29
|
+
async preAdvanceGate() {
|
|
30
|
+
calls.push("health.pre");
|
|
31
|
+
return { allow: true };
|
|
32
|
+
},
|
|
33
|
+
async postAdvanceRecord() { calls.push("health.post"); },
|
|
34
|
+
},
|
|
35
|
+
runtime: {
|
|
36
|
+
async ensureLockOwnership() { calls.push("runtime.lock"); },
|
|
37
|
+
async journalTransition(event) { calls.push(`journal:${event.name}`); },
|
|
38
|
+
},
|
|
39
|
+
notifications: {
|
|
40
|
+
async notifyLifecycle(event) { calls.push(`notify:${event.name}`); },
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
return { deps: { ...deps, ...overrides }, calls };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
test("start() advances and records active unit", async () => {
|
|
48
|
+
const { deps, calls } = makeDeps();
|
|
49
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
50
|
+
|
|
51
|
+
const result = await orchestrator.start({ basePath: "/tmp/project", trigger: "manual" });
|
|
52
|
+
|
|
53
|
+
assert.equal(result.kind, "advanced");
|
|
54
|
+
const status = orchestrator.getStatus();
|
|
55
|
+
assert.equal(status.phase, "running");
|
|
56
|
+
assert.deepEqual(status.activeUnit, { unitType: "execute-task", unitId: "T01" });
|
|
57
|
+
assert.ok(calls.includes("journal:start"));
|
|
58
|
+
assert.ok(calls.includes("journal:advance"));
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("advance() returns blocked when health gate denies", async () => {
|
|
62
|
+
const { deps } = makeDeps({
|
|
63
|
+
health: {
|
|
64
|
+
async preAdvanceGate() { return { allow: false, reason: "doctor-block" }; },
|
|
65
|
+
async postAdvanceRecord() {},
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
69
|
+
|
|
70
|
+
const result = await orchestrator.advance();
|
|
71
|
+
|
|
72
|
+
assert.equal(result.kind, "blocked");
|
|
73
|
+
assert.equal(result.reason, "doctor-block");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("advance() stops when dispatch has no next unit", async () => {
|
|
77
|
+
const { deps } = makeDeps({
|
|
78
|
+
dispatch: {
|
|
79
|
+
async decideNextUnit() { return null; },
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
83
|
+
|
|
84
|
+
const result = await orchestrator.advance();
|
|
85
|
+
|
|
86
|
+
assert.equal(result.kind, "stopped");
|
|
87
|
+
assert.equal(orchestrator.getStatus().phase, "stopped");
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("advance() uses recovery on error", async () => {
|
|
91
|
+
const { deps, calls } = makeDeps({
|
|
92
|
+
runtime: {
|
|
93
|
+
async ensureLockOwnership() { throw new Error("lock lost"); },
|
|
94
|
+
async journalTransition(event) { calls.push(`journal:${event.name}`); },
|
|
95
|
+
},
|
|
96
|
+
recovery: {
|
|
97
|
+
async classifyAndRecover() { return { action: "escalate", reason: "needs manual" }; },
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
101
|
+
|
|
102
|
+
const result = await orchestrator.advance();
|
|
103
|
+
|
|
104
|
+
assert.equal(result.kind, "error");
|
|
105
|
+
assert.equal(result.reason, "needs manual");
|
|
106
|
+
assert.equal(orchestrator.getStatus().phase, "error");
|
|
107
|
+
assert.ok(calls.includes("journal:advance-error"));
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test("advance() is idempotent for the same active unit", async () => {
|
|
111
|
+
const { deps, calls } = makeDeps();
|
|
112
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
113
|
+
|
|
114
|
+
const first = await orchestrator.advance();
|
|
115
|
+
const second = await orchestrator.advance();
|
|
116
|
+
|
|
117
|
+
assert.equal(first.kind, "advanced");
|
|
118
|
+
assert.equal(second.kind, "blocked");
|
|
119
|
+
assert.equal(second.reason, "idempotent advance: unit already active");
|
|
120
|
+
|
|
121
|
+
const prepareCalls = calls.filter((c) => c === "worktree.prepare").length;
|
|
122
|
+
assert.equal(prepareCalls, 1);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("resume() re-enters running flow via advance", async () => {
|
|
126
|
+
const { deps } = makeDeps();
|
|
127
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
128
|
+
|
|
129
|
+
const result = await orchestrator.resume();
|
|
130
|
+
|
|
131
|
+
assert.equal(result.kind, "advanced");
|
|
132
|
+
assert.equal(orchestrator.getStatus().phase, "running");
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test("resume() clears idempotent lock and allows re-advance", async () => {
|
|
136
|
+
const { deps } = makeDeps();
|
|
137
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
138
|
+
|
|
139
|
+
const first = await orchestrator.advance();
|
|
140
|
+
const blocked = await orchestrator.advance();
|
|
141
|
+
const resumed = await orchestrator.resume();
|
|
142
|
+
|
|
143
|
+
assert.equal(first.kind, "advanced");
|
|
144
|
+
assert.equal(blocked.kind, "blocked");
|
|
145
|
+
assert.equal(resumed.kind, "advanced");
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test("transitionCount increases across lifecycle transitions", async () => {
|
|
149
|
+
const { deps } = makeDeps();
|
|
150
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
151
|
+
|
|
152
|
+
const before = orchestrator.getStatus().transitionCount;
|
|
153
|
+
await orchestrator.start({ basePath: "/tmp/project", trigger: "manual" });
|
|
154
|
+
const afterStart = orchestrator.getStatus().transitionCount;
|
|
155
|
+
await orchestrator.stop("done");
|
|
156
|
+
const afterStop = orchestrator.getStatus().transitionCount;
|
|
157
|
+
|
|
158
|
+
assert.ok(afterStart > before);
|
|
159
|
+
assert.ok(afterStop > afterStart);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
test("stop() clears idempotent unit lock so advance can run again", async () => {
|
|
163
|
+
const { deps } = makeDeps();
|
|
164
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
165
|
+
|
|
166
|
+
const first = await orchestrator.advance();
|
|
167
|
+
const blocked = await orchestrator.advance();
|
|
168
|
+
const stopped = await orchestrator.stop("reset");
|
|
169
|
+
const second = await orchestrator.advance();
|
|
170
|
+
|
|
171
|
+
assert.equal(first.kind, "advanced");
|
|
172
|
+
assert.equal(blocked.kind, "blocked");
|
|
173
|
+
assert.equal(stopped.kind, "stopped");
|
|
174
|
+
assert.equal(second.kind, "advanced");
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test("advance() stopped clears previous activeUnit", async () => {
|
|
178
|
+
let first = true;
|
|
179
|
+
const { deps } = makeDeps({
|
|
180
|
+
dispatch: {
|
|
181
|
+
async decideNextUnit() {
|
|
182
|
+
if (first) {
|
|
183
|
+
first = false;
|
|
184
|
+
return { unitType: "execute-task", unitId: "T01", reason: "ready", preconditions: [] };
|
|
185
|
+
}
|
|
186
|
+
return null;
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
191
|
+
|
|
192
|
+
await orchestrator.advance();
|
|
193
|
+
const stopped = await orchestrator.advance();
|
|
194
|
+
|
|
195
|
+
assert.equal(stopped.kind, "stopped");
|
|
196
|
+
assert.equal(orchestrator.getStatus().activeUnit, undefined);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test("recovery stop clears activeUnit", async () => {
|
|
200
|
+
const { deps, calls } = makeDeps({
|
|
201
|
+
runtime: {
|
|
202
|
+
async ensureLockOwnership() { throw new Error("boom"); },
|
|
203
|
+
async journalTransition(event) { calls.push(`journal:${event.name}`); },
|
|
204
|
+
},
|
|
205
|
+
recovery: {
|
|
206
|
+
async classifyAndRecover() { return { action: "stop", reason: "fatal" }; },
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
210
|
+
|
|
211
|
+
const result = await orchestrator.advance();
|
|
212
|
+
|
|
213
|
+
assert.equal(result.kind, "stopped");
|
|
214
|
+
assert.equal(orchestrator.getStatus().activeUnit, undefined);
|
|
215
|
+
assert.ok(calls.includes("journal:advance-stopped"));
|
|
216
|
+
assert.ok(calls.includes("notify:stopped"));
|
|
217
|
+
assert.ok(!calls.includes("notify:error"));
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
test("recovery retry maps to paused result", async () => {
|
|
221
|
+
const { deps, calls } = makeDeps({
|
|
222
|
+
runtime: {
|
|
223
|
+
async ensureLockOwnership() { throw new Error("boom"); },
|
|
224
|
+
async journalTransition(event) { calls.push(`journal:${event.name}`); },
|
|
225
|
+
},
|
|
226
|
+
recovery: {
|
|
227
|
+
async classifyAndRecover() { return { action: "retry", reason: "transient" }; },
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
231
|
+
|
|
232
|
+
const result = await orchestrator.advance();
|
|
233
|
+
|
|
234
|
+
assert.equal(result.kind, "paused");
|
|
235
|
+
assert.equal(result.reason, "transient");
|
|
236
|
+
assert.equal(orchestrator.getStatus().phase, "paused");
|
|
237
|
+
assert.ok(calls.includes("journal:advance-paused"));
|
|
238
|
+
assert.ok(calls.includes("notify:pause"));
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
test("getStatus() returns defensive copy of activeUnit", async () => {
|
|
242
|
+
const { deps } = makeDeps();
|
|
243
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
244
|
+
|
|
245
|
+
await orchestrator.advance();
|
|
246
|
+
const snap1 = orchestrator.getStatus();
|
|
247
|
+
if (snap1.activeUnit) snap1.activeUnit.unitId = "MUTATED";
|
|
248
|
+
const snap2 = orchestrator.getStatus();
|
|
249
|
+
|
|
250
|
+
assert.equal(snap2.activeUnit?.unitId, "T01");
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
test("start() clears prior idempotent lock", async () => {
|
|
254
|
+
const { deps } = makeDeps();
|
|
255
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
256
|
+
|
|
257
|
+
await orchestrator.advance();
|
|
258
|
+
const blocked = await orchestrator.advance();
|
|
259
|
+
const restarted = await orchestrator.start({ basePath: "/tmp/project", trigger: "manual" });
|
|
260
|
+
|
|
261
|
+
assert.equal(blocked.kind, "blocked");
|
|
262
|
+
assert.equal(restarted.kind, "advanced");
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
test("error path emits error notification", async () => {
|
|
266
|
+
const { deps, calls } = makeDeps({
|
|
267
|
+
runtime: {
|
|
268
|
+
async ensureLockOwnership() { throw new Error("boom"); },
|
|
269
|
+
async journalTransition(event) { calls.push(`journal:${event.name}`); },
|
|
270
|
+
},
|
|
271
|
+
recovery: {
|
|
272
|
+
async classifyAndRecover() { return { action: "escalate", reason: "needs manual" }; },
|
|
273
|
+
},
|
|
274
|
+
});
|
|
275
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
276
|
+
|
|
277
|
+
await orchestrator.advance();
|
|
278
|
+
|
|
279
|
+
assert.ok(calls.includes("notify:error"));
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
test("blocked path journals advance-blocked", async () => {
|
|
283
|
+
const { deps, calls } = makeDeps();
|
|
284
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
285
|
+
|
|
286
|
+
await orchestrator.advance();
|
|
287
|
+
await orchestrator.advance();
|
|
288
|
+
|
|
289
|
+
assert.ok(calls.includes("journal:advance-blocked"));
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
test("health post hook runs on blocked result", async () => {
|
|
293
|
+
const { deps, calls } = makeDeps();
|
|
294
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
295
|
+
|
|
296
|
+
await orchestrator.advance();
|
|
297
|
+
await orchestrator.advance();
|
|
298
|
+
|
|
299
|
+
assert.ok(calls.includes("health.post"));
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
test("start() emits start notification", async () => {
|
|
303
|
+
const { deps, calls } = makeDeps();
|
|
304
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
305
|
+
|
|
306
|
+
await orchestrator.start({ basePath: "/tmp/project", trigger: "manual" });
|
|
307
|
+
|
|
308
|
+
assert.ok(calls.includes("notify:start"));
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
test("resume() emits resume notification", async () => {
|
|
312
|
+
const { deps, calls } = makeDeps();
|
|
313
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
314
|
+
|
|
315
|
+
await orchestrator.resume();
|
|
316
|
+
|
|
317
|
+
assert.ok(calls.includes("notify:resume"));
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
test("stopped with no remaining units clears idempotent lock for next advance", async () => {
|
|
321
|
+
let callCount = 0;
|
|
322
|
+
const { deps } = makeDeps({
|
|
323
|
+
dispatch: {
|
|
324
|
+
async decideNextUnit() {
|
|
325
|
+
callCount += 1;
|
|
326
|
+
if (callCount === 2) return null;
|
|
327
|
+
return { unitType: "execute-task", unitId: "T01", reason: "ready", preconditions: [] };
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
});
|
|
331
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
332
|
+
|
|
333
|
+
const first = await orchestrator.advance();
|
|
334
|
+
const stopped = await orchestrator.advance();
|
|
335
|
+
const after = await orchestrator.advance();
|
|
336
|
+
|
|
337
|
+
assert.equal(first.kind, "advanced");
|
|
338
|
+
assert.equal(stopped.kind, "stopped");
|
|
339
|
+
assert.equal(after.kind, "advanced");
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
test("stop() cleans up worktree and transitions to stopped", async () => {
|
|
343
|
+
const { deps, calls } = makeDeps();
|
|
344
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
345
|
+
|
|
346
|
+
const result = await orchestrator.stop("user-request");
|
|
347
|
+
|
|
348
|
+
assert.equal(result.kind, "stopped");
|
|
349
|
+
assert.equal(orchestrator.getStatus().phase, "stopped");
|
|
350
|
+
assert.ok(calls.includes("worktree.cleanup"));
|
|
351
|
+
assert.ok(calls.includes("journal:stop"));
|
|
352
|
+
assert.ok(calls.includes("notify:stop"));
|
|
353
|
+
});
|
|
@@ -34,6 +34,25 @@ test("#2302 bug 1: auto_pr condition should not require pushed flag", () => {
|
|
|
34
34
|
);
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
+
test("auto_pr skips milestone branch push when configured remote is absent", () => {
|
|
38
|
+
const autoPrIdx = autoWorktreeSrc.indexOf("prefs.auto_pr === true");
|
|
39
|
+
assert.ok(autoPrIdx !== -1, "auto_pr block exists in auto-worktree.ts");
|
|
40
|
+
|
|
41
|
+
const autoPrBlock = autoWorktreeSrc.slice(
|
|
42
|
+
autoPrIdx,
|
|
43
|
+
autoWorktreeSrc.indexOf("// 11. Guard removed", autoPrIdx),
|
|
44
|
+
);
|
|
45
|
+
const remoteExistsIdx = autoPrBlock.indexOf("gitRemoteExists(originalBasePath_, remote)");
|
|
46
|
+
const pushIdx = autoPrBlock.indexOf('execFileSync("git", ["push", remote, milestoneBranch]');
|
|
47
|
+
|
|
48
|
+
assert.ok(remoteExistsIdx !== -1, "auto_pr must check that the configured remote exists");
|
|
49
|
+
assert.ok(pushIdx !== -1, "auto_pr still pushes the milestone branch before creating the PR");
|
|
50
|
+
assert.ok(
|
|
51
|
+
remoteExistsIdx < pushIdx,
|
|
52
|
+
"auto_pr must check remote existence before pushing the milestone branch",
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
37
56
|
// ─── Bug 2: phases.ts should not duplicate PR creation ──────────────────────
|
|
38
57
|
|
|
39
58
|
const phasesSrcPath = join(import.meta.dirname, "..", "auto", "phases.ts");
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
|
|
4
|
+
import { autoSession, getAutoRuntimeSnapshot } from "../auto-runtime-state.ts";
|
|
5
|
+
|
|
6
|
+
test("getAutoRuntimeSnapshot includes orchestration phase when available", () => {
|
|
7
|
+
autoSession.reset();
|
|
8
|
+
autoSession.active = true;
|
|
9
|
+
autoSession.basePath = "/tmp/project";
|
|
10
|
+
autoSession.orchestration = {
|
|
11
|
+
async start() { return { kind: "advanced" as const }; },
|
|
12
|
+
async advance() { return { kind: "advanced" as const }; },
|
|
13
|
+
async resume() { return { kind: "advanced" as const }; },
|
|
14
|
+
async stop() { return { kind: "stopped" as const }; },
|
|
15
|
+
getStatus() {
|
|
16
|
+
return { phase: "running" as const, transitionCount: 3, lastTransitionAt: 123 };
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const snap = getAutoRuntimeSnapshot();
|
|
21
|
+
|
|
22
|
+
assert.equal(snap.active, true);
|
|
23
|
+
assert.equal(snap.basePath, "/tmp/project");
|
|
24
|
+
assert.equal(snap.orchestrationPhase, "running");
|
|
25
|
+
assert.equal(snap.orchestrationTransitionCount, 3);
|
|
26
|
+
assert.equal(snap.orchestrationLastTransitionAt, 123);
|
|
27
|
+
|
|
28
|
+
autoSession.reset();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("getAutoRuntimeSnapshot omits orchestration phase when seam not wired", () => {
|
|
32
|
+
autoSession.reset();
|
|
33
|
+
|
|
34
|
+
const snap = getAutoRuntimeSnapshot();
|
|
35
|
+
|
|
36
|
+
assert.equal(snap.orchestrationPhase, undefined);
|
|
37
|
+
assert.equal(snap.orchestrationTransitionCount, undefined);
|
|
38
|
+
assert.equal(snap.orchestrationLastTransitionAt, undefined);
|
|
39
|
+
});
|
|
@@ -201,6 +201,9 @@ test("AutoSession.toJSON() includes key diagnostic properties", () => {
|
|
|
201
201
|
"basePath",
|
|
202
202
|
"currentMilestoneId",
|
|
203
203
|
"currentUnit",
|
|
204
|
+
"orchestrationPhase",
|
|
205
|
+
"orchestrationTransitionCount",
|
|
206
|
+
"orchestrationLastTransitionAt",
|
|
204
207
|
];
|
|
205
208
|
|
|
206
209
|
const missing = requiredDiagnostics.filter(prop => !toJSONBody.includes(prop));
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { describe, it, beforeEach, afterEach } from "node:test";
|
|
11
11
|
import assert from "node:assert/strict";
|
|
12
|
-
import { mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
12
|
+
import { mkdirSync, realpathSync, writeFileSync, rmSync } from "node:fs";
|
|
13
13
|
import { join } from "node:path";
|
|
14
14
|
import { tmpdir } from "node:os";
|
|
15
15
|
import { randomUUID } from "node:crypto";
|
|
@@ -462,7 +462,7 @@ describe("findEvalReviewFile", () => {
|
|
|
462
462
|
const target = join(basePath, ".gsd", "milestones", "M001", "slices", "S07", "S07-EVAL-REVIEW.md");
|
|
463
463
|
writeFileSync(target, "---\nschema: eval-review/v1\n---\n", "utf-8");
|
|
464
464
|
const found = findEvalReviewFile(basePath, "M001", "S07");
|
|
465
|
-
assert.equal(found, target);
|
|
465
|
+
assert.equal(found, realpathSync(target));
|
|
466
466
|
});
|
|
467
467
|
});
|
|
468
468
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import { describe, it, beforeEach, afterEach } from "node:test";
|
|
14
14
|
import assert from "node:assert/strict";
|
|
15
|
-
import { mkdirSync, rmSync, writeFileSync, unlinkSync } from "node:fs";
|
|
15
|
+
import { mkdirSync, realpathSync, rmSync, writeFileSync, unlinkSync } from "node:fs";
|
|
16
16
|
import { join } from "node:path";
|
|
17
17
|
import { tmpdir } from "node:os";
|
|
18
18
|
import { randomUUID } from "node:crypto";
|
|
@@ -129,7 +129,8 @@ describe("checkSliceEvalReview", () => {
|
|
|
129
129
|
// points to a missing file — exactly the race a prior existsSync +
|
|
130
130
|
// readFileSync sequence panicked on.
|
|
131
131
|
const resolved = resolveSliceFile(basePath, "M001", "S07", "EVAL-REVIEW");
|
|
132
|
-
assert.
|
|
132
|
+
assert.ok(resolved);
|
|
133
|
+
assert.equal(realpathSync(resolved), realpathSync(path));
|
|
133
134
|
unlinkSync(path);
|
|
134
135
|
const result = await checkSliceEvalReview(basePath, "M001", "S07");
|
|
135
136
|
assert.equal(result.kind, "absent");
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Verifies the complete milestone prompt renders required completion and verification guardrails.
|
|
3
|
+
|
|
4
|
+
import test from "node:test";
|
|
5
|
+
import assert from "node:assert/strict";
|
|
6
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
7
|
+
import { tmpdir } from "node:os";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
|
|
10
|
+
test("complete milestone prompt renders compact verification and completion guidance", async (t) => {
|
|
11
|
+
const previousGsdHome = process.env.GSD_HOME;
|
|
12
|
+
const providedGsdHome = process.env.GSD_TEST_HOME;
|
|
13
|
+
const isolatedHome = providedGsdHome ?? mkdtempSync(join(tmpdir(), "gsd-complete-milestone-render-"));
|
|
14
|
+
process.env.GSD_HOME = isolatedHome;
|
|
15
|
+
t.after(() => {
|
|
16
|
+
if (previousGsdHome === undefined) delete process.env.GSD_HOME;
|
|
17
|
+
else process.env.GSD_HOME = previousGsdHome;
|
|
18
|
+
if (!providedGsdHome) rmSync(isolatedHome, { recursive: true, force: true });
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const { loadPrompt } = await import(`../prompt-loader.ts?test=${Date.now()}`);
|
|
22
|
+
const prompt = loadPrompt("complete-milestone", {
|
|
23
|
+
workingDirectory: process.env.GSD_TEST_WORKSPACE_ROOT ?? process.cwd(),
|
|
24
|
+
milestoneId: "M001",
|
|
25
|
+
milestoneTitle: "Baseline And Safety",
|
|
26
|
+
roadmapPath: ".gsd/milestones/M001/M001-ROADMAP.md",
|
|
27
|
+
milestoneSummaryPath: ".gsd/milestones/M001/M001-SUMMARY.md",
|
|
28
|
+
inlinedContext: "## Milestone Summary\n\n## Horizontal Checklist\n\n## Decision Re-evaluation",
|
|
29
|
+
extractLearningsSteps: "Write M001-LEARNINGS.md and call capture_thought.",
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
assert.match(prompt, /Complete Milestone M001/);
|
|
33
|
+
assert.match(prompt, /Verification Gate/);
|
|
34
|
+
assert.match(prompt, /Do NOT call `gsd_complete_milestone`/);
|
|
35
|
+
assert.match(prompt, /verification FAILED/);
|
|
36
|
+
assert.match(prompt, /gsd_requirement_update/);
|
|
37
|
+
assert.match(prompt, /gsd_complete_milestone/);
|
|
38
|
+
assert.match(prompt, /verificationPassed/);
|
|
39
|
+
assert.match(prompt, /gsd_milestone_status/);
|
|
40
|
+
assert.match(prompt, /Do NOT query.*\.gsd\/gsd\.db/i);
|
|
41
|
+
assert.match(prompt, /Horizontal Checklist/);
|
|
42
|
+
assert.match(prompt, /Decision Re-evaluation/);
|
|
43
|
+
assert.match(prompt, /self-diff/i);
|
|
44
|
+
assert.match(prompt, /GSD-(?:Task|Unit)/);
|
|
45
|
+
assert.match(prompt, /Milestone M001 complete/);
|
|
46
|
+
assert.doesNotMatch(prompt, /\{\{[a-zA-Z][a-zA-Z0-9_]*\}\}/);
|
|
47
|
+
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// GSD2 complete-milestone tests
|
|
1
2
|
import { describe, test, afterEach } from "node:test";
|
|
2
3
|
import assert from "node:assert/strict";
|
|
3
4
|
import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync, existsSync } from "node:fs";
|
|
@@ -432,10 +433,9 @@ describe("complete-milestone", () => {
|
|
|
432
433
|
}
|
|
433
434
|
});
|
|
434
435
|
|
|
435
|
-
test("handleCompleteMilestone
|
|
436
|
+
test("handleCompleteMilestone treats already-complete milestone as idempotent re-dispatch (#4598)", async () => {
|
|
436
437
|
// This test verifies that when SUMMARY.md already exists (from a prior completion),
|
|
437
438
|
// re-calling handleCompleteMilestone does not overwrite it.
|
|
438
|
-
// Before the fix this test FAILS because the handler unconditionally writes SUMMARY.md.
|
|
439
439
|
const { handleCompleteMilestone } = await import("../tools/complete-milestone.ts");
|
|
440
440
|
const base = createFixtureBase();
|
|
441
441
|
const mid = "M001";
|
|
@@ -443,7 +443,7 @@ describe("complete-milestone", () => {
|
|
|
443
443
|
try {
|
|
444
444
|
// Set up DB with milestone and a complete slice + task
|
|
445
445
|
openDatabase(dbPath);
|
|
446
|
-
insertMilestone({ id: mid, title: "Test Milestone", status: "
|
|
446
|
+
insertMilestone({ id: mid, title: "Test Milestone", status: "complete" });
|
|
447
447
|
insertSlice({ id: "S01", milestoneId: mid, title: "Slice One", status: "complete" });
|
|
448
448
|
insertTask({ id: "T01", sliceId: "S01", milestoneId: mid, title: "Task One", status: "complete" });
|
|
449
449
|
|
|
@@ -472,15 +472,29 @@ describe("complete-milestone", () => {
|
|
|
472
472
|
};
|
|
473
473
|
|
|
474
474
|
const result = await handleCompleteMilestone(params, base);
|
|
475
|
+
assert.ok(!("error" in result), `already-complete re-dispatch should succeed: ${JSON.stringify(result)}`);
|
|
476
|
+
assert.equal(result.alreadyComplete, true);
|
|
475
477
|
|
|
476
|
-
// The call may return an error (milestone already complete) or success
|
|
477
|
-
// but in either case the SUMMARY.md must NOT be overwritten.
|
|
478
478
|
const actualContent = readFileSync(summaryPath, "utf-8");
|
|
479
479
|
assert.strictEqual(
|
|
480
480
|
actualContent,
|
|
481
481
|
originalContent,
|
|
482
482
|
"existing SUMMARY.md must not be overwritten on re-dispatch (#4598)",
|
|
483
483
|
);
|
|
484
|
+
|
|
485
|
+
// Repeated re-dispatch should also be idempotent.
|
|
486
|
+
const repeatResult = await handleCompleteMilestone(params, base);
|
|
487
|
+
assert.ok(!("error" in repeatResult), "repeated re-dispatch should also succeed");
|
|
488
|
+
assert.strictEqual(repeatResult.alreadyComplete, true, "repeated re-dispatch is identified as already-complete");
|
|
489
|
+
assert.ok(
|
|
490
|
+
repeatResult.summaryPath.endsWith(join(".gsd", "milestones", mid, `${mid}-SUMMARY.md`)),
|
|
491
|
+
"repeated re-dispatch returns the existing summary path",
|
|
492
|
+
);
|
|
493
|
+
assert.strictEqual(
|
|
494
|
+
readFileSync(summaryPath, "utf-8"),
|
|
495
|
+
originalContent,
|
|
496
|
+
"repeated re-dispatch must not overwrite SUMMARY.md",
|
|
497
|
+
);
|
|
484
498
|
} finally {
|
|
485
499
|
try { closeDatabase(); } catch { /* */ }
|
|
486
500
|
clearPathCache();
|
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* Tests for multi-format component loading:
|
|
5
|
-
* - New format (component.yaml)
|
|
6
|
-
* - Legacy skill format (SKILL.md with frontmatter)
|
|
7
|
-
* - Legacy agent format (.md with frontmatter)
|
|
8
|
-
* - Directory scanning
|
|
9
|
-
*/
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Verifies component loading across modern and legacy formats.
|
|
10
3
|
|
|
11
4
|
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
12
5
|
import assert from 'node:assert/strict';
|
|
@@ -372,6 +372,44 @@ describe("Custom engine loop integration", () => {
|
|
|
372
372
|
assert.ok(stopEntry?.includes("Workflow complete"), "Should stop with 'Workflow complete'");
|
|
373
373
|
});
|
|
374
374
|
|
|
375
|
+
it("finishes custom-engine skip turns and clears current turn state", async () => {
|
|
376
|
+
_resetPendingResolve();
|
|
377
|
+
|
|
378
|
+
const runDir = makeTmpDir();
|
|
379
|
+
const graph = makeGraph([
|
|
380
|
+
makeStep({ id: "step-a", dependsOn: ["step-b"] }),
|
|
381
|
+
makeStep({ id: "step-b", dependsOn: ["step-a"] }),
|
|
382
|
+
], "blocked-workflow");
|
|
383
|
+
writeGraph(runDir, graph);
|
|
384
|
+
writeDefinition(runDir, graph.steps, "blocked-workflow");
|
|
385
|
+
|
|
386
|
+
const ctx = makeMockCtx();
|
|
387
|
+
const pi = makeMockPi();
|
|
388
|
+
const s = makeLoopSession({
|
|
389
|
+
activeEngineId: "custom",
|
|
390
|
+
activeRunDir: runDir,
|
|
391
|
+
basePath: runDir,
|
|
392
|
+
});
|
|
393
|
+
const turnResults: Array<{ status: string }> = [];
|
|
394
|
+
const deps = makeMockDeps({
|
|
395
|
+
uokObserver: {
|
|
396
|
+
onTurnStart: () => {},
|
|
397
|
+
onTurnResult: (result) => {
|
|
398
|
+
turnResults.push({ status: result.status });
|
|
399
|
+
s.active = false;
|
|
400
|
+
},
|
|
401
|
+
onPhaseResult: () => {},
|
|
402
|
+
},
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
await autoLoop(ctx, pi, s, deps);
|
|
406
|
+
|
|
407
|
+
assert.deepEqual(turnResults, [{ status: "skipped" }]);
|
|
408
|
+
assert.equal(s.currentTraceId, null);
|
|
409
|
+
assert.equal(s.currentTurnId, null);
|
|
410
|
+
assert.equal(pi.calls.length, 0, "skip should not dispatch a custom step");
|
|
411
|
+
});
|
|
412
|
+
|
|
375
413
|
it("does not call runPreDispatch or runFinalize on the custom path", async () => {
|
|
376
414
|
_resetPendingResolve();
|
|
377
415
|
|