@opengsd/gsd-pi 1.3.0-dev.eed73bea → 1.4.0-dev.5fc22c6f
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/README.md +11 -11
- package/dist/cli.js +17 -4
- package/dist/headless-answers.js +1 -1
- package/dist/headless-ui.d.ts +1 -1
- package/dist/headless-ui.js +1 -1
- package/dist/headless.js +1 -1
- package/dist/onboarding.js +11 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +20 -25
- package/dist/resources/extensions/claude-code-cli/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +61 -50
- package/dist/resources/extensions/cursor-cli/index.js +16 -0
- package/dist/resources/extensions/cursor-cli/models.js +63 -0
- package/dist/resources/extensions/cursor-cli/package.json +11 -0
- package/dist/resources/extensions/cursor-cli/readiness.js +128 -0
- package/dist/resources/extensions/cursor-cli/stream-adapter.js +353 -0
- package/dist/resources/extensions/gsd/activity-log.js +4 -1
- package/dist/resources/extensions/gsd/artifact-verification.js +431 -0
- package/dist/resources/extensions/gsd/auto/session.js +11 -0
- package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +1 -1
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +28 -1
- package/dist/resources/extensions/gsd/auto-budget.js +5 -1
- package/dist/resources/extensions/gsd/auto-dispatch.js +32 -11
- package/dist/resources/extensions/gsd/auto-model-selection.js +36 -18
- package/dist/resources/extensions/gsd/auto-post-unit.js +1 -1
- package/dist/resources/extensions/gsd/auto-prompts.js +83 -25
- package/dist/resources/extensions/gsd/auto-recovery.js +9 -517
- package/dist/resources/extensions/gsd/auto-runtime-state.js +4 -5
- package/dist/resources/extensions/gsd/auto-start.js +4 -3
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +7 -3
- package/dist/resources/extensions/gsd/auto-verification.js +5 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +38 -11
- package/dist/resources/extensions/gsd/auto.js +32 -10
- package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +39 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +8 -4
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +147 -23
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +56 -36
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +29 -5
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +3 -1
- package/dist/resources/extensions/gsd/codebase-generator.js +157 -19
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +1 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +40 -4
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +154 -2
- package/dist/resources/extensions/gsd/commands-usage.js +1 -1
- package/dist/resources/extensions/gsd/commands-worktree.js +11 -2
- package/dist/resources/extensions/gsd/db/engine.js +4 -1
- package/dist/resources/extensions/gsd/db/queries.js +39 -0
- package/dist/resources/extensions/gsd/db-memory-fts-schema.js +34 -0
- package/dist/resources/extensions/gsd/db-workspace.js +55 -3
- package/dist/resources/extensions/gsd/delegation-policy.js +1 -1
- package/dist/resources/extensions/gsd/discussion-handoff.js +8 -3
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -4
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +227 -5
- package/dist/resources/extensions/gsd/doctor-providers.js +38 -10
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +3 -0
- package/dist/resources/extensions/gsd/doctor.js +93 -3
- package/dist/resources/extensions/gsd/exec-sandbox.js +14 -4
- package/dist/resources/extensions/gsd/flat-phase-migration.js +119 -23
- package/dist/resources/extensions/gsd/git-service.js +61 -8
- package/dist/resources/extensions/gsd/gitignore.js +4 -1
- package/dist/resources/extensions/gsd/guidance.js +1 -0
- package/dist/resources/extensions/gsd/guided-flow-queue.js +20 -13
- package/dist/resources/extensions/gsd/guided-flow.js +40 -2
- package/dist/resources/extensions/gsd/json-persistence.js +20 -0
- package/dist/resources/extensions/gsd/key-manager.js +1 -0
- package/dist/resources/extensions/gsd/knowledge-backfill.js +18 -11
- package/dist/resources/extensions/gsd/layout-policy.js +3 -1
- package/dist/resources/extensions/gsd/markdown-renderer.js +27 -15
- package/dist/resources/extensions/gsd/memory-backfill.js +28 -21
- package/dist/resources/extensions/gsd/metrics.js +4 -4
- package/dist/resources/extensions/gsd/migrate-external.js +22 -5
- package/dist/resources/extensions/gsd/migration-auto-check.js +22 -0
- package/dist/resources/extensions/gsd/milestone-ids.js +32 -2
- package/dist/resources/extensions/gsd/orphan-stash-audit.js +92 -16
- package/dist/resources/extensions/gsd/preferences-diagnostics.js +24 -1
- package/dist/resources/extensions/gsd/preferences-models.js +6 -4
- package/dist/resources/extensions/gsd/preferences-validation.js +25 -2
- package/dist/resources/extensions/gsd/preferences.js +29 -2
- package/dist/resources/extensions/gsd/prompts/code-review.md +6 -4
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +5 -3
- package/dist/resources/extensions/gsd/redact-secrets.js +37 -0
- package/dist/resources/extensions/gsd/repository-registry.js +6 -1
- package/dist/resources/extensions/gsd/root-write-leak-guard.js +7 -1
- package/dist/resources/extensions/gsd/safe-fs.js +23 -2
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +8 -1
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +16 -1
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +5 -2
- package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
- package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +2 -1
- package/dist/resources/extensions/gsd/state/derive/cache.js +28 -0
- package/dist/resources/extensions/gsd/state/derive/db-open.js +39 -0
- package/dist/resources/extensions/gsd/state/derive/from-db.js +452 -0
- package/dist/resources/extensions/gsd/state/derive/index.js +75 -0
- package/dist/resources/extensions/gsd/state/derive/interrupted-work.js +21 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +27 -33
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +48 -23
- package/dist/resources/extensions/gsd/state-reconciliation/registry.js +32 -28
- package/dist/resources/extensions/gsd/state.js +12 -611
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +4 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +3 -34
- package/dist/resources/extensions/gsd/tools/complete-task.js +8 -41
- package/dist/resources/extensions/gsd/tools/plan-slice.js +59 -44
- package/dist/resources/extensions/gsd/tools/plan-task.js +103 -12
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +40 -0
- package/dist/resources/extensions/gsd/undo.js +43 -6
- package/dist/resources/extensions/gsd/unit-context-manifest.js +5 -4
- package/dist/resources/extensions/gsd/unit-registry.js +11 -3
- package/dist/resources/extensions/gsd/unit-runtime.js +21 -0
- package/dist/resources/extensions/gsd/verification-gate.js +7 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +126 -13
- package/dist/resources/extensions/gsd/workflow-projections.js +19 -14
- package/dist/resources/extensions/gsd/workspace.js +26 -8
- package/dist/resources/extensions/gsd/worktree-manager.js +140 -5
- 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 +12 -12
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +9 -9
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/{2659.b7b129ee6a769448.js → 2659.58e950899a9bb82f.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/2772.a7c1fcc69a4685ef.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{3616.3c60753b8ffcbd2e.js → 3616.61a2af74bb8833c8.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{4283.8e446784528ed9dc.js → 4283.d0d9e0a955e441cb.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{5826.a46ecdd1cfe8dabc.js → 5826.5421d66c72b9f34e.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{8785.481aa5869991b760.js → 8785.e29b3134cab1d153.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/8937.640dc9c2aaa1dfad.js +10 -0
- package/dist/web/standalone/.next/static/chunks/app/{page-6644fc6ee8ca1247.js → page-72a856634ad14c10.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/webpack-9c401904f87ded16.js +1 -0
- package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/wizard.d.ts +8 -0
- package/dist/wizard.js +8 -1
- package/integrations/hermes/__init__.py +31 -0
- package/integrations/hermes/tests/test_directory_loader.py +37 -0
- package/package.json +8 -8
- package/packages/cloud-mcp-gateway/dist/auth-store.d.ts +1 -0
- package/packages/cloud-mcp-gateway/dist/auth-store.d.ts.map +1 -1
- package/packages/cloud-mcp-gateway/dist/auth-store.js +21 -1
- package/packages/cloud-mcp-gateway/dist/auth-store.js.map +1 -1
- package/packages/cloud-mcp-gateway/dist/auth-store.test.js +34 -0
- package/packages/cloud-mcp-gateway/dist/auth-store.test.js.map +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/dist/cloud-runtime.d.ts +2 -0
- package/packages/daemon/dist/cloud-runtime.d.ts.map +1 -1
- package/packages/daemon/dist/cloud-runtime.js +25 -1
- package/packages/daemon/dist/cloud-runtime.js.map +1 -1
- package/packages/daemon/dist/cloud-runtime.test.js +51 -0
- package/packages/daemon/dist/cloud-runtime.test.js.map +1 -1
- package/packages/daemon/dist/message-batcher.d.ts +7 -0
- package/packages/daemon/dist/message-batcher.d.ts.map +1 -1
- package/packages/daemon/dist/message-batcher.js +13 -0
- package/packages/daemon/dist/message-batcher.js.map +1 -1
- package/packages/daemon/dist/message-batcher.test.js +48 -0
- package/packages/daemon/dist/message-batcher.test.js.map +1 -1
- package/packages/daemon/package.json +5 -5
- package/packages/gsd-agent-core/dist/agent-session.d.ts +1 -0
- package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/agent-session.js +3 -0
- package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.d.ts +13 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.js +15 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts +41 -0
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts.map +1 -0
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.js +62 -0
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.js.map +1 -0
- package/packages/gsd-agent-core/dist/index.d.ts +2 -0
- package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/index.js +2 -0
- package/packages/gsd-agent-core/dist/index.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-events.js +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-events.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +1 -0
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts +5 -0
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +60 -3
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
- package/packages/gsd-agent-core/dist/transcript-store.d.ts +58 -0
- package/packages/gsd-agent-core/dist/transcript-store.d.ts.map +1 -0
- package/packages/gsd-agent-core/dist/transcript-store.js +132 -0
- package/packages/gsd-agent-core/dist/transcript-store.js.map +1 -0
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +2 -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 +25 -11
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts +4 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js +7 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -24
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -841
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts +58 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js +312 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts +31 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js +130 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts +15 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +259 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts +13 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js +118 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +9 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts +54 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js +20 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +4 -1
- 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 +9 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts +56 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js +44 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js +77 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +24 -6
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +18 -0
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/workflow-tools.js +1 -1
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +3 -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/dist/env-api-keys.d.ts.map +1 -1
- package/packages/pi-ai/dist/env-api-keys.js +3 -0
- package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +46 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +38 -0
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +2 -2
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/README.md +3 -2
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-context.js +94 -0
- package/packages/pi-coding-agent/dist/core/session-manager-context.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts +8 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.js +244 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts +12 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.js +84 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +135 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.js +2 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts +6 -154
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +22 -459
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts +75 -75
- package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme-schema.js +1 -1
- package/packages/pi-coding-agent/dist/theme/theme-schema.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 +11 -7
- 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/package.json +2 -2
- package/packages/rpc-client/dist/rpc-client.js +1 -1
- package/packages/rpc-client/dist/rpc-client.js.map +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/dist/theme/theme-schema.d.ts +75 -75
- package/pkg/dist/theme/theme-schema.d.ts.map +1 -1
- package/pkg/dist/theme/theme-schema.js +1 -1
- package/pkg/dist/theme/theme-schema.js.map +1 -1
- package/pkg/dist/theme/theme.d.ts.map +1 -1
- package/pkg/dist/theme/theme.js +11 -7
- package/pkg/dist/theme/theme.js.map +1 -1
- package/pkg/package.json +1 -1
- package/scripts/link-workspace-packages.cjs +14 -4
- package/src/resources/GSD-WORKFLOW.md +20 -25
- package/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +67 -49
- package/src/resources/extensions/claude-code-cli/tests/index.test.ts +14 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +159 -0
- package/src/resources/extensions/cursor-cli/index.ts +18 -0
- package/src/resources/extensions/cursor-cli/models.ts +65 -0
- package/src/resources/extensions/cursor-cli/package.json +11 -0
- package/src/resources/extensions/cursor-cli/readiness.ts +143 -0
- package/src/resources/extensions/cursor-cli/stream-adapter.ts +440 -0
- package/src/resources/extensions/cursor-cli/tests/index.test.ts +54 -0
- package/src/resources/extensions/cursor-cli/tests/readiness.test.ts +29 -0
- package/src/resources/extensions/cursor-cli/tests/stream-adapter.test.ts +166 -0
- package/src/resources/extensions/gsd/activity-log.ts +4 -1
- package/src/resources/extensions/gsd/artifact-verification.ts +468 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/session.ts +14 -0
- package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +3 -1
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +47 -1
- package/src/resources/extensions/gsd/auto-budget.ts +12 -1
- package/src/resources/extensions/gsd/auto-dispatch.ts +34 -12
- package/src/resources/extensions/gsd/auto-model-selection.ts +49 -18
- package/src/resources/extensions/gsd/auto-post-unit.ts +1 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +80 -25
- package/src/resources/extensions/gsd/auto-recovery.ts +13 -518
- package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -5
- package/src/resources/extensions/gsd/auto-start.ts +4 -3
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +7 -2
- package/src/resources/extensions/gsd/auto-verification.ts +5 -1
- package/src/resources/extensions/gsd/auto-worktree.ts +50 -11
- package/src/resources/extensions/gsd/auto.ts +36 -8
- package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +44 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +8 -4
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +171 -23
- package/src/resources/extensions/gsd/bootstrap/tests/write-gate-basepath.test.ts +49 -1
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +60 -37
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +39 -5
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +2 -1
- package/src/resources/extensions/gsd/codebase-generator.ts +179 -18
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +1 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +39 -3
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +136 -2
- package/src/resources/extensions/gsd/commands-usage.ts +1 -1
- package/src/resources/extensions/gsd/commands-worktree.ts +13 -2
- package/src/resources/extensions/gsd/db/engine.ts +8 -1
- package/src/resources/extensions/gsd/db/queries.ts +40 -0
- package/src/resources/extensions/gsd/db-memory-fts-schema.ts +45 -0
- package/src/resources/extensions/gsd/db-workspace.ts +61 -3
- package/src/resources/extensions/gsd/delegation-policy.ts +1 -1
- package/src/resources/extensions/gsd/discussion-handoff.ts +10 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -4
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +275 -5
- package/src/resources/extensions/gsd/doctor-providers.ts +39 -10
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +3 -0
- package/src/resources/extensions/gsd/doctor-types.ts +8 -1
- package/src/resources/extensions/gsd/doctor.ts +95 -3
- package/src/resources/extensions/gsd/exec-sandbox.ts +13 -4
- package/src/resources/extensions/gsd/flat-phase-migration.ts +142 -22
- package/src/resources/extensions/gsd/git-service.ts +70 -9
- package/src/resources/extensions/gsd/gitignore.ts +4 -1
- package/src/resources/extensions/gsd/guidance.ts +2 -0
- package/src/resources/extensions/gsd/guided-flow-queue.ts +20 -13
- package/src/resources/extensions/gsd/guided-flow.ts +45 -2
- package/src/resources/extensions/gsd/json-persistence.ts +20 -0
- package/src/resources/extensions/gsd/key-manager.ts +1 -0
- package/src/resources/extensions/gsd/knowledge-backfill.ts +16 -10
- package/src/resources/extensions/gsd/layout-policy.ts +2 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +27 -17
- package/src/resources/extensions/gsd/memory-backfill.ts +26 -20
- package/src/resources/extensions/gsd/metrics.ts +4 -4
- package/src/resources/extensions/gsd/migrate-external.ts +17 -4
- package/src/resources/extensions/gsd/migration-auto-check.ts +23 -0
- package/src/resources/extensions/gsd/milestone-ids.ts +31 -2
- package/src/resources/extensions/gsd/model-router.ts +4 -5
- package/src/resources/extensions/gsd/orphan-stash-audit.ts +108 -20
- package/src/resources/extensions/gsd/preferences-diagnostics.ts +24 -0
- package/src/resources/extensions/gsd/preferences-models.ts +6 -3
- package/src/resources/extensions/gsd/preferences-validation.ts +28 -2
- package/src/resources/extensions/gsd/preferences.ts +38 -4
- package/src/resources/extensions/gsd/prompts/code-review.md +6 -4
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +5 -3
- package/src/resources/extensions/gsd/redact-secrets.ts +40 -0
- package/src/resources/extensions/gsd/repository-registry.ts +7 -1
- package/src/resources/extensions/gsd/root-write-leak-guard.ts +13 -1
- package/src/resources/extensions/gsd/safe-fs.ts +22 -2
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +9 -1
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +16 -1
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +8 -2
- package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
- package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +2 -1
- package/src/resources/extensions/gsd/state/derive/cache.ts +46 -0
- package/src/resources/extensions/gsd/state/derive/db-open.ts +45 -0
- package/src/resources/extensions/gsd/state/derive/from-db.ts +561 -0
- package/src/resources/extensions/gsd/state/derive/index.ts +104 -0
- package/src/resources/extensions/gsd/state/derive/interrupted-work.ts +31 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +36 -30
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +50 -24
- package/src/resources/extensions/gsd/state-reconciliation/registry.ts +43 -28
- package/src/resources/extensions/gsd/state.ts +32 -732
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +98 -1
- package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +14 -5
- package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +178 -0
- package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +182 -4
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/auto-session-scope.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/auto-timeout-recovery-harness-abort.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/batch-task-query.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +365 -0
- package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +62 -1
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/db-memory-fts-schema.test.ts +58 -3
- package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +143 -0
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +138 -1
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +296 -2
- package/src/resources/extensions/gsd/tests/doctor-workspace.test.ts +207 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +74 -2
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +87 -19
- package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +11 -2
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/json-persistence-atomic.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +31 -1
- package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/metrics.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +57 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +91 -7
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +103 -4
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +307 -1
- package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/preferences.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +50 -14
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -6
- package/src/resources/extensions/gsd/tests/recovery-verify-logs.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/redact-secrets.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/register-hooks-flat-phase-migration.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +378 -0
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +41 -2
- package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +20 -1
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +15 -3
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +115 -0
- package/src/resources/extensions/gsd/tests/status-per-repo.test.ts +94 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +203 -0
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/undo.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +66 -18
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +53 -1
- package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +69 -4
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +96 -15
- package/src/resources/extensions/gsd/tests/workflow-mcp-preflight.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +214 -6
- package/src/resources/extensions/gsd/tests/workspace.test.ts +18 -4
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +31 -1
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +32 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
- package/src/resources/extensions/gsd/tools/complete-slice.ts +3 -30
- package/src/resources/extensions/gsd/tools/complete-task.ts +7 -39
- package/src/resources/extensions/gsd/tools/plan-slice.ts +60 -47
- package/src/resources/extensions/gsd/tools/plan-task.ts +135 -12
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +58 -0
- package/src/resources/extensions/gsd/undo.ts +47 -6
- package/src/resources/extensions/gsd/unit-context-manifest.ts +11 -5
- package/src/resources/extensions/gsd/unit-registry.ts +11 -3
- package/src/resources/extensions/gsd/unit-runtime.ts +42 -0
- package/src/resources/extensions/gsd/verification-gate.ts +8 -0
- package/src/resources/extensions/gsd/workflow-manifest.ts +141 -7
- package/src/resources/extensions/gsd/workflow-projections.ts +20 -14
- package/src/resources/extensions/gsd/workspace.ts +42 -8
- package/src/resources/extensions/gsd/worktree-manager.ts +183 -5
- package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +0 -1
- package/dist/web/standalone/.next/static/chunks/796.3976108148518f7d.js +0 -10
- package/dist/web/standalone/.next/static/chunks/webpack-7c1d97e39be2da11.js +0 -1
- /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → kIEFsCryyGy6RzifULbJl}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → kIEFsCryyGy6RzifULbJl}/_ssgManifest.js +0 -0
|
@@ -65,14 +65,18 @@ test("auto execute-task requires canonical task completion tool", () => {
|
|
|
65
65
|
assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("execute-task"), expected);
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
test("plan-slice requires planning and roadmap reassessment tools", () => {
|
|
69
|
-
|
|
68
|
+
test("plan-slice requires slice + incremental task planning and roadmap reassessment tools", () => {
|
|
69
|
+
// Incremental planning (#1027): gsd_plan_slice persists metadata, then
|
|
70
|
+
// gsd_plan_task adds tasks one at a time, so both must be on the surface.
|
|
71
|
+
const expected = ["gsd_plan_slice", "gsd_plan_task", "gsd_reassess_roadmap"];
|
|
70
72
|
assert.deepEqual(getRequiredWorkflowToolsForGuidedUnit("plan-slice"), expected);
|
|
71
73
|
assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("plan-slice"), expected);
|
|
72
74
|
});
|
|
73
75
|
|
|
74
|
-
test("plan-milestone requires status, roadmap, and
|
|
75
|
-
|
|
76
|
+
test("plan-milestone requires status, roadmap, and slice + task planning tools", () => {
|
|
77
|
+
// gsd_plan_task is required alongside gsd_plan_slice for incremental
|
|
78
|
+
// milestone planning (#1027).
|
|
79
|
+
const expected = ["gsd_milestone_status", "gsd_plan_milestone", "gsd_plan_slice", "gsd_plan_task"];
|
|
76
80
|
assert.deepEqual(getRequiredWorkflowToolsForGuidedUnit("plan-milestone"), expected);
|
|
77
81
|
assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("plan-milestone"), expected);
|
|
78
82
|
});
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
getArtifact,
|
|
13
13
|
getAssessment,
|
|
14
14
|
insertAssessment,
|
|
15
|
+
insertGateRow,
|
|
15
16
|
insertMilestone,
|
|
16
17
|
upsertRequirement,
|
|
17
18
|
getAllMilestones,
|
|
@@ -21,6 +22,7 @@ import { claimMilestoneLease, getMilestoneLease } from "../db/milestone-leases.t
|
|
|
21
22
|
import { deriveState, invalidateStateCache } from "../state.ts";
|
|
22
23
|
import { autoSession } from "../auto-runtime-state.ts";
|
|
23
24
|
import { normalizeRealPath } from "../paths.ts";
|
|
25
|
+
import { recordUnitHarnessAbort } from "../unit-runtime.ts";
|
|
24
26
|
import { markApprovalGateVerified, markDepthVerified, clearDiscussionFlowState, loadWriteGateSnapshot, setPendingGate } from "../bootstrap/write-gate.ts";
|
|
25
27
|
import {
|
|
26
28
|
executeCompleteMilestone,
|
|
@@ -37,6 +39,11 @@ import {
|
|
|
37
39
|
executeValidateMilestone,
|
|
38
40
|
executeUatResultSave,
|
|
39
41
|
} from "../tools/workflow-tool-executors.ts";
|
|
42
|
+
import {
|
|
43
|
+
initNotificationStore,
|
|
44
|
+
readNotifications,
|
|
45
|
+
_resetNotificationStore,
|
|
46
|
+
} from "../notification-store.ts";
|
|
40
47
|
|
|
41
48
|
function makeTmpBase(): string {
|
|
42
49
|
const base = join(tmpdir(), `gsd-workflow-executors-${randomUUID()}`);
|
|
@@ -781,22 +788,23 @@ test("executePlanSlice writes task planning state and rendered plan artifacts",
|
|
|
781
788
|
}
|
|
782
789
|
});
|
|
783
790
|
|
|
784
|
-
test("executePlanSlice
|
|
791
|
+
test("executePlanSlice accepts metadata-only incremental planning payloads", async () => {
|
|
785
792
|
const base = makeTmpBase();
|
|
786
793
|
try {
|
|
787
794
|
openTestDb(base);
|
|
795
|
+
await inProjectDir(base, () => executePlanMilestone(validMilestonePlan(), base));
|
|
788
796
|
|
|
789
797
|
const result = await inProjectDir(base, () => executePlanSlice({
|
|
790
798
|
milestoneId: "M001",
|
|
791
799
|
sliceId: "S01",
|
|
792
|
-
goal: "
|
|
800
|
+
goal: "Persist slice metadata before tasks.",
|
|
793
801
|
tasks: [],
|
|
794
802
|
}, base));
|
|
795
803
|
|
|
796
|
-
assert.equal(result.isError, true);
|
|
797
804
|
assert.equal(result.details.operation, "plan_slice");
|
|
798
|
-
assert.
|
|
799
|
-
assert.
|
|
805
|
+
assert.equal(result.details.sliceId, "S01");
|
|
806
|
+
assert.equal(result.isError, undefined);
|
|
807
|
+
assert.match(result.content[0].text, /Planned slice S01/);
|
|
800
808
|
} finally {
|
|
801
809
|
closeDatabase();
|
|
802
810
|
cleanup(base);
|
|
@@ -909,6 +917,104 @@ test("executeUatResultSave accepts gsd_uat_exec evidence written in a milestone
|
|
|
909
917
|
}
|
|
910
918
|
});
|
|
911
919
|
|
|
920
|
+
test("executeUatResultSave leaves UAT pending after a harness-aborted turn", async () => {
|
|
921
|
+
const base = makeTmpBase();
|
|
922
|
+
const worktree = join(base, ".gsd", "worktrees", "M001");
|
|
923
|
+
const worktreeExecDir = join(worktree, ".gsd", "exec");
|
|
924
|
+
const evidenceId = "harness-aborted-uat-evidence";
|
|
925
|
+
const startedAt = Date.now();
|
|
926
|
+
try {
|
|
927
|
+
openTestDb(base);
|
|
928
|
+
seedMilestone("M001", "Milestone One");
|
|
929
|
+
seedSlice("M001", "S04", "complete");
|
|
930
|
+
mkdirSync(worktreeExecDir, { recursive: true });
|
|
931
|
+
writeFileSync(
|
|
932
|
+
join(worktreeExecDir, `${evidenceId}.meta.json`),
|
|
933
|
+
JSON.stringify({
|
|
934
|
+
id: evidenceId,
|
|
935
|
+
metadata: {
|
|
936
|
+
kind: "uat_exec",
|
|
937
|
+
milestoneId: "M001",
|
|
938
|
+
sliceId: "S04",
|
|
939
|
+
checkId: "UAT-01",
|
|
940
|
+
intent: "uat-runtime-check",
|
|
941
|
+
},
|
|
942
|
+
}),
|
|
943
|
+
"utf-8",
|
|
944
|
+
);
|
|
945
|
+
_getAdapter()!.prepare(
|
|
946
|
+
`INSERT INTO quality_gates (milestone_id, slice_id, gate_id, scope, task_id, status)
|
|
947
|
+
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
948
|
+
).run("M001", "S04", "UAT", "slice", "", "pending");
|
|
949
|
+
autoSession.reset();
|
|
950
|
+
autoSession.active = true;
|
|
951
|
+
autoSession.basePath = base;
|
|
952
|
+
autoSession.currentUnit = { type: "run-uat", id: "M001/S04", startedAt, workspaceRoot: worktree };
|
|
953
|
+
recordUnitHarnessAbort(base, "run-uat", "M001/S04", startedAt, {
|
|
954
|
+
kind: "tool-loop-guard",
|
|
955
|
+
reason: "Tool loop detected (repeated tool): browser_click called 7 times this turn.",
|
|
956
|
+
toolName: "browser_click",
|
|
957
|
+
count: 7,
|
|
958
|
+
});
|
|
959
|
+
|
|
960
|
+
const result = await inProjectDir(worktree, () => executeUatResultSave({
|
|
961
|
+
milestoneId: "M001",
|
|
962
|
+
sliceId: "S04",
|
|
963
|
+
uatType: "runtime-executable",
|
|
964
|
+
verdict: "FAIL",
|
|
965
|
+
checks: [{
|
|
966
|
+
id: "UAT-01",
|
|
967
|
+
description: "Runtime behavior could not be fully evaluated before harness abort",
|
|
968
|
+
mode: "runtime",
|
|
969
|
+
result: "FAIL",
|
|
970
|
+
evidence: [{ kind: "gsd_uat_exec", ref: evidenceId }],
|
|
971
|
+
notes: "Partial failure should be retried because the harness aborted the turn.",
|
|
972
|
+
}],
|
|
973
|
+
presentation: {
|
|
974
|
+
surface: "mcp",
|
|
975
|
+
presentedTools: [
|
|
976
|
+
"gsd_uat_exec",
|
|
977
|
+
"gsd_uat_result_save",
|
|
978
|
+
"gsd_resume",
|
|
979
|
+
"gsd_milestone_status",
|
|
980
|
+
"gsd_journal_query",
|
|
981
|
+
],
|
|
982
|
+
blockedTools: [
|
|
983
|
+
{ name: "gsd_exec", reason: "forbidden during run-uat" },
|
|
984
|
+
{ name: "gsd_summary_save", reason: "forbidden during run-uat" },
|
|
985
|
+
{ name: "gsd_save_gate_result", reason: "forbidden during run-uat" },
|
|
986
|
+
],
|
|
987
|
+
},
|
|
988
|
+
notes: "Partial UAT result after harness abort.",
|
|
989
|
+
}, worktree));
|
|
990
|
+
|
|
991
|
+
assert.equal(result.isError, true);
|
|
992
|
+
assert.equal(result.details.operation, "save_uat_result");
|
|
993
|
+
assert.equal(result.details.error, "harness_aborted_needs_retry");
|
|
994
|
+
assert.equal(result.details.retryable, true);
|
|
995
|
+
assert.equal(result.details.harnessAbortKind, "tool-loop-guard");
|
|
996
|
+
assert.equal(
|
|
997
|
+
existsSync(join(base, ".gsd", "uat", "M001", "S04", "attempt-1.json")),
|
|
998
|
+
false,
|
|
999
|
+
"harness-aborted UAT should not persist an attempt artifact",
|
|
1000
|
+
);
|
|
1001
|
+
assert.equal(
|
|
1002
|
+
existsSync(join(base, ".gsd", "phases", "01-m001", "01-04-ASSESSMENT.md")),
|
|
1003
|
+
false,
|
|
1004
|
+
"harness-aborted UAT should not write an ASSESSMENT verdict",
|
|
1005
|
+
);
|
|
1006
|
+
const row = _getAdapter()!.prepare(
|
|
1007
|
+
"SELECT status, verdict FROM quality_gates WHERE milestone_id = ? AND slice_id = ? AND gate_id = ?",
|
|
1008
|
+
).get("M001", "S04", "UAT") as Record<string, unknown>;
|
|
1009
|
+
assert.equal(row.status, "pending");
|
|
1010
|
+
assert.equal(row.verdict, "");
|
|
1011
|
+
} finally {
|
|
1012
|
+
autoSession.reset();
|
|
1013
|
+
closeDatabase();
|
|
1014
|
+
cleanup(base);
|
|
1015
|
+
}
|
|
1016
|
+
});
|
|
1017
|
+
|
|
912
1018
|
test("executeUatResultSave supplies canonical presentation and normalizes verdict casing", async () => {
|
|
913
1019
|
const base = makeTmpBase();
|
|
914
1020
|
const worktree = join(base, ".gsd", "worktrees", "M001");
|
|
@@ -1099,13 +1205,14 @@ test("executeUatResultSave merges canonical plan ID and read-only tools when pre
|
|
|
1099
1205
|
}
|
|
1100
1206
|
});
|
|
1101
1207
|
|
|
1102
|
-
test("executeUatResultSave surfaces the worktree validation path for NEEDS-HUMAN checks", async () => {
|
|
1208
|
+
test("executeUatResultSave surfaces the worktree validation path and notification for NEEDS-HUMAN checks", async () => {
|
|
1103
1209
|
const base = makeTmpBase();
|
|
1104
1210
|
const worktree = join(base, ".gsd", "worktrees", "M001");
|
|
1105
1211
|
const worktreeExecDir = join(worktree, ".gsd", "exec");
|
|
1106
1212
|
const evidenceId = "uat-human-validation-evidence";
|
|
1107
1213
|
try {
|
|
1108
1214
|
openTestDb(base);
|
|
1215
|
+
initNotificationStore(base);
|
|
1109
1216
|
seedMilestone("M001", "Milestone One");
|
|
1110
1217
|
seedSlice("M001", "S07", "complete");
|
|
1111
1218
|
mkdirSync(worktreeExecDir, { recursive: true });
|
|
@@ -1165,7 +1272,17 @@ test("executeUatResultSave surfaces the worktree validation path for NEEDS-HUMAN
|
|
|
1165
1272
|
assert.match(assessment, /## Manual Validation/);
|
|
1166
1273
|
assert.ok(assessment.includes(worktree), "assessment should include the worktree checkout path");
|
|
1167
1274
|
assert.match(assessment, /git worktree/);
|
|
1275
|
+
|
|
1276
|
+
const notifications = readNotifications(base, { kind: "uat-needs-human", scope: "M001/S07" });
|
|
1277
|
+
assert.equal(notifications.length, 1);
|
|
1278
|
+
assert.equal(notifications[0].severity, "warning");
|
|
1279
|
+
assert.equal(notifications[0].source, "notify");
|
|
1280
|
+
assert.equal(
|
|
1281
|
+
notifications[0].message,
|
|
1282
|
+
"UAT for M001/S07 has NEEDS-HUMAN checks awaiting human validation",
|
|
1283
|
+
);
|
|
1168
1284
|
} finally {
|
|
1285
|
+
_resetNotificationStore();
|
|
1169
1286
|
closeDatabase();
|
|
1170
1287
|
cleanup(base);
|
|
1171
1288
|
}
|
|
@@ -1756,6 +1873,97 @@ test("executeSaveGateResult validates inputs and persists verdicts", async () =>
|
|
|
1756
1873
|
}
|
|
1757
1874
|
});
|
|
1758
1875
|
|
|
1876
|
+
test("executeSaveGateResult leaves quality gates pending after a retryable tool error", async () => {
|
|
1877
|
+
const base = makeTmpBase();
|
|
1878
|
+
const startedAt = Date.now();
|
|
1879
|
+
try {
|
|
1880
|
+
openTestDb(base);
|
|
1881
|
+
seedMilestone("M005", "Milestone Five");
|
|
1882
|
+
seedSlice("M005", "S05", "pending");
|
|
1883
|
+
insertGateRow({ milestoneId: "M005", sliceId: "S05", gateId: "Q3", scope: "slice" });
|
|
1884
|
+
autoSession.reset();
|
|
1885
|
+
autoSession.active = true;
|
|
1886
|
+
autoSession.basePath = base;
|
|
1887
|
+
autoSession.currentUnit = { type: "plan-slice", id: "M005/S05", startedAt };
|
|
1888
|
+
recordUnitHarnessAbort(base, "plan-slice", "M005/S05", startedAt, {
|
|
1889
|
+
kind: "tool-error",
|
|
1890
|
+
reason: "Input validation error: selector is required",
|
|
1891
|
+
toolName: "browser_click",
|
|
1892
|
+
});
|
|
1893
|
+
|
|
1894
|
+
const result = await inProjectDir(base, () => executeSaveGateResult({
|
|
1895
|
+
milestoneId: "M005",
|
|
1896
|
+
sliceId: "S05",
|
|
1897
|
+
gateId: "Q3",
|
|
1898
|
+
verdict: "flag",
|
|
1899
|
+
rationale: "Partial gate failure after harness abort.",
|
|
1900
|
+
findings: "This should not be persisted as a product-quality finding.",
|
|
1901
|
+
}, base));
|
|
1902
|
+
|
|
1903
|
+
assert.equal(result.isError, true);
|
|
1904
|
+
assert.equal(result.details.operation, "save_gate_result");
|
|
1905
|
+
assert.equal(result.details.error, "harness_aborted_needs_retry");
|
|
1906
|
+
assert.equal(result.details.retryable, true);
|
|
1907
|
+
assert.equal(result.details.harnessAbortKind, "tool-error");
|
|
1908
|
+
const row = _getAdapter()!.prepare(
|
|
1909
|
+
"SELECT status, verdict, rationale, findings FROM quality_gates WHERE milestone_id = ? AND slice_id = ? AND gate_id = ? AND task_id = ''",
|
|
1910
|
+
).get("M005", "S05", "Q3") as Record<string, unknown>;
|
|
1911
|
+
assert.equal(row.status, "pending");
|
|
1912
|
+
assert.equal(row.verdict, "");
|
|
1913
|
+
assert.equal(row.rationale, "");
|
|
1914
|
+
assert.equal(row.findings, "");
|
|
1915
|
+
} finally {
|
|
1916
|
+
autoSession.reset();
|
|
1917
|
+
closeDatabase();
|
|
1918
|
+
cleanup(base);
|
|
1919
|
+
}
|
|
1920
|
+
});
|
|
1921
|
+
|
|
1922
|
+
test("executeSaveGateResult leaves quality gates pending after a turn abort", async () => {
|
|
1923
|
+
const base = makeTmpBase();
|
|
1924
|
+
const startedAt = Date.now();
|
|
1925
|
+
try {
|
|
1926
|
+
openTestDb(base);
|
|
1927
|
+
seedMilestone("M005", "Milestone Five");
|
|
1928
|
+
seedSlice("M005", "S05", "pending");
|
|
1929
|
+
insertGateRow({ milestoneId: "M005", sliceId: "S05", gateId: "Q3", scope: "slice" });
|
|
1930
|
+
autoSession.reset();
|
|
1931
|
+
autoSession.active = true;
|
|
1932
|
+
autoSession.basePath = base;
|
|
1933
|
+
autoSession.currentUnit = { type: "plan-slice", id: "M005/S05", startedAt };
|
|
1934
|
+
recordUnitHarnessAbort(base, "plan-slice", "M005/S05", startedAt, {
|
|
1935
|
+
kind: "turn-abort",
|
|
1936
|
+
reason: "Agent turn aborted before the gate evaluation completed. origin=timeout stopReason=aborted",
|
|
1937
|
+
});
|
|
1938
|
+
|
|
1939
|
+
const result = await inProjectDir(base, () => executeSaveGateResult({
|
|
1940
|
+
milestoneId: "M005",
|
|
1941
|
+
sliceId: "S05",
|
|
1942
|
+
gateId: "Q3",
|
|
1943
|
+
verdict: "flag",
|
|
1944
|
+
rationale: "Partial gate failure after a turn abort.",
|
|
1945
|
+
findings: "This should not be persisted as a product-quality finding.",
|
|
1946
|
+
}, base));
|
|
1947
|
+
|
|
1948
|
+
assert.equal(result.isError, true);
|
|
1949
|
+
assert.equal(result.details.operation, "save_gate_result");
|
|
1950
|
+
assert.equal(result.details.error, "harness_aborted_needs_retry");
|
|
1951
|
+
assert.equal(result.details.retryable, true);
|
|
1952
|
+
assert.equal(result.details.harnessAbortKind, "turn-abort");
|
|
1953
|
+
const row = _getAdapter()!.prepare(
|
|
1954
|
+
"SELECT status, verdict, rationale, findings FROM quality_gates WHERE milestone_id = ? AND slice_id = ? AND gate_id = ? AND task_id = ''",
|
|
1955
|
+
).get("M005", "S05", "Q3") as Record<string, unknown>;
|
|
1956
|
+
assert.equal(row.status, "pending");
|
|
1957
|
+
assert.equal(row.verdict, "");
|
|
1958
|
+
assert.equal(row.rationale, "");
|
|
1959
|
+
assert.equal(row.findings, "");
|
|
1960
|
+
} finally {
|
|
1961
|
+
autoSession.reset();
|
|
1962
|
+
closeDatabase();
|
|
1963
|
+
cleanup(base);
|
|
1964
|
+
}
|
|
1965
|
+
});
|
|
1966
|
+
|
|
1759
1967
|
test("executeSaveGateResult fails when no canonical gate row is updated", async () => {
|
|
1760
1968
|
const base = makeTmpBase();
|
|
1761
1969
|
try {
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
rmSync,
|
|
9
9
|
realpathSync,
|
|
10
10
|
symlinkSync,
|
|
11
|
+
writeFileSync,
|
|
11
12
|
} from "node:fs";
|
|
12
13
|
import { tmpdir } from "node:os";
|
|
13
14
|
import { join } from "node:path";
|
|
@@ -118,17 +119,17 @@ describe("scopeMilestone path methods", () => {
|
|
|
118
119
|
rmSync(projectDir, { recursive: true, force: true });
|
|
119
120
|
});
|
|
120
121
|
|
|
121
|
-
test("produces
|
|
122
|
+
test("produces flat-phase paths for a known milestone ID", () => {
|
|
122
123
|
const ws = createWorkspace(projectDir);
|
|
123
124
|
const scope = scopeMilestone(ws, MID);
|
|
124
125
|
const gsd = ws.contract.projectGsd;
|
|
125
126
|
|
|
126
127
|
assert.equal(scope.milestoneId, MID);
|
|
127
|
-
assert.equal(scope.contextFile(), join(gsd, "
|
|
128
|
-
assert.equal(scope.roadmapFile(), join(gsd, "
|
|
128
|
+
assert.equal(scope.contextFile(), join(gsd, "phases", "01-m001", "01-CONTEXT.md"));
|
|
129
|
+
assert.equal(scope.roadmapFile(), join(gsd, "phases", "01-m001", "01-ROADMAP.md"));
|
|
129
130
|
assert.equal(scope.stateFile(), join(gsd, "STATE.md"));
|
|
130
131
|
assert.equal(scope.dbPath(), ws.contract.projectDb);
|
|
131
|
-
assert.equal(scope.milestoneDir(), join(gsd, "
|
|
132
|
+
assert.equal(scope.milestoneDir(), join(gsd, "phases", "01-m001"));
|
|
132
133
|
assert.equal(scope.metaJson(), join(gsd, `${MID}-META.json`));
|
|
133
134
|
});
|
|
134
135
|
|
|
@@ -144,6 +145,19 @@ describe("scopeMilestone path methods", () => {
|
|
|
144
145
|
assert.equal(scope1.milestoneDir(), scope2.milestoneDir());
|
|
145
146
|
assert.equal(scope1.metaJson(), scope2.metaJson());
|
|
146
147
|
});
|
|
148
|
+
|
|
149
|
+
test("uses legacy milestone paths when legacy content exists", () => {
|
|
150
|
+
const legacyDir = join(projectDir, ".gsd", "milestones", MID);
|
|
151
|
+
mkdirSync(legacyDir, { recursive: true });
|
|
152
|
+
writeFileSync(join(legacyDir, `${MID}-CONTEXT.md`), "# Legacy context\n");
|
|
153
|
+
|
|
154
|
+
const ws = createWorkspace(projectDir);
|
|
155
|
+
const scope = scopeMilestone(ws, MID);
|
|
156
|
+
|
|
157
|
+
assert.equal(scope.contextFile(), join(legacyDir, `${MID}-CONTEXT.md`));
|
|
158
|
+
assert.equal(scope.roadmapFile(), join(legacyDir, `${MID}-ROADMAP.md`));
|
|
159
|
+
assert.equal(scope.milestoneDir(), legacyDir);
|
|
160
|
+
});
|
|
147
161
|
});
|
|
148
162
|
|
|
149
163
|
describe("createWorkspace: contract.projectGsd is realpath-canonicalized when basePath is a symlink", () => {
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
diffWorktreeNumstat,
|
|
14
14
|
getWorktreeGSDDiff,
|
|
15
15
|
getWorktreeLog,
|
|
16
|
+
mergeWorktreeToMain,
|
|
16
17
|
worktreeBranchName,
|
|
17
18
|
worktreePath,
|
|
18
19
|
pruneEphemeralGhostWorktreeDirectories,
|
|
@@ -333,6 +334,44 @@ describe("getWorktreeLog", () => {
|
|
|
333
334
|
});
|
|
334
335
|
});
|
|
335
336
|
|
|
337
|
+
// ─── mergeWorktreeToMain ─────────────────────────────────────────────────────
|
|
338
|
+
|
|
339
|
+
describe("mergeWorktreeToMain", () => {
|
|
340
|
+
let base: string;
|
|
341
|
+
let wtPath: string;
|
|
342
|
+
|
|
343
|
+
beforeEach(() => {
|
|
344
|
+
base = makeBaseRepo();
|
|
345
|
+
wtPath = worktreePath(base, "M900");
|
|
346
|
+
mkdirSync(join(base, ".gsd-worktrees"), { recursive: true });
|
|
347
|
+
run(`git worktree add -b milestone/M900 "${wtPath}"`, base);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
afterEach(() => { rmSync(base, { recursive: true, force: true }); });
|
|
351
|
+
|
|
352
|
+
test("cleans failed milestone squash state and deletes orphan branch", () => {
|
|
353
|
+
writeFileSync(join(wtPath, "README.md"), "# Milestone change\n", "utf-8");
|
|
354
|
+
run("git add README.md", wtPath);
|
|
355
|
+
run('git commit -m "feat: milestone change"', wtPath);
|
|
356
|
+
|
|
357
|
+
writeFileSync(join(base, "README.md"), "# Main change\n", "utf-8");
|
|
358
|
+
run("git add README.md", base);
|
|
359
|
+
run('git commit -m "feat: main change"', base);
|
|
360
|
+
|
|
361
|
+
assert.throws(
|
|
362
|
+
() => mergeWorktreeToMain(base, "M900", "feat: merge M900", "milestone/M900"),
|
|
363
|
+
/Merge conflicts detected/,
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
assert.equal(run("git status --porcelain", base), "", "failed squash cleanup should leave main clean");
|
|
367
|
+
assert.ok(!existsSync(wtPath), "failed milestone worktree should be removed");
|
|
368
|
+
assert.ok(
|
|
369
|
+
!run("git branch", base).includes("milestone/M900"),
|
|
370
|
+
"failed milestone branch should be deleted after worktree removal",
|
|
371
|
+
);
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
|
|
336
375
|
// ─── removeWorktree ───────────────────────────────────────────────────────────
|
|
337
376
|
|
|
338
377
|
describe("removeWorktree", () => {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* - syncWorktreeStateBack skips non-standard milestone projection dir names
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, readFileSync } from 'node:fs';
|
|
26
|
+
import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, readFileSync, statSync } from 'node:fs';
|
|
27
27
|
import { join } from 'node:path';
|
|
28
28
|
import { tmpdir } from 'node:os';
|
|
29
29
|
|
|
@@ -148,6 +148,36 @@ describe('worktree-sync-milestones', async () => {
|
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
// ─── 3c. artifact file/dir collisions preserve existing worktree files ─
|
|
152
|
+
console.log('\n=== 3c. artifact file/dir collisions preserve existing worktree files (#1157) ===');
|
|
153
|
+
{
|
|
154
|
+
const mainBase = createBase('main');
|
|
155
|
+
const wtBase = createBase('wt');
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
const mainSliceDir = join(mainBase, '.gsd', 'milestones', 'M001', 'slices', 'S01');
|
|
159
|
+
mkdirSync(join(mainSliceDir, 'S01-SUMMARY.md'), { recursive: true });
|
|
160
|
+
mkdirSync(join(mainSliceDir, 'S01-ASSESSMENT.md'), { recursive: true });
|
|
161
|
+
|
|
162
|
+
const wtSliceDir = join(wtBase, '.gsd', 'milestones', 'M001', 'slices', 'S01');
|
|
163
|
+
mkdirSync(wtSliceDir, { recursive: true });
|
|
164
|
+
writeFileSync(join(wtSliceDir, 'S01-SUMMARY.md'), '# Valid summary\n');
|
|
165
|
+
writeFileSync(join(wtSliceDir, 'S01-ASSESSMENT.md'), '---\nverdict: pass\n---\n# Valid assessment\n');
|
|
166
|
+
|
|
167
|
+
syncProjectRootToWorktree(mainBase, wtBase, 'M001');
|
|
168
|
+
|
|
169
|
+
const summaryPath = join(wtSliceDir, 'S01-SUMMARY.md');
|
|
170
|
+
const assessmentPath = join(wtSliceDir, 'S01-ASSESSMENT.md');
|
|
171
|
+
assert.ok(statSync(summaryPath).isFile(), 'existing SUMMARY.md stays a file');
|
|
172
|
+
assert.ok(statSync(assessmentPath).isFile(), 'existing ASSESSMENT.md stays a file');
|
|
173
|
+
assert.equal(readFileSync(summaryPath, 'utf-8'), '# Valid summary\n');
|
|
174
|
+
assert.equal(readFileSync(assessmentPath, 'utf-8'), '---\nverdict: pass\n---\n# Valid assessment\n');
|
|
175
|
+
} finally {
|
|
176
|
+
cleanup(mainBase);
|
|
177
|
+
cleanup(wtBase);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
151
181
|
// ─── 4. No-op when paths are equal ────────────────────────────────────
|
|
152
182
|
console.log('\n=== 4. no-op when paths are equal ===');
|
|
153
183
|
{
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
existsSync,
|
|
21
21
|
realpathSync,
|
|
22
22
|
readFileSync,
|
|
23
|
+
readdirSync,
|
|
23
24
|
} from "node:fs";
|
|
24
25
|
import { join } from "node:path";
|
|
25
26
|
import { tmpdir } from "node:os";
|
|
@@ -132,6 +133,37 @@ describe("worktree-teardown-safety", () => {
|
|
|
132
133
|
);
|
|
133
134
|
});
|
|
134
135
|
|
|
136
|
+
it("removeWorktree quarantines dirty worktree contents before forced cleanup", () => {
|
|
137
|
+
const tempDir = createTempRepo();
|
|
138
|
+
dirs.push(tempDir);
|
|
139
|
+
|
|
140
|
+
const wt = createWorktree(tempDir, "dirty-wt");
|
|
141
|
+
writeFileSync(join(wt.path, "generated-feature.ts"), "export const answer = 42;\n");
|
|
142
|
+
writeFileSync(join(wt.path, "README.md"), "# changed in worktree\n");
|
|
143
|
+
|
|
144
|
+
removeWorktree(tempDir, "dirty-wt", { deleteBranch: false });
|
|
145
|
+
|
|
146
|
+
assertTrue(!existsSync(wt.path), "original dirty worktree path removed after quarantine");
|
|
147
|
+
const quarantineRoot = join(tempDir, ".gsd", "quarantine", "worktrees");
|
|
148
|
+
const entries = readdirSync(quarantineRoot).filter((entry) => entry.startsWith("dirty-wt-"));
|
|
149
|
+
assertEq(entries.length, 1, "dirty worktree snapshot quarantined");
|
|
150
|
+
const quarantineDir = join(quarantineRoot, entries[0]!);
|
|
151
|
+
assertEq(
|
|
152
|
+
readFileSync(join(quarantineDir, "generated-feature.ts"), "utf-8"),
|
|
153
|
+
"export const answer = 42;\n",
|
|
154
|
+
"untracked source file survives in quarantine",
|
|
155
|
+
);
|
|
156
|
+
assertEq(
|
|
157
|
+
readFileSync(join(quarantineDir, "README.md"), "utf-8"),
|
|
158
|
+
"# changed in worktree\n",
|
|
159
|
+
"modified tracked file survives in quarantine",
|
|
160
|
+
);
|
|
161
|
+
assertTrue(
|
|
162
|
+
existsSync(join(quarantineDir, ".gsd-quarantine.json")),
|
|
163
|
+
"quarantine metadata written",
|
|
164
|
+
);
|
|
165
|
+
});
|
|
166
|
+
|
|
135
167
|
it("worktreePath always returns paths under .gsd/worktrees/", () => {
|
|
136
168
|
const tempDir = createTempRepo();
|
|
137
169
|
dirs.push(tempDir);
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
} from "../gsd-db.js";
|
|
24
24
|
import { gsdProjectionRoot, clearPathCache, relMilestoneFile } from "../paths.js";
|
|
25
25
|
import { resolveCanonicalMilestoneRoot } from "../worktree-manager.js";
|
|
26
|
-
import { isClosedStatus } from "../status-guards.js";
|
|
26
|
+
import { isClosedStatus, isDeferredStatus } from "../status-guards.js";
|
|
27
27
|
import { saveFile, clearParseCache } from "../files.js";
|
|
28
28
|
import { invalidateStateCache } from "../state.js";
|
|
29
29
|
import { stripIdPrefix } from "../workflow-projections.js";
|
|
@@ -180,7 +180,7 @@ export async function handleCompleteMilestone(
|
|
|
180
180
|
return;
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
const incompleteSlices = slices.filter(s => !isClosedStatus(s.status));
|
|
183
|
+
const incompleteSlices = slices.filter(s => !isClosedStatus(s.status) && !isDeferredStatus(s.status));
|
|
184
184
|
if (incompleteSlices.length > 0) {
|
|
185
185
|
const incompleteIds = incompleteSlices.map(s => `${s.id} (status: ${s.status})`).join(", ");
|
|
186
186
|
guardError = `incomplete slices: ${incompleteIds}`;
|
|
@@ -189,6 +189,7 @@ export async function handleCompleteMilestone(
|
|
|
189
189
|
|
|
190
190
|
// Deep check: verify all tasks in all slices are complete
|
|
191
191
|
for (const slice of slices) {
|
|
192
|
+
if (isDeferredStatus(slice.status)) continue;
|
|
192
193
|
const tasks = getSliceTasks(params.milestoneId, slice.id);
|
|
193
194
|
const incompleteTasks = tasks.filter(t => !isClosedStatus(t.status));
|
|
194
195
|
if (incompleteTasks.length > 0) {
|
|
@@ -30,7 +30,7 @@ import { classifyUatContent, escalatesArtifactUatToBrowser } from "../uat-policy
|
|
|
30
30
|
import { invalidateStateCache } from "../state.js";
|
|
31
31
|
import { renderRoadmapFromDb, roadmapRenderMarksSliceDone } from "../markdown-renderer.js";
|
|
32
32
|
import { isStaleWrite } from "../auto/turn-epoch.js";
|
|
33
|
-
import {
|
|
33
|
+
import { renderMilestoneShellProjections } from "../workflow-projections.js";
|
|
34
34
|
import { writeManifest } from "../workflow-manifest.js";
|
|
35
35
|
import { appendEvent } from "../workflow-events.js";
|
|
36
36
|
import { logWarning, logError } from "../workflow-logger.js";
|
|
@@ -539,37 +539,10 @@ export async function handleCompleteSlice(
|
|
|
539
539
|
// ── Post-mutation hook: projections, manifest, event log ───────────────
|
|
540
540
|
// Separate try/catch per step so a projection failure doesn't prevent
|
|
541
541
|
// the event log entry (critical for worktree reconciliation).
|
|
542
|
-
//
|
|
543
|
-
// If the primary summary/UAT/roadmap write block failed (projectionStale),
|
|
544
|
-
// retry the milestone-level roadmap here so ROADMAP.md is not left stale
|
|
545
|
-
// after a committed slice completion. This restores the recovery that the
|
|
546
|
-
// removed flushWorkflowProjections/renderAllProjections provided.
|
|
547
|
-
if (projectionStale) {
|
|
548
|
-
try {
|
|
549
|
-
await renderRoadmapFromDb(artifactBasePath, params.milestoneId);
|
|
550
|
-
} catch (projErr) {
|
|
551
|
-
logWarning("tool", `complete-slice milestone roadmap retry warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
try {
|
|
555
|
-
await renderRoadmapFromDb(artifactBasePath, params.milestoneId);
|
|
556
|
-
} catch (projErr) {
|
|
557
|
-
logWarning("tool", `complete-slice milestone roadmap projection warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
|
|
558
|
-
}
|
|
559
|
-
try {
|
|
560
|
-
renderTopLevelRoadmapFromDb(artifactBasePath);
|
|
561
|
-
} catch (projErr) {
|
|
562
|
-
logWarning("tool", `complete-slice roadmap projection warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
|
|
563
|
-
}
|
|
564
|
-
try {
|
|
565
|
-
renderTopLevelQueueFromDb(artifactBasePath);
|
|
566
|
-
} catch (projErr) {
|
|
567
|
-
logWarning("tool", `complete-slice queue projection warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
|
|
568
|
-
}
|
|
569
542
|
try {
|
|
570
|
-
await
|
|
543
|
+
await renderMilestoneShellProjections(artifactBasePath, params.milestoneId);
|
|
571
544
|
} catch (projErr) {
|
|
572
|
-
logWarning("tool", `complete-slice
|
|
545
|
+
logWarning("tool", `complete-slice projection warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
|
|
573
546
|
}
|
|
574
547
|
try {
|
|
575
548
|
writeManifest(artifactBasePath);
|