@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
|
@@ -13,7 +13,7 @@ import { existsSync } from "node:fs";
|
|
|
13
13
|
import { transaction, getMilestone, getMilestoneSlices, getSliceTasks, getLatestAssessmentByScope, updateMilestoneStatus, } from "../gsd-db.js";
|
|
14
14
|
import { clearPathCache, relMilestoneFile } from "../paths.js";
|
|
15
15
|
import { resolveCanonicalMilestoneRoot } from "../worktree-manager.js";
|
|
16
|
-
import { isClosedStatus } from "../status-guards.js";
|
|
16
|
+
import { isClosedStatus, isDeferredStatus } from "../status-guards.js";
|
|
17
17
|
import { saveFile, clearParseCache } from "../files.js";
|
|
18
18
|
import { invalidateStateCache } from "../state.js";
|
|
19
19
|
import { stripIdPrefix } from "../workflow-projections.js";
|
|
@@ -118,7 +118,7 @@ export async function handleCompleteMilestone(params, basePath) {
|
|
|
118
118
|
guardError = `no slices found for milestone ${params.milestoneId}`;
|
|
119
119
|
return;
|
|
120
120
|
}
|
|
121
|
-
const incompleteSlices = slices.filter(s => !isClosedStatus(s.status));
|
|
121
|
+
const incompleteSlices = slices.filter(s => !isClosedStatus(s.status) && !isDeferredStatus(s.status));
|
|
122
122
|
if (incompleteSlices.length > 0) {
|
|
123
123
|
const incompleteIds = incompleteSlices.map(s => `${s.id} (status: ${s.status})`).join(", ");
|
|
124
124
|
guardError = `incomplete slices: ${incompleteIds}`;
|
|
@@ -126,6 +126,8 @@ export async function handleCompleteMilestone(params, basePath) {
|
|
|
126
126
|
}
|
|
127
127
|
// Deep check: verify all tasks in all slices are complete
|
|
128
128
|
for (const slice of slices) {
|
|
129
|
+
if (isDeferredStatus(slice.status))
|
|
130
|
+
continue;
|
|
129
131
|
const tasks = getSliceTasks(params.milestoneId, slice.id);
|
|
130
132
|
const incompleteTasks = tasks.filter(t => !isClosedStatus(t.status));
|
|
131
133
|
if (incompleteTasks.length > 0) {
|
|
@@ -21,7 +21,7 @@ import { classifyUatContent, escalatesArtifactUatToBrowser } from "../uat-policy
|
|
|
21
21
|
import { invalidateStateCache } from "../state.js";
|
|
22
22
|
import { renderRoadmapFromDb, roadmapRenderMarksSliceDone } from "../markdown-renderer.js";
|
|
23
23
|
import { isStaleWrite } from "../auto/turn-epoch.js";
|
|
24
|
-
import {
|
|
24
|
+
import { renderMilestoneShellProjections } from "../workflow-projections.js";
|
|
25
25
|
import { writeManifest } from "../workflow-manifest.js";
|
|
26
26
|
import { appendEvent } from "../workflow-events.js";
|
|
27
27
|
import { logWarning, logError } from "../workflow-logger.js";
|
|
@@ -457,42 +457,11 @@ export async function handleCompleteSlice(params, basePath) {
|
|
|
457
457
|
// ── Post-mutation hook: projections, manifest, event log ───────────────
|
|
458
458
|
// Separate try/catch per step so a projection failure doesn't prevent
|
|
459
459
|
// the event log entry (critical for worktree reconciliation).
|
|
460
|
-
//
|
|
461
|
-
// If the primary summary/UAT/roadmap write block failed (projectionStale),
|
|
462
|
-
// retry the milestone-level roadmap here so ROADMAP.md is not left stale
|
|
463
|
-
// after a committed slice completion. This restores the recovery that the
|
|
464
|
-
// removed flushWorkflowProjections/renderAllProjections provided.
|
|
465
|
-
if (projectionStale) {
|
|
466
|
-
try {
|
|
467
|
-
await renderRoadmapFromDb(artifactBasePath, params.milestoneId);
|
|
468
|
-
}
|
|
469
|
-
catch (projErr) {
|
|
470
|
-
logWarning("tool", `complete-slice milestone roadmap retry warning for ${params.milestoneId}/${params.sliceId}: ${projErr.message}`);
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
try {
|
|
474
|
-
await renderRoadmapFromDb(artifactBasePath, params.milestoneId);
|
|
475
|
-
}
|
|
476
|
-
catch (projErr) {
|
|
477
|
-
logWarning("tool", `complete-slice milestone roadmap projection warning for ${params.milestoneId}/${params.sliceId}: ${projErr.message}`);
|
|
478
|
-
}
|
|
479
|
-
try {
|
|
480
|
-
renderTopLevelRoadmapFromDb(artifactBasePath);
|
|
481
|
-
}
|
|
482
|
-
catch (projErr) {
|
|
483
|
-
logWarning("tool", `complete-slice roadmap projection warning for ${params.milestoneId}/${params.sliceId}: ${projErr.message}`);
|
|
484
|
-
}
|
|
485
|
-
try {
|
|
486
|
-
renderTopLevelQueueFromDb(artifactBasePath);
|
|
487
|
-
}
|
|
488
|
-
catch (projErr) {
|
|
489
|
-
logWarning("tool", `complete-slice queue projection warning for ${params.milestoneId}/${params.sliceId}: ${projErr.message}`);
|
|
490
|
-
}
|
|
491
460
|
try {
|
|
492
|
-
await
|
|
461
|
+
await renderMilestoneShellProjections(artifactBasePath, params.milestoneId);
|
|
493
462
|
}
|
|
494
463
|
catch (projErr) {
|
|
495
|
-
logWarning("tool", `complete-slice
|
|
464
|
+
logWarning("tool", `complete-slice projection warning for ${params.milestoneId}/${params.sliceId}: ${projErr.message}`);
|
|
496
465
|
}
|
|
497
466
|
try {
|
|
498
467
|
writeManifest(artifactBasePath);
|
|
@@ -12,16 +12,16 @@
|
|
|
12
12
|
import { existsSync, unlinkSync } from "node:fs";
|
|
13
13
|
import { join } from "node:path";
|
|
14
14
|
import { isClosedStatus } from "../status-guards.js";
|
|
15
|
-
import { transaction, insertMilestone, insertSlice, insertTask, insertVerificationEvidence, getMilestone, getSlice, getTask, updateTaskStatus, deleteVerificationEvidence, saveGateResult, getPendingGatesForTurn,
|
|
16
|
-
import { getWorkflowDatabasePath,
|
|
15
|
+
import { transaction, insertMilestone, insertSlice, insertTask, insertVerificationEvidence, getMilestone, getSlice, getTask, updateTaskStatus, deleteVerificationEvidence, saveGateResult, getPendingGatesForTurn, } from "../gsd-db.js";
|
|
16
|
+
import { getWorkflowDatabasePath, ensureWorkflowDbAtPath } from "../db-workspace.js";
|
|
17
17
|
import { getGatesForTurn } from "../gate-registry.js";
|
|
18
18
|
import { gsdProjectionRoot, clearPathCache, resolveMilestonePath, resolveSlicePath } from "../paths.js";
|
|
19
19
|
import { resolveCanonicalMilestoneRoot } from "../worktree-manager.js";
|
|
20
20
|
import { checkOwnership, taskUnitKey } from "../unit-ownership.js";
|
|
21
21
|
import { saveFile, clearParseCache } from "../files.js";
|
|
22
22
|
import { invalidateStateCache } from "../state.js";
|
|
23
|
-
import { renderPlanCheckboxes
|
|
24
|
-
import {
|
|
23
|
+
import { renderPlanCheckboxes } from "../markdown-renderer.js";
|
|
24
|
+
import { renderMilestoneShellProjections, renderSummaryContent, } from "../workflow-projections.js";
|
|
25
25
|
import { writeManifest } from "../workflow-manifest.js";
|
|
26
26
|
import { appendEvent } from "../workflow-events.js";
|
|
27
27
|
import { logWarning, logError } from "../workflow-logger.js";
|
|
@@ -45,39 +45,6 @@ function taskSummaryPath(basePath, milestoneId, sliceId, taskId) {
|
|
|
45
45
|
// Fallback: legacy hardcoded path (milestone/slice dir not on disk yet)
|
|
46
46
|
return join(gsdProjectionRoot(basePath), "milestones", milestoneId, "slices", sliceId, "tasks", `${taskId}-SUMMARY.md`);
|
|
47
47
|
}
|
|
48
|
-
async function renderCompleteTaskProjections(basePath, milestoneId) {
|
|
49
|
-
try {
|
|
50
|
-
await renderRoadmapFromDb(basePath, milestoneId);
|
|
51
|
-
}
|
|
52
|
-
catch (err) {
|
|
53
|
-
logWarning("projection", `renderRoadmapFromDb failed for ${milestoneId}: ${err.message}`);
|
|
54
|
-
}
|
|
55
|
-
try {
|
|
56
|
-
renderTopLevelRoadmapFromDb(basePath);
|
|
57
|
-
}
|
|
58
|
-
catch (err) {
|
|
59
|
-
logWarning("projection", `renderTopLevelRoadmapFromDb failed: ${err.message}`);
|
|
60
|
-
}
|
|
61
|
-
try {
|
|
62
|
-
renderTopLevelQueueFromDb(basePath);
|
|
63
|
-
}
|
|
64
|
-
catch (err) {
|
|
65
|
-
logWarning("projection", `renderTopLevelQueueFromDb failed: ${err.message}`);
|
|
66
|
-
}
|
|
67
|
-
try {
|
|
68
|
-
await renderStateProjection(basePath);
|
|
69
|
-
}
|
|
70
|
-
catch (err) {
|
|
71
|
-
logWarning("projection", `renderStateProjection failed: ${err.message}`);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
function ensureCompleteTaskDbOpen(dbPath) {
|
|
75
|
-
if (!dbPath || dbPath === ":memory:")
|
|
76
|
-
return isDbAvailable();
|
|
77
|
-
if (isDbAvailable() && getWorkflowDatabasePath() === dbPath)
|
|
78
|
-
return true;
|
|
79
|
-
return openWorkflowDatabasePath(dbPath);
|
|
80
|
-
}
|
|
81
48
|
async function repairMissingTaskSummaryProjection(artifactBasePath, taskRow) {
|
|
82
49
|
const summaryPath = taskSummaryPath(artifactBasePath, taskRow.milestone_id, taskRow.slice_id, taskRow.id);
|
|
83
50
|
const summaryMd = renderSummaryContent(taskRow, taskRow.slice_id, taskRow.milestone_id, []);
|
|
@@ -94,7 +61,7 @@ async function repairMissingTaskSummaryProjection(artifactBasePath, taskRow) {
|
|
|
94
61
|
clearPathCache();
|
|
95
62
|
clearParseCache();
|
|
96
63
|
try {
|
|
97
|
-
await
|
|
64
|
+
await renderMilestoneShellProjections(artifactBasePath, taskRow.milestone_id);
|
|
98
65
|
}
|
|
99
66
|
catch (projErr) {
|
|
100
67
|
logWarning("tool", `complete-task repair projection warning: ${projErr.message}`);
|
|
@@ -358,7 +325,7 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
358
325
|
await saveFile(summaryPath, summaryMd);
|
|
359
326
|
// Toggle or regenerate the plan projection from DB. Missing projection
|
|
360
327
|
// files are rebuilt by the renderer instead of being skipped.
|
|
361
|
-
if (!
|
|
328
|
+
if (!ensureWorkflowDbAtPath(rollbackDbPath)) {
|
|
362
329
|
throw new Error(`database unavailable before plan projection render for ${params.milestoneId}/${params.sliceId}`);
|
|
363
330
|
}
|
|
364
331
|
const wrotePlan = await renderPlanCheckboxes(artifactBasePath, params.milestoneId, params.sliceId);
|
|
@@ -370,7 +337,7 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
370
337
|
logWarning("projection", `complete_task projection write failed for ${params.milestoneId}/${params.sliceId}/${params.taskId}`, { error: renderErr.message });
|
|
371
338
|
let rollbackSucceeded = false;
|
|
372
339
|
try {
|
|
373
|
-
|
|
340
|
+
ensureWorkflowDbAtPath(rollbackDbPath);
|
|
374
341
|
deleteVerificationEvidence(params.milestoneId, params.sliceId, params.taskId);
|
|
375
342
|
updateTaskStatus(params.milestoneId, params.sliceId, params.taskId, "pending");
|
|
376
343
|
invalidateStateCache();
|
|
@@ -498,7 +465,7 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
498
465
|
// Separate try/catch per step so a projection failure doesn't prevent
|
|
499
466
|
// the event log entry (critical for worktree reconciliation).
|
|
500
467
|
try {
|
|
501
|
-
await
|
|
468
|
+
await renderMilestoneShellProjections(artifactBasePath, params.milestoneId);
|
|
502
469
|
}
|
|
503
470
|
catch (projErr) {
|
|
504
471
|
logWarning("tool", `complete-task projection warning: ${projErr.message}`);
|
|
@@ -28,9 +28,13 @@ function validateRepositoryTargetIds(field, value) {
|
|
|
28
28
|
return deduped;
|
|
29
29
|
}
|
|
30
30
|
function validateTasks(value) {
|
|
31
|
-
if (
|
|
32
|
-
|
|
31
|
+
if (value === undefined)
|
|
32
|
+
return undefined;
|
|
33
|
+
if (!Array.isArray(value)) {
|
|
34
|
+
throw new Error("tasks must be an array");
|
|
33
35
|
}
|
|
36
|
+
if (value.length === 0)
|
|
37
|
+
return undefined;
|
|
34
38
|
const seen = new Set();
|
|
35
39
|
return value.map((entry, index) => {
|
|
36
40
|
if (!entry || typeof entry !== "object") {
|
|
@@ -129,7 +133,7 @@ function validateReferencedRepositories(params, registry, defaultTargets) {
|
|
|
129
133
|
};
|
|
130
134
|
for (const id of params.targetRepositories ?? defaultTargets)
|
|
131
135
|
noteMissing(id);
|
|
132
|
-
for (const task of params.tasks) {
|
|
136
|
+
for (const task of params.tasks ?? []) {
|
|
133
137
|
for (const id of task.targetRepositories ?? params.targetRepositories ?? defaultTargets)
|
|
134
138
|
noteMissing(id);
|
|
135
139
|
}
|
|
@@ -141,7 +145,7 @@ function resolveAllowedRootsForPathScope(params, registry, defaultTargets) {
|
|
|
141
145
|
const requested = new Set();
|
|
142
146
|
for (const id of params.targetRepositories ?? defaultTargets)
|
|
143
147
|
requested.add(id);
|
|
144
|
-
for (const task of params.tasks) {
|
|
148
|
+
for (const task of params.tasks ?? []) {
|
|
145
149
|
for (const id of task.targetRepositories ?? params.targetRepositories ?? defaultTargets)
|
|
146
150
|
requested.add(id);
|
|
147
151
|
}
|
|
@@ -153,7 +157,7 @@ function resolveAllowedRootsForPathScope(params, registry, defaultTargets) {
|
|
|
153
157
|
return roots.length > 0 ? roots : [registry.projectRoot];
|
|
154
158
|
}
|
|
155
159
|
function toTaskRows(params, defaultTargets) {
|
|
156
|
-
return params.tasks.map((task, index) => ({
|
|
160
|
+
return (params.tasks ?? []).map((task, index) => ({
|
|
157
161
|
milestone_id: params.milestoneId,
|
|
158
162
|
slice_id: params.sliceId,
|
|
159
163
|
id: task.taskId,
|
|
@@ -230,19 +234,21 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
230
234
|
return { error: `validation failed: ${message}` };
|
|
231
235
|
}
|
|
232
236
|
const defaultTargets = defaultRepositoryTargets(repositoryRegistry);
|
|
237
|
+
const taskPayload = params.tasks ?? [];
|
|
238
|
+
const hasTaskPayload = taskPayload.length > 0;
|
|
233
239
|
const repoValidationError = validateReferencedRepositories(params, repositoryRegistry, defaultTargets);
|
|
234
240
|
if (repoValidationError) {
|
|
235
241
|
return { error: `validation failed: ${repoValidationError}` };
|
|
236
242
|
}
|
|
237
243
|
const allowedAbsoluteRoots = resolveAllowedRootsForPathScope(params, repositoryRegistry, defaultTargets);
|
|
238
|
-
const pathOnlyError = validatePathOnlyPlanningFields(
|
|
244
|
+
const pathOnlyError = validatePathOnlyPlanningFields(taskPayload.map((task, index) => ({
|
|
239
245
|
field: `tasks[${index}].expectedOutput`,
|
|
240
246
|
values: task.expectedOutput,
|
|
241
247
|
})));
|
|
242
248
|
if (pathOnlyError) {
|
|
243
249
|
return { error: `validation failed: ${pathOnlyError}` };
|
|
244
250
|
}
|
|
245
|
-
const pathScopeError = validatePlanningPathScope(basePath,
|
|
251
|
+
const pathScopeError = validatePlanningPathScope(basePath, taskPayload.flatMap((task, index) => [
|
|
246
252
|
{ field: `tasks[${index}].files`, values: task.files },
|
|
247
253
|
{ field: `tasks[${index}].inputs`, values: task.inputs },
|
|
248
254
|
{ field: `tasks[${index}].expectedOutput`, values: task.expectedOutput },
|
|
@@ -279,15 +285,17 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
279
285
|
guardError = `cannot re-plan slice ${params.sliceId}: it is already complete — use gsd_slice_reopen first`;
|
|
280
286
|
return;
|
|
281
287
|
}
|
|
282
|
-
const newTaskIds = new Set(
|
|
288
|
+
const newTaskIds = new Set(taskPayload.map((task) => task.taskId));
|
|
283
289
|
const existingTasks = getSliceTasks(params.milestoneId, params.sliceId);
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
290
|
+
if (hasTaskPayload) {
|
|
291
|
+
omittedTaskIds = existingTasks
|
|
292
|
+
.filter((task) => !newTaskIds.has(task.id))
|
|
293
|
+
.map((task) => task.id);
|
|
294
|
+
for (const task of existingTasks) {
|
|
295
|
+
if (!newTaskIds.has(task.id) && isClosedStatus(task.status)) {
|
|
296
|
+
guardError = `cannot remove completed task ${task.id}`;
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
291
299
|
}
|
|
292
300
|
}
|
|
293
301
|
if (isDeferredStatus(parentSlice.status)) {
|
|
@@ -301,34 +309,36 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
301
309
|
observabilityImpact: params.observabilityImpact,
|
|
302
310
|
targetRepositories: params.targetRepositories ?? defaultTargets,
|
|
303
311
|
});
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
const
|
|
310
|
-
|
|
311
|
-
description: task.description,
|
|
312
|
-
estimate: task.estimate,
|
|
313
|
-
files: task.files,
|
|
314
|
-
verify: task.verify,
|
|
315
|
-
inputs: task.inputs,
|
|
316
|
-
expectedOutput: task.expectedOutput,
|
|
317
|
-
observabilityImpact: task.observabilityImpact ?? "",
|
|
318
|
-
fullPlanMd: task.fullPlanMd,
|
|
319
|
-
targetRepositories: task.targetRepositories ?? params.targetRepositories ?? defaultTargets,
|
|
320
|
-
};
|
|
321
|
-
const existingTask = existingTaskById.get(task.taskId);
|
|
322
|
-
if (!existingTask || !isClosedStatus(existingTask.status)) {
|
|
323
|
-
insertTask({
|
|
324
|
-
id: task.taskId,
|
|
325
|
-
sliceId: params.sliceId,
|
|
326
|
-
milestoneId: params.milestoneId,
|
|
312
|
+
if (hasTaskPayload) {
|
|
313
|
+
for (const taskId of omittedTaskIds) {
|
|
314
|
+
deleteTask(params.milestoneId, params.sliceId, taskId);
|
|
315
|
+
}
|
|
316
|
+
const existingTaskById = new Map(existingTasks.map((task) => [task.id, task]));
|
|
317
|
+
for (const task of taskPayload) {
|
|
318
|
+
const planning = {
|
|
327
319
|
title: task.title,
|
|
328
|
-
|
|
329
|
-
|
|
320
|
+
description: task.description,
|
|
321
|
+
estimate: task.estimate,
|
|
322
|
+
files: task.files,
|
|
323
|
+
verify: task.verify,
|
|
324
|
+
inputs: task.inputs,
|
|
325
|
+
expectedOutput: task.expectedOutput,
|
|
326
|
+
observabilityImpact: task.observabilityImpact ?? "",
|
|
327
|
+
fullPlanMd: task.fullPlanMd,
|
|
328
|
+
targetRepositories: task.targetRepositories ?? params.targetRepositories ?? defaultTargets,
|
|
329
|
+
};
|
|
330
|
+
const existingTask = existingTaskById.get(task.taskId);
|
|
331
|
+
if (!existingTask || !isClosedStatus(existingTask.status)) {
|
|
332
|
+
insertTask({
|
|
333
|
+
id: task.taskId,
|
|
334
|
+
sliceId: params.sliceId,
|
|
335
|
+
milestoneId: params.milestoneId,
|
|
336
|
+
title: task.title,
|
|
337
|
+
status: "pending",
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
upsertTaskPlanning(params.milestoneId, params.sliceId, task.taskId, planning);
|
|
330
341
|
}
|
|
331
|
-
upsertTaskPlanning(params.milestoneId, params.sliceId, task.taskId, planning);
|
|
332
342
|
}
|
|
333
343
|
// Seed quality gate rows inside the transaction — all-or-nothing with
|
|
334
344
|
// the plan data so a crash can't leave orphaned gates without tasks.
|
|
@@ -337,7 +347,7 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
337
347
|
insertGateRow({ milestoneId: params.milestoneId, sliceId: params.sliceId, gateId: gid, scope: "slice" });
|
|
338
348
|
}
|
|
339
349
|
const taskGates = resolveTaskGates(gateEvaluation);
|
|
340
|
-
for (const task of
|
|
350
|
+
for (const task of taskPayload) {
|
|
341
351
|
for (const gid of taskGates) {
|
|
342
352
|
insertGateRow({ milestoneId: params.milestoneId, sliceId: params.sliceId, gateId: gid, scope: "task", taskId: task.taskId });
|
|
343
353
|
}
|
|
@@ -360,8 +370,13 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
360
370
|
const artifactPath = relative(gsdProjectionRoot(basePath), taskPlanPath).replace(/\\/g, "/");
|
|
361
371
|
deleteArtifactByPath(artifactPath);
|
|
362
372
|
}
|
|
363
|
-
const
|
|
364
|
-
|
|
373
|
+
const sliceTasks = getSliceTasks(params.milestoneId, params.sliceId);
|
|
374
|
+
const renderResult = sliceTasks.length === 0
|
|
375
|
+
? { planPath: "", taskPlanPaths: [] }
|
|
376
|
+
: await renderPlanFromDb(basePath, params.milestoneId, params.sliceId);
|
|
377
|
+
if (sliceTasks.length > 0) {
|
|
378
|
+
setSliceSketchFlag(params.milestoneId, params.sliceId, false);
|
|
379
|
+
}
|
|
365
380
|
invalidateStateCache();
|
|
366
381
|
clearParseCache();
|
|
367
382
|
// ── Post-mutation hook: manifest, event log ─────────────────────────
|
|
@@ -1,15 +1,58 @@
|
|
|
1
1
|
import { clearParseCache } from "../files.js";
|
|
2
2
|
import { isClosedStatus } from "../status-guards.js";
|
|
3
3
|
import { isNonEmptyString, validateStringArray } from "../validation.js";
|
|
4
|
-
import {
|
|
4
|
+
import { getGateIdsForTurn } from "../gate-registry.js";
|
|
5
|
+
import { transaction, getSlice, getTask, insertTask, upsertTaskPlanning, insertGateRow, setSliceSketchFlag } from "../gsd-db.js";
|
|
5
6
|
import { invalidateStateCache } from "../state.js";
|
|
6
7
|
import { renderTaskPlanFromDb, renderPlanFromDb } from "../markdown-renderer.js";
|
|
7
|
-
import {
|
|
8
|
+
import { resolveTasksDir } from "../paths.js";
|
|
8
9
|
import { flushWorkflowProjections } from "../projection-flush.js";
|
|
9
10
|
import { writeManifest } from "../workflow-manifest.js";
|
|
10
11
|
import { appendEvent } from "../workflow-events.js";
|
|
11
12
|
import { logWarning } from "../workflow-logger.js";
|
|
13
|
+
import { loadEffectiveGSDPreferences } from "../preferences.js";
|
|
12
14
|
import { validatePathOnlyPlanningFields, validatePlanningPathScope } from "../planning-path-scope.js";
|
|
15
|
+
import { createRepositoryRegistryFromPreferences, defaultRepositoryTargets } from "../repository-registry.js";
|
|
16
|
+
function validateRepositoryTargetIds(field, value) {
|
|
17
|
+
const ids = validateStringArray(value, field);
|
|
18
|
+
if (ids.length === 0)
|
|
19
|
+
throw new Error(`${field} must include at least one repository id when provided`);
|
|
20
|
+
const deduped = Array.from(new Set(ids.map((id) => id.trim()).filter(Boolean)));
|
|
21
|
+
if (deduped.length === 0)
|
|
22
|
+
throw new Error(`${field} must include at least one repository id when provided`);
|
|
23
|
+
return deduped;
|
|
24
|
+
}
|
|
25
|
+
function validateReferencedRepositories(targetRepositories, registry) {
|
|
26
|
+
if (!targetRepositories)
|
|
27
|
+
return null;
|
|
28
|
+
const known = new Set(registry.repositories.map((repo) => repo.id));
|
|
29
|
+
const missing = targetRepositories.filter((id) => !known.has(id));
|
|
30
|
+
if (missing.length === 0)
|
|
31
|
+
return null;
|
|
32
|
+
return `unknown targetRepositories: ${missing.join(", ")}. Declared repositories: ${Array.from(known).join(", ")}`;
|
|
33
|
+
}
|
|
34
|
+
function resolveAllowedRootsForPathScope(targetRepositories, registry) {
|
|
35
|
+
if (targetRepositories.length === 0)
|
|
36
|
+
return [registry.projectRoot];
|
|
37
|
+
const roots = targetRepositories
|
|
38
|
+
.map((id) => registry.byId.get(id)?.root)
|
|
39
|
+
.filter((root) => typeof root === "string");
|
|
40
|
+
return roots.length > 0 ? roots : [registry.projectRoot];
|
|
41
|
+
}
|
|
42
|
+
function validatePathScopeForTargetRepositories(params, basePath, registry, targetRepositories) {
|
|
43
|
+
return validatePlanningPathScope(basePath, [
|
|
44
|
+
{ field: "files", values: params.files },
|
|
45
|
+
{ field: "inputs", values: params.inputs },
|
|
46
|
+
{ field: "expectedOutput", values: params.expectedOutput },
|
|
47
|
+
], resolveAllowedRootsForPathScope(targetRepositories, registry));
|
|
48
|
+
}
|
|
49
|
+
function resolveEffectiveTargetRepositories(taskTargetRepositories, sliceTargetRepositories, defaultTargets) {
|
|
50
|
+
if (taskTargetRepositories)
|
|
51
|
+
return taskTargetRepositories;
|
|
52
|
+
if (sliceTargetRepositories?.length)
|
|
53
|
+
return sliceTargetRepositories;
|
|
54
|
+
return defaultTargets;
|
|
55
|
+
}
|
|
13
56
|
function validateParams(params) {
|
|
14
57
|
if (!isNonEmptyString(params?.milestoneId))
|
|
15
58
|
throw new Error("milestoneId is required");
|
|
@@ -33,8 +76,17 @@ function validateParams(params) {
|
|
|
33
76
|
files: validateStringArray(params.files, "files"),
|
|
34
77
|
inputs: validateStringArray(params.inputs, "inputs"),
|
|
35
78
|
expectedOutput: validateStringArray(params.expectedOutput, "expectedOutput"),
|
|
79
|
+
...(params.targetRepositories !== undefined
|
|
80
|
+
? { targetRepositories: validateRepositoryTargetIds("targetRepositories", params.targetRepositories) }
|
|
81
|
+
: {}),
|
|
36
82
|
};
|
|
37
83
|
}
|
|
84
|
+
function resolveTaskGates(basePath) {
|
|
85
|
+
const loaded = loadEffectiveGSDPreferences(basePath);
|
|
86
|
+
if (loaded?.preferences?.gate_evaluation?.task_gates === false)
|
|
87
|
+
return [];
|
|
88
|
+
return [...getGateIdsForTurn("execute-task")];
|
|
89
|
+
}
|
|
38
90
|
export async function handlePlanTask(rawParams, basePath) {
|
|
39
91
|
let params;
|
|
40
92
|
try {
|
|
@@ -49,14 +101,18 @@ export async function handlePlanTask(rawParams, basePath) {
|
|
|
49
101
|
if (pathOnlyError) {
|
|
50
102
|
return { error: `validation failed: ${pathOnlyError}` };
|
|
51
103
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
104
|
+
let taskGates;
|
|
105
|
+
let repositoryRegistry;
|
|
106
|
+
try {
|
|
107
|
+
taskGates = resolveTaskGates(basePath);
|
|
108
|
+
const loaded = loadEffectiveGSDPreferences(basePath);
|
|
109
|
+
repositoryRegistry = createRepositoryRegistryFromPreferences(basePath, loaded?.preferences);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
113
|
+
return { error: `validation failed: ${message}` };
|
|
59
114
|
}
|
|
115
|
+
const defaultTargets = defaultRepositoryTargets(repositoryRegistry);
|
|
60
116
|
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
61
117
|
// Guards must be inside the transaction so the state they check cannot
|
|
62
118
|
// change between the read and the write (#2723).
|
|
@@ -77,6 +133,33 @@ export async function handlePlanTask(rawParams, basePath) {
|
|
|
77
133
|
guardError = `cannot re-plan task ${params.taskId}: it is already complete — use gsd_task_reopen first`;
|
|
78
134
|
return;
|
|
79
135
|
}
|
|
136
|
+
let effectiveTargetRepositories = resolveEffectiveTargetRepositories(params.targetRepositories, parentSlice.target_repositories, defaultTargets);
|
|
137
|
+
const repoValidationError = validateReferencedRepositories(effectiveTargetRepositories, repositoryRegistry);
|
|
138
|
+
if (repoValidationError) {
|
|
139
|
+
guardError = `validation failed: ${repoValidationError}`;
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
let pathScopeError = validatePathScopeForTargetRepositories(params, basePath, repositoryRegistry, effectiveTargetRepositories);
|
|
143
|
+
const storedTaskTargets = existingTask?.target_repositories?.length
|
|
144
|
+
? existingTask.target_repositories
|
|
145
|
+
: undefined;
|
|
146
|
+
// Omitted targetRepositories inherit the current slice default first.
|
|
147
|
+
// Fall back to the stored task target only when that inherited scope
|
|
148
|
+
// rejects the replan paths, preserving explicit per-task parent-root work.
|
|
149
|
+
if (pathScopeError && params.targetRepositories === undefined && storedTaskTargets) {
|
|
150
|
+
const storedRepoValidationError = validateReferencedRepositories(storedTaskTargets, repositoryRegistry);
|
|
151
|
+
const storedPathScopeError = storedRepoValidationError
|
|
152
|
+
? storedRepoValidationError
|
|
153
|
+
: validatePathScopeForTargetRepositories(params, basePath, repositoryRegistry, storedTaskTargets);
|
|
154
|
+
if (!storedPathScopeError) {
|
|
155
|
+
effectiveTargetRepositories = storedTaskTargets;
|
|
156
|
+
pathScopeError = null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (pathScopeError) {
|
|
160
|
+
guardError = `validation failed: ${pathScopeError}`;
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
80
163
|
if (!existingTask) {
|
|
81
164
|
insertTask({
|
|
82
165
|
id: params.taskId,
|
|
@@ -96,7 +179,11 @@ export async function handlePlanTask(rawParams, basePath) {
|
|
|
96
179
|
expectedOutput: params.expectedOutput,
|
|
97
180
|
observabilityImpact: params.observabilityImpact ?? "",
|
|
98
181
|
fullPlanMd: params.fullPlanMd,
|
|
182
|
+
targetRepositories: effectiveTargetRepositories,
|
|
99
183
|
});
|
|
184
|
+
for (const gid of taskGates) {
|
|
185
|
+
insertGateRow({ milestoneId: params.milestoneId, sliceId: params.sliceId, gateId: gid, scope: "task", taskId: params.taskId });
|
|
186
|
+
}
|
|
100
187
|
});
|
|
101
188
|
}
|
|
102
189
|
catch (err) {
|
|
@@ -110,17 +197,21 @@ export async function handlePlanTask(rawParams, basePath) {
|
|
|
110
197
|
// Flat-phase: tasks live as checkboxes in the slice plan's <tasks> block,
|
|
111
198
|
// not as standalone TID-PLAN.md files. Re-render the slice plan so the
|
|
112
199
|
// new/updated task appears in the plan file that gsd-core reads.
|
|
113
|
-
// Guard: resolveTasksDir is null in flat-phase (no tasks/ subdir exists)
|
|
114
|
-
|
|
200
|
+
// Guard: resolveTasksDir is null in flat-phase (no tasks/ subdir exists).
|
|
201
|
+
let slicePlanSynced = false;
|
|
115
202
|
try {
|
|
116
203
|
const tDir = resolveTasksDir(basePath, params.milestoneId, params.sliceId);
|
|
117
|
-
if (!tDir
|
|
204
|
+
if (!tDir) {
|
|
118
205
|
await renderPlanFromDb(basePath, params.milestoneId, params.sliceId);
|
|
206
|
+
slicePlanSynced = true;
|
|
119
207
|
}
|
|
120
208
|
}
|
|
121
209
|
catch (syncErr) {
|
|
122
210
|
logWarning("tool", `plan-task: slice-plan sync failed: ${syncErr.message}`);
|
|
123
211
|
}
|
|
212
|
+
if (slicePlanSynced) {
|
|
213
|
+
setSliceSketchFlag(params.milestoneId, params.sliceId, false);
|
|
214
|
+
}
|
|
124
215
|
invalidateStateCache();
|
|
125
216
|
clearParseCache();
|
|
126
217
|
// ── Post-mutation hook: projections, manifest, event log ─────────────
|
|
@@ -29,7 +29,9 @@ import { loadEffectiveGSDPreferences } from "../preferences.js";
|
|
|
29
29
|
import { parseProject } from "../schemas/parsers.js";
|
|
30
30
|
import { autoSession, getAutoRuntimeSnapshot, isAutoActive } from "../auto-runtime-state.js";
|
|
31
31
|
import { renderPlanFromDb } from "../markdown-renderer.js";
|
|
32
|
+
import { readUnitHarnessAbort } from "../unit-runtime.js";
|
|
32
33
|
import { prepareUatRun, saveUatAttemptArtifact, } from "../uat-run.js";
|
|
34
|
+
import { appendNotification } from "../notification-store.js";
|
|
33
35
|
import { registerAutoWorker, markWorkerStopping, getAutoWorker } from "../db/auto-workers.js";
|
|
34
36
|
import { claimMilestoneLease, releaseMilestoneLease, getMilestoneLease, refreshMilestoneLease, milestoneLeaseTtlSeconds, } from "../db/milestone-leases.js";
|
|
35
37
|
export const SUPPORTED_SUMMARY_ARTIFACT_TYPES = [
|
|
@@ -65,6 +67,35 @@ function blockIfWrongAutoUnit(requiredUnitType, operation) {
|
|
|
65
67
|
isError: true,
|
|
66
68
|
};
|
|
67
69
|
}
|
|
70
|
+
function blockIfHarnessAbortedUnit(operation, basePath) {
|
|
71
|
+
const snapshot = getAutoRuntimeSnapshot();
|
|
72
|
+
if (!snapshot.active || !snapshot.currentUnit)
|
|
73
|
+
return null;
|
|
74
|
+
const abort = readUnitHarnessAbort(snapshot.basePath || basePath, snapshot.currentUnit.type, snapshot.currentUnit.id, snapshot.currentUnit.startedAt);
|
|
75
|
+
if (!abort)
|
|
76
|
+
return null;
|
|
77
|
+
return harnessAbortResult(operation, snapshot.currentUnit.type, snapshot.currentUnit.id, abort);
|
|
78
|
+
}
|
|
79
|
+
function harnessAbortResult(operation, unitType, unitId, abort) {
|
|
80
|
+
const toolText = abort.toolName ? ` while calling ${abort.toolName}` : "";
|
|
81
|
+
const message = `Retryable harness abort: ${unitType} ${unitId} was truncated by ${abort.kind}${toolText}. ` +
|
|
82
|
+
"This gate result was not saved; leave the gate pending so auto-mode can rerun it.";
|
|
83
|
+
return {
|
|
84
|
+
content: [{ type: "text", text: message }],
|
|
85
|
+
details: {
|
|
86
|
+
operation,
|
|
87
|
+
error: "harness_aborted_needs_retry",
|
|
88
|
+
retryable: true,
|
|
89
|
+
unitType,
|
|
90
|
+
unitId,
|
|
91
|
+
harnessAbortKind: abort.kind,
|
|
92
|
+
harnessAbortReason: abort.reason,
|
|
93
|
+
harnessAbortToolName: abort.toolName,
|
|
94
|
+
harnessAbortCount: abort.count,
|
|
95
|
+
},
|
|
96
|
+
isError: true,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
68
99
|
function milestoneLeaseConflictResult(milestoneId, byWorker, expiresAt) {
|
|
69
100
|
return {
|
|
70
101
|
content: [{ type: "text", text: `Milestone ${milestoneId} is currently leased by ${byWorker}. Retry after ${expiresAt}.` }],
|
|
@@ -959,6 +990,9 @@ export async function executeReassessRoadmap(params, basePath = process.cwd()) {
|
|
|
959
990
|
}
|
|
960
991
|
}
|
|
961
992
|
export async function executeSaveGateResult(params, basePath = process.cwd()) {
|
|
993
|
+
const harnessAbort = blockIfHarnessAbortedUnit("save_gate_result", basePath);
|
|
994
|
+
if (harnessAbort)
|
|
995
|
+
return harnessAbort;
|
|
962
996
|
const dbAvailable = await ensureDbOpen(basePath);
|
|
963
997
|
if (!dbAvailable) {
|
|
964
998
|
return {
|
|
@@ -1023,6 +1057,9 @@ export async function executeUatResultSave(params, basePath = process.cwd()) {
|
|
|
1023
1057
|
const unitGuard = blockIfWrongAutoUnit("run-uat", "save_uat_result");
|
|
1024
1058
|
if (unitGuard)
|
|
1025
1059
|
return unitGuard;
|
|
1060
|
+
const harnessAbort = blockIfHarnessAbortedUnit("save_uat_result", basePath);
|
|
1061
|
+
if (harnessAbort)
|
|
1062
|
+
return harnessAbort;
|
|
1026
1063
|
const dbAvailable = await ensureDbOpen(basePath);
|
|
1027
1064
|
if (!dbAvailable)
|
|
1028
1065
|
return errorResult("save_uat_result", "GSD database is not available.", "db_unavailable");
|
|
@@ -1082,6 +1119,9 @@ export async function executeUatResultSave(params, basePath = process.cwd()) {
|
|
|
1082
1119
|
evaluatedAt: run.evaluatedAt,
|
|
1083
1120
|
});
|
|
1084
1121
|
invalidateStateCache();
|
|
1122
|
+
if (run.hasHuman) {
|
|
1123
|
+
appendNotification(`UAT for ${run.params.milestoneId}/${run.params.sliceId} has NEEDS-HUMAN checks awaiting human validation`, "warning", "notify", { kind: "uat-needs-human", scope: `${run.params.milestoneId}/${run.params.sliceId}` });
|
|
1124
|
+
}
|
|
1085
1125
|
const savedText = `UAT result saved for ${run.params.milestoneId}/${run.params.sliceId}: ${run.params.verdict}`;
|
|
1086
1126
|
return {
|
|
1087
1127
|
content: [{
|