@opengsd/gsd-pi 1.4.0 → 1.5.0-dev.4fb2d460
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/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/ask-user-questions.js +1 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +118 -53
- 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 +25 -9
- package/dist/resources/extensions/gsd/auto/closeout.js +137 -42
- package/dist/resources/extensions/gsd/auto/finalize.js +9 -0
- package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -3
- package/dist/resources/extensions/gsd/auto/pre-dispatch.js +6 -3
- package/dist/resources/extensions/gsd/auto/run-unit.js +5 -2
- package/dist/resources/extensions/gsd/auto/schedule-wakeup.js +3 -0
- package/dist/resources/extensions/gsd/auto/unit-phase.js +5 -9
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +12 -3
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -7
- package/dist/resources/extensions/gsd/auto-dispatch.js +31 -7
- package/dist/resources/extensions/gsd/auto-model-selection.js +36 -18
- package/dist/resources/extensions/gsd/auto-prompts.js +76 -2
- package/dist/resources/extensions/gsd/auto-recovery.js +50 -6
- package/dist/resources/extensions/gsd/auto-start.js +8 -6
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +4 -0
- package/dist/resources/extensions/gsd/auto-worktree-branch-lifecycle.js +189 -0
- package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +133 -0
- package/dist/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.js +35 -0
- package/dist/resources/extensions/gsd/auto-worktree-creation.js +130 -0
- package/dist/resources/extensions/gsd/auto-worktree-entry.js +118 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-already-merged.js +98 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-branch-head.js +52 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-cleanup.js +87 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-code-changes.js +46 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-db-ready.js +68 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-integration-branch.js +51 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-message.js +106 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-pre-teardown.js +64 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-stash.js +168 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge.js +302 -0
- package/dist/resources/extensions/gsd/auto-worktree-milestone-shelter.js +119 -0
- package/dist/resources/extensions/gsd/auto-worktree-path-resolution.js +5 -0
- package/dist/resources/extensions/gsd/auto-worktree-path-utils.js +5 -0
- package/dist/resources/extensions/gsd/auto-worktree-resource-version.js +41 -0
- package/dist/resources/extensions/gsd/auto-worktree-runtime-cleanup.js +99 -0
- package/dist/resources/extensions/gsd/auto-worktree-session-registry.js +57 -0
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +249 -0
- package/dist/resources/extensions/gsd/auto-worktree-teardown.js +120 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +20 -2046
- package/dist/resources/extensions/gsd/auto.js +31 -5
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -0
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +134 -7
- package/dist/resources/extensions/gsd/bootstrap/schedule-wakeup-tool.js +58 -9
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +194 -28
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +14 -1
- package/dist/resources/extensions/gsd/codebase-generator.js +164 -20
- package/dist/resources/extensions/gsd/commands/handlers/core.js +40 -4
- package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +153 -1
- package/dist/resources/extensions/gsd/commands-workflow-templates.js +3 -3
- package/dist/resources/extensions/gsd/commands-worktree.js +11 -2
- package/dist/resources/extensions/gsd/db/queries.js +48 -9
- package/dist/resources/extensions/gsd/db/writers/cascades.js +20 -2
- package/dist/resources/extensions/gsd/discussion-handoff.js +8 -3
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -2
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +292 -18
- package/dist/resources/extensions/gsd/doctor-providers.js +38 -10
- package/dist/resources/extensions/gsd/doctor.js +93 -3
- package/dist/resources/extensions/gsd/exec-sandbox.js +6 -2
- package/dist/resources/extensions/gsd/flat-phase-migration.js +106 -26
- package/dist/resources/extensions/gsd/forensics.js +1 -1
- package/dist/resources/extensions/gsd/git-conflict-resolve.js +2 -2
- package/dist/resources/extensions/gsd/git-service.js +59 -18
- package/dist/resources/extensions/gsd/gsd-db.js +75 -11
- package/dist/resources/extensions/gsd/guidance.js +1 -0
- package/dist/resources/extensions/gsd/guided-flow.js +62 -19
- package/dist/resources/extensions/gsd/key-manager.js +1 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +40 -11
- package/dist/resources/extensions/gsd/md-importer.js +89 -23
- package/dist/resources/extensions/gsd/migrate-external.js +24 -7
- package/dist/resources/extensions/gsd/migration-auto-check.js +30 -3
- package/dist/resources/extensions/gsd/milestone-merge-transaction.js +14 -3
- package/dist/resources/extensions/gsd/milestone-settlement.js +1 -1
- package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -1
- package/dist/resources/extensions/gsd/paths.js +17 -3
- 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-skills.js +10 -16
- package/dist/resources/extensions/gsd/preferences-types.js +1 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +107 -2
- package/dist/resources/extensions/gsd/preferences.js +49 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -2
- package/dist/resources/extensions/gsd/prompts/system.md +6 -6
- package/dist/resources/extensions/gsd/quick.js +12 -3
- package/dist/resources/extensions/gsd/redact-secrets.js +37 -0
- package/dist/resources/extensions/gsd/repo-identity.js +16 -0
- package/dist/resources/extensions/gsd/repository-registry.js +6 -1
- package/dist/resources/extensions/gsd/root-write-leak-guard.js +4 -2
- package/dist/resources/extensions/gsd/safe-fs.js +23 -2
- package/dist/resources/extensions/gsd/skill-discovery.js +36 -23
- package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
- package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +2 -1
- package/dist/resources/extensions/gsd/state/derive/from-db.js +88 -153
- package/dist/resources/extensions/gsd/tool-contract.js +14 -0
- package/dist/resources/extensions/gsd/tools/plan-task.js +76 -8
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +5 -0
- package/dist/resources/extensions/gsd/tools/reopen-task.js +13 -5
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +40 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +5 -4
- package/dist/resources/extensions/gsd/unit-registry.js +37 -2
- package/dist/resources/extensions/gsd/unit-runtime.js +21 -0
- package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +1 -1
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -1
- package/dist/resources/extensions/gsd/workspace-git-preflight.js +2 -2
- package/dist/resources/extensions/gsd/workspace.js +26 -8
- package/dist/resources/extensions/gsd/worktree-command.js +1 -1
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +81 -14
- package/dist/resources/extensions/gsd/worktree-manager.js +97 -4
- package/dist/resources/extensions/gsd/worktree-reentry.js +2 -1
- package/dist/resources/extensions/shared/interview-ui.js +62 -9
- 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 +9 -9
- 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/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- 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.js +2 -2
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- 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 +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
- package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
- 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.js +3 -3
- 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/app/_not-found/page-a6fb1847f67f167c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.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/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/dist/wizard.d.ts +8 -0
- package/dist/wizard.js +8 -1
- package/integrations/hermes/CONTEXT.md +47 -0
- package/integrations/hermes/README.md +21 -0
- package/integrations/hermes/__init__.py +31 -0
- package/integrations/hermes/docs/issue-1162-grilling.md +197 -0
- package/integrations/hermes/docs/setup.md +4 -0
- package/integrations/hermes/open_gsd_hermes/commands.py +141 -0
- package/integrations/hermes/open_gsd_hermes/config.py +2 -0
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +591 -39
- package/integrations/hermes/open_gsd_hermes/notifications.py +10 -1
- package/integrations/hermes/plugin.yaml +4 -0
- package/integrations/hermes/tests/test_config.py +6 -0
- package/integrations/hermes/tests/test_directory_loader.py +37 -0
- package/integrations/hermes/tests/test_gsd_client_cache.py +3 -0
- package/integrations/hermes/tests/test_gsd_client_execute.py +35 -0
- package/integrations/hermes/tests/test_gsd_client_process_cwd.py +22 -0
- package/integrations/hermes/tests/test_gsd_client_timeout.py +98 -0
- package/integrations/hermes/tests/test_milestone_client.py +447 -0
- package/integrations/hermes/tests/test_new_milestone_command.py +313 -0
- package/integrations/hermes/tests/test_supervisor_fsm.py +40 -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/dist/session-manager.js +1 -1
- package/packages/daemon/dist/session-manager.js.map +1 -1
- package/packages/daemon/package.json +5 -5
- 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/export-html/template.js +53 -4
- package/packages/gsd-agent-core/dist/session/agent-session-navigation.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-navigation.js +4 -1
- package/packages/gsd-agent-core/dist/session/agent-session-navigation.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- 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 +3 -2
- 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-segment-walker.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/server.d.ts +18 -5
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +46 -5
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/session-manager.js +1 -1
- package/packages/mcp-server/dist/session-manager.js.map +1 -1
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +14 -9
- 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/index.d.ts +1 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +7 -3
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/dist/tool-result-content.d.ts +3 -0
- package/packages/pi-ai/dist/tool-result-content.d.ts.map +1 -0
- package/packages/pi-ai/dist/tool-result-content.js +62 -0
- package/packages/pi-ai/dist/tool-result-content.js.map +1 -0
- package/packages/pi-ai/dist/types.d.ts +10 -22
- 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/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/package-manager.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.js +74 -53
- package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +30 -2
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +3 -0
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skill-directories.d.ts +66 -0
- package/packages/pi-coding-agent/dist/core/skill-directories.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/skill-directories.js +138 -0
- package/packages/pi-coding-agent/dist/core/skill-directories.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/skills.d.ts +4 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +4 -1
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -0
- package/packages/pi-coding-agent/dist/index.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/core/export-html/template.js +53 -4
- 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/ask-user-questions.ts +1 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +130 -51
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +371 -39
- 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 +25 -9
- package/src/resources/extensions/gsd/auto/closeout.ts +163 -58
- package/src/resources/extensions/gsd/auto/finalize.ts +8 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -3
- package/src/resources/extensions/gsd/auto/pre-dispatch.ts +6 -3
- package/src/resources/extensions/gsd/auto/run-unit.ts +5 -2
- package/src/resources/extensions/gsd/auto/schedule-wakeup.ts +8 -0
- package/src/resources/extensions/gsd/auto/unit-phase.ts +5 -9
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +12 -3
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +13 -7
- package/src/resources/extensions/gsd/auto-dispatch.ts +35 -7
- package/src/resources/extensions/gsd/auto-model-selection.ts +49 -18
- package/src/resources/extensions/gsd/auto-prompts.ts +73 -2
- package/src/resources/extensions/gsd/auto-recovery.ts +50 -6
- package/src/resources/extensions/gsd/auto-start.ts +9 -6
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +4 -0
- package/src/resources/extensions/gsd/auto-worktree-branch-lifecycle.ts +237 -0
- package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +166 -0
- package/src/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.ts +37 -0
- package/src/resources/extensions/gsd/auto-worktree-creation.ts +171 -0
- package/src/resources/extensions/gsd/auto-worktree-entry.ts +154 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-already-merged.ts +161 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-branch-head.ts +83 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-cleanup.ts +132 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-code-changes.ts +71 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-db-ready.ts +112 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-integration-branch.ts +99 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-message.ts +166 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-pre-teardown.ts +93 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-stash.ts +213 -0
- package/src/resources/extensions/gsd/auto-worktree-merge.ts +391 -0
- package/src/resources/extensions/gsd/auto-worktree-milestone-shelter.ts +159 -0
- package/src/resources/extensions/gsd/auto-worktree-path-resolution.ts +6 -0
- package/src/resources/extensions/gsd/auto-worktree-path-utils.ts +10 -0
- package/src/resources/extensions/gsd/auto-worktree-resource-version.ts +44 -0
- package/src/resources/extensions/gsd/auto-worktree-runtime-cleanup.ts +119 -0
- package/src/resources/extensions/gsd/auto-worktree-session-registry.ts +71 -0
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +370 -0
- package/src/resources/extensions/gsd/auto-worktree-teardown.ts +161 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +69 -2390
- package/src/resources/extensions/gsd/auto.ts +32 -19
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -0
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +148 -7
- package/src/resources/extensions/gsd/bootstrap/schedule-wakeup-tool.ts +80 -12
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +229 -28
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +23 -1
- package/src/resources/extensions/gsd/codebase-generator.ts +186 -19
- package/src/resources/extensions/gsd/commands/handlers/core.ts +39 -3
- package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +135 -1
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +3 -3
- package/src/resources/extensions/gsd/commands-worktree.ts +13 -2
- package/src/resources/extensions/gsd/db/queries.ts +49 -9
- package/src/resources/extensions/gsd/db/writers/cascades.ts +23 -1
- package/src/resources/extensions/gsd/discussion-handoff.ts +10 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -2
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +372 -22
- package/src/resources/extensions/gsd/doctor-providers.ts +39 -10
- package/src/resources/extensions/gsd/doctor-types.ts +5 -1
- package/src/resources/extensions/gsd/doctor.ts +95 -3
- package/src/resources/extensions/gsd/exec-sandbox.ts +6 -2
- package/src/resources/extensions/gsd/flat-phase-migration.ts +132 -25
- package/src/resources/extensions/gsd/forensics.ts +1 -1
- package/src/resources/extensions/gsd/git-conflict-resolve.ts +2 -2
- package/src/resources/extensions/gsd/git-service.ts +67 -17
- package/src/resources/extensions/gsd/gsd-db.ts +105 -11
- package/src/resources/extensions/gsd/guidance.ts +2 -0
- package/src/resources/extensions/gsd/guided-flow.ts +71 -20
- package/src/resources/extensions/gsd/key-manager.ts +1 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +40 -10
- package/src/resources/extensions/gsd/md-importer.ts +93 -22
- package/src/resources/extensions/gsd/migrate-external.ts +23 -6
- package/src/resources/extensions/gsd/migration-auto-check.ts +32 -3
- package/src/resources/extensions/gsd/milestone-merge-transaction.ts +19 -4
- package/src/resources/extensions/gsd/milestone-settlement.ts +1 -1
- package/src/resources/extensions/gsd/model-router.ts +4 -5
- package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -1
- package/src/resources/extensions/gsd/paths.ts +21 -3
- 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-skills.ts +10 -16
- package/src/resources/extensions/gsd/preferences-types.ts +30 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +97 -2
- package/src/resources/extensions/gsd/preferences.ts +58 -4
- package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -2
- package/src/resources/extensions/gsd/prompts/system.md +6 -6
- package/src/resources/extensions/gsd/quick.ts +11 -3
- package/src/resources/extensions/gsd/redact-secrets.ts +40 -0
- package/src/resources/extensions/gsd/repo-identity.ts +17 -0
- package/src/resources/extensions/gsd/repository-registry.ts +7 -1
- package/src/resources/extensions/gsd/root-write-leak-guard.ts +3 -2
- package/src/resources/extensions/gsd/safe-fs.ts +22 -2
- package/src/resources/extensions/gsd/skill-discovery.ts +47 -23
- package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
- package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -1
- package/src/resources/extensions/gsd/state/derive/from-db.ts +201 -157
- package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +169 -1
- package/src/resources/extensions/gsd/tests/auto-loop-no-copy-artifacts.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +131 -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-phases-lifecycle.test.ts +43 -1
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +111 -0
- package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +41 -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-start-clean-runtime-db-gated.test.ts +1 -1
- 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 +10 -1
- package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-already-merged.test.ts +177 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-branch-head.test.ts +118 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-cleanup.test.ts +115 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-code-changes.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-db-ready.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-integration-branch.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-message.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-pre-teardown.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-stash.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-shelter.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +6 -6
- package/src/resources/extensions/gsd/tests/auto-worktree-resource-version.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +3 -1
- 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 +387 -0
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +62 -1
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -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 +571 -5
- package/src/resources/extensions/gsd/tests/doctor-workspace.test.ts +207 -0
- package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +109 -2
- package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +25 -1
- 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/gsd-db.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/import-completion-lost-update.test.ts +196 -0
- package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +4 -6
- package/src/resources/extensions/gsd/tests/integration/auto-stash-merge.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/integration/feature-branch-lifecycle-integration.test.ts +2 -5
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/integration/merge-cwd-restore.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/merge-preserve-worktree-on-preteardown-error.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +5 -7
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +2 -4
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -15
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +91 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +592 -23
- package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +25 -1
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/parallel-worker-lock-contention.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +50 -6
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +264 -1
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +1 -4
- package/src/resources/extensions/gsd/tests/preferences.test.ts +169 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +147 -0
- 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 +275 -0
- package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +52 -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 +31 -9
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/schedule-wakeup-tool.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +3 -5
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/status-per-repo.test.ts +94 -0
- package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/system-flat-phase-layout.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +4 -4
- 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 +259 -0
- package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +66 -18
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +81 -0
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +53 -1
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +208 -1
- package/src/resources/extensions/gsd/tests/workspace.test.ts +18 -4
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +1 -3
- package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +36 -3
- package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +32 -0
- package/src/resources/extensions/gsd/tool-contract.ts +29 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +107 -9
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +5 -0
- package/src/resources/extensions/gsd/tools/reopen-task.ts +13 -5
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +58 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +11 -5
- package/src/resources/extensions/gsd/unit-registry.ts +48 -2
- package/src/resources/extensions/gsd/unit-runtime.ts +42 -0
- package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +1 -1
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -1
- package/src/resources/extensions/gsd/workspace-git-preflight.ts +2 -2
- package/src/resources/extensions/gsd/workspace.ts +42 -8
- package/src/resources/extensions/gsd/worktree-command.ts +1 -1
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +154 -26
- package/src/resources/extensions/gsd/worktree-manager.ts +143 -5
- package/src/resources/extensions/gsd/worktree-reentry.ts +2 -1
- package/src/resources/extensions/shared/interview-ui.ts +58 -11
- package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +32 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
- /package/dist/web/standalone/.next/static/{zQLcXm0Za8lexoXtgDpMG → gXoWec4UNqcR0tkuHwYCr}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{zQLcXm0Za8lexoXtgDpMG → gXoWec4UNqcR0tkuHwYCr}/_ssgManifest.js +0 -0
|
@@ -12,6 +12,31 @@ import { countUnmappedActiveRequirements, formatCompletePhaseNextAction } from '
|
|
|
12
12
|
import { logWarning } from '../../workflow-logger.js';
|
|
13
13
|
import { buildDbUnavailableState, ensureExistingWorkflowDbOpen, getRequestedMilestoneLock, } from './db-open.js';
|
|
14
14
|
const isStatusDone = isClosedStatus;
|
|
15
|
+
function buildProgress(context) {
|
|
16
|
+
return {
|
|
17
|
+
milestones: context.milestoneProgress,
|
|
18
|
+
...(context.sliceProgress ? { slices: context.sliceProgress } : {}),
|
|
19
|
+
...(context.taskProgress ? { tasks: context.taskProgress } : {}),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function buildDerivedState(context, phase, nextAction, options = {}) {
|
|
23
|
+
return {
|
|
24
|
+
activeMilestone: context.activeMilestone,
|
|
25
|
+
activeSlice: context.activeSlice ?? null,
|
|
26
|
+
activeTask: context.activeTask ?? null,
|
|
27
|
+
phase,
|
|
28
|
+
recentDecisions: [],
|
|
29
|
+
blockers: options.blockers ?? [],
|
|
30
|
+
nextAction,
|
|
31
|
+
...(options.lastCompletedMilestone !== undefined
|
|
32
|
+
? { lastCompletedMilestone: options.lastCompletedMilestone }
|
|
33
|
+
: {}),
|
|
34
|
+
...(options.includeActiveWorkspace ? { activeWorkspace: undefined } : {}),
|
|
35
|
+
registry: context.registry,
|
|
36
|
+
requirements: context.requirements,
|
|
37
|
+
progress: buildProgress(context),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
15
40
|
function stripMilestonePrefix(title) {
|
|
16
41
|
return title.replace(/^M\d+(?:-[a-z0-9]{6})?[^:]*:\s*/, '') || title;
|
|
17
42
|
}
|
|
@@ -125,103 +150,60 @@ async function buildRegistryAndFindActive(basePath, milestones, completeMileston
|
|
|
125
150
|
function handleNoActiveMilestone(registry, requirements, milestoneProgress) {
|
|
126
151
|
const pendingEntries = registry.filter(e => e.status === 'pending');
|
|
127
152
|
const parkedEntries = registry.filter(e => e.status === 'parked');
|
|
153
|
+
const context = {
|
|
154
|
+
activeMilestone: null,
|
|
155
|
+
registry,
|
|
156
|
+
requirements,
|
|
157
|
+
milestoneProgress,
|
|
158
|
+
};
|
|
128
159
|
if (pendingEntries.length > 0) {
|
|
129
160
|
const blockerDetails = pendingEntries
|
|
130
161
|
.filter(e => e.dependsOn && e.dependsOn.length > 0)
|
|
131
162
|
.map(e => `${e.id} is waiting on unmet deps: ${e.dependsOn.join(', ')}`);
|
|
132
|
-
return {
|
|
133
|
-
|
|
134
|
-
phase: 'blocked',
|
|
135
|
-
recentDecisions: [], blockers: blockerDetails.length > 0
|
|
163
|
+
return buildDerivedState(context, 'blocked', 'Resolve milestone dependencies before proceeding.', {
|
|
164
|
+
blockers: blockerDetails.length > 0
|
|
136
165
|
? blockerDetails
|
|
137
166
|
: ['All remaining milestones are dep-blocked but no deps listed — check CONTEXT.md files'],
|
|
138
|
-
|
|
139
|
-
registry, requirements,
|
|
140
|
-
progress: { milestones: milestoneProgress },
|
|
141
|
-
};
|
|
167
|
+
});
|
|
142
168
|
}
|
|
143
169
|
if (parkedEntries.length > 0) {
|
|
144
170
|
const parkedIds = parkedEntries.map(e => e.id).join(', ');
|
|
145
|
-
return {
|
|
146
|
-
activeMilestone: null, activeSlice: null, activeTask: null,
|
|
147
|
-
phase: 'pre-planning',
|
|
148
|
-
recentDecisions: [], blockers: [],
|
|
149
|
-
nextAction: `All remaining milestones are parked (${parkedIds}). Run /gsd unpark <id> or create a new milestone.`,
|
|
150
|
-
registry, requirements,
|
|
151
|
-
progress: { milestones: milestoneProgress },
|
|
152
|
-
};
|
|
171
|
+
return buildDerivedState(context, 'pre-planning', `All remaining milestones are parked (${parkedIds}). Run /gsd unpark <id> or create a new milestone.`);
|
|
153
172
|
}
|
|
154
173
|
if (registry.length === 0) {
|
|
155
|
-
return {
|
|
156
|
-
activeMilestone: null, activeSlice: null, activeTask: null,
|
|
157
|
-
phase: 'pre-planning',
|
|
158
|
-
recentDecisions: [], blockers: [],
|
|
159
|
-
nextAction: 'No milestones found. Run /gsd to create one.',
|
|
160
|
-
registry: [], requirements,
|
|
161
|
-
progress: { milestones: { done: 0, total: 0 } },
|
|
162
|
-
};
|
|
174
|
+
return buildDerivedState({ ...context, registry: [], milestoneProgress: { done: 0, total: 0 } }, 'pre-planning', 'No milestones found. Run /gsd to create one.');
|
|
163
175
|
}
|
|
164
176
|
const lastEntry = registry[registry.length - 1];
|
|
165
177
|
const unmappedActive = countUnmappedActiveRequirements();
|
|
166
178
|
const completionNote = formatCompletePhaseNextAction(unmappedActive);
|
|
167
|
-
return {
|
|
168
|
-
activeMilestone: null,
|
|
179
|
+
return buildDerivedState(context, 'complete', completionNote, {
|
|
169
180
|
lastCompletedMilestone: lastEntry ? { id: lastEntry.id, title: lastEntry.title } : null,
|
|
170
|
-
|
|
171
|
-
phase: 'complete',
|
|
172
|
-
recentDecisions: [], blockers: [],
|
|
173
|
-
nextAction: completionNote,
|
|
174
|
-
registry, requirements,
|
|
175
|
-
progress: { milestones: milestoneProgress },
|
|
176
|
-
};
|
|
181
|
+
});
|
|
177
182
|
}
|
|
178
183
|
async function handleAllSlicesDone(basePath, activeMilestone, registry, requirements, milestoneProgress, sliceProgress) {
|
|
179
184
|
const validation = getLatestAssessmentByScope(activeMilestone.id, "milestone-validation");
|
|
180
185
|
const verdict = typeof validation?.status === "string" ? validation.status : undefined;
|
|
181
186
|
const validationTerminal = verdict != null && verdict !== "";
|
|
187
|
+
const context = {
|
|
188
|
+
activeMilestone,
|
|
189
|
+
registry,
|
|
190
|
+
requirements,
|
|
191
|
+
milestoneProgress,
|
|
192
|
+
sliceProgress,
|
|
193
|
+
};
|
|
182
194
|
if (!validationTerminal) {
|
|
183
|
-
return {
|
|
184
|
-
activeMilestone, activeSlice: null, activeTask: null,
|
|
185
|
-
phase: 'validating-milestone',
|
|
186
|
-
recentDecisions: [], blockers: [],
|
|
187
|
-
nextAction: `Validate milestone ${activeMilestone.id} before completion.`,
|
|
188
|
-
registry, requirements,
|
|
189
|
-
progress: { milestones: milestoneProgress, slices: sliceProgress },
|
|
190
|
-
};
|
|
195
|
+
return buildDerivedState(context, 'validating-milestone', `Validate milestone ${activeMilestone.id} before completion.`);
|
|
191
196
|
}
|
|
192
197
|
// All roadmap slices are done (enforced by caller) and verdict is
|
|
193
198
|
// needs-remediation — remediation cannot progress without new slices.
|
|
194
199
|
// Return blocked instead of re-dispatching validate-milestone (#4506).
|
|
195
200
|
if (verdict === 'needs-attention') {
|
|
196
|
-
return {
|
|
197
|
-
activeMilestone, activeSlice: null, activeTask: null,
|
|
198
|
-
phase: 'blocked',
|
|
199
|
-
recentDecisions: [],
|
|
200
|
-
blockers: [formatNeedsAttentionBlocker(activeMilestone.id)],
|
|
201
|
-
nextAction: `Resolve ${activeMilestone.id} validation attention before proceeding.`,
|
|
202
|
-
registry, requirements,
|
|
203
|
-
progress: { milestones: milestoneProgress, slices: sliceProgress },
|
|
204
|
-
};
|
|
201
|
+
return buildDerivedState(context, 'blocked', `Resolve ${activeMilestone.id} validation attention before proceeding.`, { blockers: [formatNeedsAttentionBlocker(activeMilestone.id)] });
|
|
205
202
|
}
|
|
206
203
|
if (verdict === 'needs-remediation') {
|
|
207
|
-
return {
|
|
208
|
-
activeMilestone, activeSlice: null, activeTask: null,
|
|
209
|
-
phase: 'blocked',
|
|
210
|
-
recentDecisions: [],
|
|
211
|
-
blockers: [formatNeedsRemediationBlocker(activeMilestone.id)],
|
|
212
|
-
nextAction: `Resolve ${activeMilestone.id} remediation before proceeding.`,
|
|
213
|
-
registry, requirements,
|
|
214
|
-
progress: { milestones: milestoneProgress, slices: sliceProgress },
|
|
215
|
-
};
|
|
204
|
+
return buildDerivedState(context, 'blocked', `Resolve ${activeMilestone.id} remediation before proceeding.`, { blockers: [formatNeedsRemediationBlocker(activeMilestone.id)] });
|
|
216
205
|
}
|
|
217
|
-
return {
|
|
218
|
-
activeMilestone, activeSlice: null, activeTask: null,
|
|
219
|
-
phase: 'completing-milestone',
|
|
220
|
-
recentDecisions: [], blockers: [],
|
|
221
|
-
nextAction: `All slices complete in ${activeMilestone.id}. Write milestone summary.`,
|
|
222
|
-
registry, requirements,
|
|
223
|
-
progress: { milestones: milestoneProgress, slices: sliceProgress },
|
|
224
|
-
};
|
|
206
|
+
return buildDerivedState(context, 'completing-milestone', `All slices complete in ${activeMilestone.id}. Write milestone summary.`);
|
|
225
207
|
}
|
|
226
208
|
function resolveSliceDependencies(activeMilestoneSlices) {
|
|
227
209
|
const doneSliceIds = new Set(activeMilestoneSlices.filter(s => isStatusDone(s.status)).map(s => s.id));
|
|
@@ -271,13 +253,12 @@ export async function deriveStateFromDb(basePath, artifactReadRoot = basePath) {
|
|
|
271
253
|
? allMilestones.filter(m => m.id === milestoneLock)
|
|
272
254
|
: allMilestones;
|
|
273
255
|
if (milestones.length === 0) {
|
|
274
|
-
return {
|
|
275
|
-
activeMilestone: null,
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
};
|
|
256
|
+
return buildDerivedState({
|
|
257
|
+
activeMilestone: null,
|
|
258
|
+
registry: [],
|
|
259
|
+
requirements,
|
|
260
|
+
milestoneProgress: { done: 0, total: 0 },
|
|
261
|
+
}, 'pre-planning', 'No milestones found. Run /gsd to create one.');
|
|
281
262
|
}
|
|
282
263
|
const { completeMilestoneIds, parkedMilestoneIds } = buildCompletenessSet(basePath, milestones);
|
|
283
264
|
const registryContext = await buildRegistryAndFindActive(basePath, milestones, completeMilestoneIds, parkedMilestoneIds);
|
|
@@ -294,18 +275,20 @@ export async function deriveStateFromDb(basePath, artifactReadRoot = basePath) {
|
|
|
294
275
|
const nextAction = activeMilestoneHasDraft
|
|
295
276
|
? `Discuss draft context for milestone ${activeMilestone.id}.`
|
|
296
277
|
: `Plan milestone ${activeMilestone.id}.`;
|
|
297
|
-
return {
|
|
298
|
-
activeMilestone, activeSlice: null, activeTask: null,
|
|
299
|
-
phase, recentDecisions: [], blockers: [],
|
|
300
|
-
nextAction, registry, requirements,
|
|
301
|
-
progress: { milestones: milestoneProgress },
|
|
302
|
-
};
|
|
278
|
+
return buildDerivedState({ activeMilestone, registry, requirements, milestoneProgress }, phase, nextAction);
|
|
303
279
|
}
|
|
304
280
|
const allSlicesDone = activeMilestoneSlices.every(s => isStatusDone(s.status));
|
|
305
281
|
const sliceProgress = {
|
|
306
282
|
done: activeMilestoneSlices.filter(s => isStatusDone(s.status)).length,
|
|
307
283
|
total: activeMilestoneSlices.length,
|
|
308
284
|
};
|
|
285
|
+
const sliceStateContext = {
|
|
286
|
+
activeMilestone,
|
|
287
|
+
registry,
|
|
288
|
+
requirements,
|
|
289
|
+
milestoneProgress,
|
|
290
|
+
sliceProgress,
|
|
291
|
+
};
|
|
309
292
|
if (allSlicesDone) {
|
|
310
293
|
return handleAllSlicesDone(basePath, activeMilestone, registry, requirements, milestoneProgress, sliceProgress);
|
|
311
294
|
}
|
|
@@ -314,21 +297,9 @@ export async function deriveStateFromDb(basePath, artifactReadRoot = basePath) {
|
|
|
314
297
|
// If locked slice wasn't found, it returns null but logs warning, we need to return 'blocked'
|
|
315
298
|
const sliceLock = process.env.GSD_PARALLEL_WORKER ? process.env.GSD_SLICE_LOCK : undefined;
|
|
316
299
|
if (sliceLock) {
|
|
317
|
-
return {
|
|
318
|
-
activeMilestone, activeSlice: null, activeTask: null,
|
|
319
|
-
phase: 'blocked', recentDecisions: [], blockers: [`GSD_SLICE_LOCK=${sliceLock} not found in active milestone slices`],
|
|
320
|
-
nextAction: 'Slice lock references a non-existent slice — check orchestrator dispatch.',
|
|
321
|
-
registry, requirements,
|
|
322
|
-
progress: { milestones: milestoneProgress, slices: sliceProgress },
|
|
323
|
-
};
|
|
300
|
+
return buildDerivedState(sliceStateContext, 'blocked', 'Slice lock references a non-existent slice — check orchestrator dispatch.', { blockers: [`GSD_SLICE_LOCK=${sliceLock} not found in active milestone slices`] });
|
|
324
301
|
}
|
|
325
|
-
return {
|
|
326
|
-
activeMilestone, activeSlice: null, activeTask: null,
|
|
327
|
-
phase: 'blocked', recentDecisions: [], blockers: ['No slice eligible — check dependency ordering'],
|
|
328
|
-
nextAction: 'Resolve dependency blockers or plan next slice.',
|
|
329
|
-
registry, requirements,
|
|
330
|
-
progress: { milestones: milestoneProgress, slices: sliceProgress },
|
|
331
|
-
};
|
|
302
|
+
return buildDerivedState(sliceStateContext, 'blocked', 'Resolve dependency blockers or plan next slice.', { blockers: ['No slice eligible — check dependency ordering'] });
|
|
332
303
|
}
|
|
333
304
|
const { activeSlice } = activeSliceContext;
|
|
334
305
|
const activeSliceRow = activeSliceContext.activeSliceRow;
|
|
@@ -338,39 +309,30 @@ export async function deriveStateFromDb(basePath, artifactReadRoot = basePath) {
|
|
|
338
309
|
// PLAN.md and preference flags are projections/configuration and are
|
|
339
310
|
// deliberately not used to infer whether the slice itself is a sketch.
|
|
340
311
|
if (activeSliceRow?.is_sketch === 1) {
|
|
341
|
-
return {
|
|
342
|
-
activeMilestone, activeSlice, activeTask: null,
|
|
343
|
-
phase: 'refining', recentDecisions: [], blockers: [],
|
|
344
|
-
nextAction: `Refine sketch slice ${activeSlice.id} (${activeSlice.title}) using prior slice context.`,
|
|
345
|
-
registry, requirements,
|
|
346
|
-
progress: { milestones: milestoneProgress, slices: sliceProgress },
|
|
347
|
-
};
|
|
312
|
+
return buildDerivedState({ ...sliceStateContext, activeSlice }, 'refining', `Refine sketch slice ${activeSlice.id} (${activeSlice.title}) using prior slice context.`);
|
|
348
313
|
}
|
|
349
314
|
const tasks = getSliceTasks(activeMilestone.id, activeSlice.id);
|
|
350
315
|
const taskProgress = {
|
|
351
316
|
done: tasks.filter(t => isStatusDone(t.status)).length,
|
|
352
317
|
total: tasks.length,
|
|
353
318
|
};
|
|
319
|
+
const taskStateContext = {
|
|
320
|
+
...sliceStateContext,
|
|
321
|
+
activeSlice,
|
|
322
|
+
taskProgress,
|
|
323
|
+
};
|
|
354
324
|
const activeTaskRow = tasks.find(t => !isStatusDone(t.status));
|
|
355
325
|
if (!activeTaskRow && tasks.length > 0) {
|
|
356
|
-
return {
|
|
357
|
-
activeMilestone, activeSlice, activeTask: null,
|
|
358
|
-
phase: 'summarizing', recentDecisions: [], blockers: [],
|
|
359
|
-
nextAction: `All tasks done in ${activeSlice.id}. Write slice summary and complete slice.`,
|
|
360
|
-
registry, requirements,
|
|
361
|
-
progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
|
|
362
|
-
};
|
|
326
|
+
return buildDerivedState(taskStateContext, 'summarizing', `All tasks done in ${activeSlice.id}. Write slice summary and complete slice.`);
|
|
363
327
|
}
|
|
364
328
|
if (!activeTaskRow) {
|
|
365
|
-
return {
|
|
366
|
-
activeMilestone, activeSlice, activeTask: null,
|
|
367
|
-
phase: 'planning', recentDecisions: [], blockers: [],
|
|
368
|
-
nextAction: `Slice ${activeSlice.id} has no DB tasks. Plan slice tasks before execution.`,
|
|
369
|
-
registry, requirements,
|
|
370
|
-
progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
|
|
371
|
-
};
|
|
329
|
+
return buildDerivedState(taskStateContext, 'planning', `Slice ${activeSlice.id} has no DB tasks. Plan slice tasks before execution.`);
|
|
372
330
|
}
|
|
373
331
|
const activeTask = { id: activeTaskRow.id, title: activeTaskRow.title };
|
|
332
|
+
const activeTaskStateContext = {
|
|
333
|
+
...taskStateContext,
|
|
334
|
+
activeTask,
|
|
335
|
+
};
|
|
374
336
|
// ── Quality gate evaluation check ──────────────────────────────────
|
|
375
337
|
// Pause before execution only when gates owned by the `gate-evaluate`
|
|
376
338
|
// turn (Q3/Q4) are still pending. Q8 is also `scope:"slice"` but is
|
|
@@ -380,27 +342,16 @@ export async function deriveStateFromDb(basePath, artifactReadRoot = basePath) {
|
|
|
380
342
|
// Slices with zero gate rows (pre-feature or simple) skip straight through.
|
|
381
343
|
const pendingGateCount = getPendingGateCountForTurn(activeMilestone.id, activeSlice.id, "gate-evaluate");
|
|
382
344
|
if (pendingGateCount > 0) {
|
|
383
|
-
return {
|
|
384
|
-
activeMilestone, activeSlice, activeTask: null,
|
|
385
|
-
phase: 'evaluating-gates', recentDecisions: [], blockers: [],
|
|
386
|
-
nextAction: `Evaluate ${pendingGateCount} quality gate(s) for ${activeSlice.id} before execution.`,
|
|
387
|
-
registry, requirements,
|
|
388
|
-
progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
|
|
389
|
-
};
|
|
345
|
+
return buildDerivedState(taskStateContext, 'evaluating-gates', `Evaluate ${pendingGateCount} quality gate(s) for ${activeSlice.id} before execution.`);
|
|
390
346
|
}
|
|
391
347
|
const blockerTaskId = await detectBlockers(basePath, activeMilestone.id, activeSlice.id, tasks);
|
|
392
348
|
if (blockerTaskId) {
|
|
393
349
|
const replanHistory = getReplanHistory(activeMilestone.id, activeSlice.id);
|
|
394
350
|
if (replanHistory.length === 0) {
|
|
395
|
-
return {
|
|
396
|
-
activeMilestone, activeSlice, activeTask,
|
|
397
|
-
phase: 'replanning-slice', recentDecisions: [],
|
|
351
|
+
return buildDerivedState(activeTaskStateContext, 'replanning-slice', `Task ${blockerTaskId} reported blocker_discovered. Replan slice ${activeSlice.id} before continuing.`, {
|
|
398
352
|
blockers: [`Task ${blockerTaskId} discovered a blocker requiring slice replan`],
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
registry, requirements,
|
|
402
|
-
progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
|
|
403
|
-
};
|
|
353
|
+
includeActiveWorkspace: true,
|
|
354
|
+
});
|
|
404
355
|
}
|
|
405
356
|
}
|
|
406
357
|
// ADR-011 Phase 2: pause-on-escalation takes precedence over dispatching the
|
|
@@ -415,38 +366,22 @@ export async function deriveStateFromDb(basePath, artifactReadRoot = basePath) {
|
|
|
415
366
|
// and the user's prior resolution never lands.
|
|
416
367
|
const escalatingTaskId = detectPendingEscalation(tasks, basePath);
|
|
417
368
|
if (escalatingTaskId) {
|
|
418
|
-
return {
|
|
419
|
-
activeMilestone, activeSlice, activeTask,
|
|
420
|
-
phase: 'escalating-task', recentDecisions: [],
|
|
369
|
+
return buildDerivedState(activeTaskStateContext, 'escalating-task', `Run /gsd escalate show ${escalatingTaskId} to review, then /gsd escalate resolve ${escalatingTaskId} <choice> to proceed.`, {
|
|
421
370
|
blockers: [`Task ${escalatingTaskId} requires a user decision before the loop can proceed`],
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
registry, requirements,
|
|
425
|
-
progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
|
|
426
|
-
};
|
|
371
|
+
includeActiveWorkspace: true,
|
|
372
|
+
});
|
|
427
373
|
}
|
|
428
374
|
if (!blockerTaskId) {
|
|
429
375
|
const isTriggered = checkReplanTrigger(basePath, activeMilestone.id, activeSlice.id);
|
|
430
376
|
if (isTriggered) {
|
|
431
377
|
const replanHistory = getReplanHistory(activeMilestone.id, activeSlice.id);
|
|
432
378
|
if (replanHistory.length === 0) {
|
|
433
|
-
return {
|
|
434
|
-
activeMilestone, activeSlice, activeTask,
|
|
435
|
-
phase: 'replanning-slice', recentDecisions: [],
|
|
379
|
+
return buildDerivedState(activeTaskStateContext, 'replanning-slice', `Triage replan triggered for slice ${activeSlice.id}. Replan before continuing.`, {
|
|
436
380
|
blockers: ['Triage replan trigger detected — slice replan required'],
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
registry, requirements,
|
|
440
|
-
progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
|
|
441
|
-
};
|
|
381
|
+
includeActiveWorkspace: true,
|
|
382
|
+
});
|
|
442
383
|
}
|
|
443
384
|
}
|
|
444
385
|
}
|
|
445
|
-
return {
|
|
446
|
-
activeMilestone, activeSlice, activeTask,
|
|
447
|
-
phase: 'executing', recentDecisions: [], blockers: [],
|
|
448
|
-
nextAction: `Execute ${activeTask.id}: ${activeTask.title} in slice ${activeSlice.id}.`,
|
|
449
|
-
registry, requirements,
|
|
450
|
-
progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
|
|
451
|
-
};
|
|
386
|
+
return buildDerivedState(activeTaskStateContext, 'executing', `Execute ${activeTask.id}: ${activeTask.title} in slice ${activeSlice.id}.`);
|
|
452
387
|
}
|
|
@@ -26,6 +26,20 @@ export function getUnitWorkflowDispatchReadinessError(input) {
|
|
|
26
26
|
activeTools: input.activeTools,
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
|
+
export function getUnitWorkflowDispatchReadinessErrorForModel(input) {
|
|
30
|
+
const provider = input.model?.provider ?? input.fallbackModel?.provider;
|
|
31
|
+
const baseUrl = input.model?.baseUrl ?? input.fallbackModel?.baseUrl;
|
|
32
|
+
return getUnitWorkflowDispatchReadinessError({
|
|
33
|
+
provider,
|
|
34
|
+
unitType: input.unitType,
|
|
35
|
+
projectRoot: input.projectRoot,
|
|
36
|
+
env: input.env,
|
|
37
|
+
surface: input.surface,
|
|
38
|
+
authMode: provider ? input.getProviderAuthMode?.(provider) : undefined,
|
|
39
|
+
baseUrl,
|
|
40
|
+
activeTools: input.activeTools,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
29
43
|
export function compileUnitToolContract(unitType) {
|
|
30
44
|
const manifest = resolveManifest(unitType);
|
|
31
45
|
const surfaceContract = getUnitToolSurfaceContract(unitType);
|
|
@@ -12,6 +12,47 @@ import { appendEvent } from "../workflow-events.js";
|
|
|
12
12
|
import { logWarning } from "../workflow-logger.js";
|
|
13
13
|
import { loadEffectiveGSDPreferences } from "../preferences.js";
|
|
14
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
|
+
}
|
|
15
56
|
function validateParams(params) {
|
|
16
57
|
if (!isNonEmptyString(params?.milestoneId))
|
|
17
58
|
throw new Error("milestoneId is required");
|
|
@@ -35,6 +76,9 @@ function validateParams(params) {
|
|
|
35
76
|
files: validateStringArray(params.files, "files"),
|
|
36
77
|
inputs: validateStringArray(params.inputs, "inputs"),
|
|
37
78
|
expectedOutput: validateStringArray(params.expectedOutput, "expectedOutput"),
|
|
79
|
+
...(params.targetRepositories !== undefined
|
|
80
|
+
? { targetRepositories: validateRepositoryTargetIds("targetRepositories", params.targetRepositories) }
|
|
81
|
+
: {}),
|
|
38
82
|
};
|
|
39
83
|
}
|
|
40
84
|
function resolveTaskGates(basePath) {
|
|
@@ -57,22 +101,18 @@ export async function handlePlanTask(rawParams, basePath) {
|
|
|
57
101
|
if (pathOnlyError) {
|
|
58
102
|
return { error: `validation failed: ${pathOnlyError}` };
|
|
59
103
|
}
|
|
60
|
-
const pathScopeError = validatePlanningPathScope(basePath, [
|
|
61
|
-
{ field: "files", values: params.files },
|
|
62
|
-
{ field: "inputs", values: params.inputs },
|
|
63
|
-
{ field: "expectedOutput", values: params.expectedOutput },
|
|
64
|
-
]);
|
|
65
|
-
if (pathScopeError) {
|
|
66
|
-
return { error: `validation failed: ${pathScopeError}` };
|
|
67
|
-
}
|
|
68
104
|
let taskGates;
|
|
105
|
+
let repositoryRegistry;
|
|
69
106
|
try {
|
|
70
107
|
taskGates = resolveTaskGates(basePath);
|
|
108
|
+
const loaded = loadEffectiveGSDPreferences(basePath);
|
|
109
|
+
repositoryRegistry = createRepositoryRegistryFromPreferences(basePath, loaded?.preferences);
|
|
71
110
|
}
|
|
72
111
|
catch (err) {
|
|
73
112
|
const message = err instanceof Error ? err.message : String(err);
|
|
74
113
|
return { error: `validation failed: ${message}` };
|
|
75
114
|
}
|
|
115
|
+
const defaultTargets = defaultRepositoryTargets(repositoryRegistry);
|
|
76
116
|
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
77
117
|
// Guards must be inside the transaction so the state they check cannot
|
|
78
118
|
// change between the read and the write (#2723).
|
|
@@ -93,6 +133,33 @@ export async function handlePlanTask(rawParams, basePath) {
|
|
|
93
133
|
guardError = `cannot re-plan task ${params.taskId}: it is already complete — use gsd_task_reopen first`;
|
|
94
134
|
return;
|
|
95
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
|
+
}
|
|
96
163
|
if (!existingTask) {
|
|
97
164
|
insertTask({
|
|
98
165
|
id: params.taskId,
|
|
@@ -112,6 +179,7 @@ export async function handlePlanTask(rawParams, basePath) {
|
|
|
112
179
|
expectedOutput: params.expectedOutput,
|
|
113
180
|
observabilityImpact: params.observabilityImpact ?? "",
|
|
114
181
|
fullPlanMd: params.fullPlanMd,
|
|
182
|
+
targetRepositories: effectiveTargetRepositories,
|
|
115
183
|
});
|
|
116
184
|
for (const gid of taskGates) {
|
|
117
185
|
insertGateRow({ milestoneId: params.milestoneId, sliceId: params.sliceId, gateId: gid, scope: "task", taskId: params.taskId });
|
|
@@ -5,6 +5,11 @@
|
|
|
5
5
|
* tasks back to "pending". This is intentional — if you're reopening a
|
|
6
6
|
* slice, you're re-doing the work. Partial resets create ambiguous state.
|
|
7
7
|
*
|
|
8
|
+
* Also recovers a desynced slice (#1205): when a UAT→planning fallback leaves
|
|
9
|
+
* the slice open (e.g. "pending") but its tasks still "complete", this clears
|
|
10
|
+
* that state so the planner can re-plan without hitting "already complete"
|
|
11
|
+
* rejections.
|
|
12
|
+
*
|
|
8
13
|
* The parent milestone must still be open (not complete).
|
|
9
14
|
*/
|
|
10
15
|
// GSD — reopen-slice tool handler
|
|
@@ -16,8 +16,8 @@ import { writeManifest } from "../workflow-manifest.js";
|
|
|
16
16
|
import { appendEvent } from "../workflow-events.js";
|
|
17
17
|
import { logWarning } from "../workflow-logger.js";
|
|
18
18
|
import { existsSync, unlinkSync } from "node:fs";
|
|
19
|
-
import { join } from "node:path";
|
|
20
|
-
import { resolveTasksDir, clearPathCache } from "../paths.js";
|
|
19
|
+
import { join, basename, dirname } from "node:path";
|
|
20
|
+
import { resolveTasksDir, resolveSlicePath, clearPathCache } from "../paths.js";
|
|
21
21
|
export async function handleReopenTask(params, basePath) {
|
|
22
22
|
// ── Validate required fields ────────────────────────────────────────────
|
|
23
23
|
if (!params.taskId || typeof params.taskId !== "string" || params.taskId.trim() === "") {
|
|
@@ -69,10 +69,18 @@ export async function handleReopenTask(params, basePath) {
|
|
|
69
69
|
// ── Clean up stale filesystem artifacts (M12 fix) ────────────────────────
|
|
70
70
|
// Without this, the DB-filesystem reconciler sees the SUMMARY.md and
|
|
71
71
|
// auto-corrects the task back to "complete", making reopen a no-op (#3161).
|
|
72
|
+
// Legacy layout keeps the summary under a tasks/ subdir; flat-phase writes
|
|
73
|
+
// TID-SUMMARY.md directly in the phase dir. A tasks/ subdir may still exist
|
|
74
|
+
// in flat-phase for auxiliary artifacts — its mere existence must NOT redirect
|
|
75
|
+
// summary cleanup into tasks/ (#1208).
|
|
72
76
|
try {
|
|
73
|
-
const
|
|
74
|
-
if (
|
|
75
|
-
const
|
|
77
|
+
const slicePath = resolveSlicePath(basePath, params.milestoneId, params.sliceId);
|
|
78
|
+
if (slicePath) {
|
|
79
|
+
const isLegacySlice = basename(dirname(slicePath)) === "slices";
|
|
80
|
+
const summaryDir = isLegacySlice
|
|
81
|
+
? (resolveTasksDir(basePath, params.milestoneId, params.sliceId) ?? slicePath)
|
|
82
|
+
: slicePath;
|
|
83
|
+
const summaryPath = join(summaryDir, `${params.taskId}-SUMMARY.md`);
|
|
76
84
|
if (existsSync(summaryPath))
|
|
77
85
|
unlinkSync(summaryPath);
|
|
78
86
|
}
|
|
@@ -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: [{
|
|
@@ -178,9 +178,10 @@ export const UNIT_MANIFESTS = {
|
|
|
178
178
|
codebaseMap: false,
|
|
179
179
|
preferences: "active-only",
|
|
180
180
|
contextMode: "verification",
|
|
181
|
-
// Validation
|
|
182
|
-
//
|
|
183
|
-
|
|
181
|
+
// Validation must persist its durable output through gsd_validate_milestone;
|
|
182
|
+
// generic write/bash tools can create filesystem artifacts that bypass DB
|
|
183
|
+
// state and trigger destructive recovery loops.
|
|
184
|
+
tools: { mode: "workflow-only", allowedSubagents: ["reviewer", "security", "tester"] },
|
|
184
185
|
artifacts: {
|
|
185
186
|
inline: ["roadmap", "requirements", "templates"],
|
|
186
187
|
excerpt: ["slice-summary", "slice-assessment"],
|
|
@@ -531,7 +532,7 @@ export function compileSubagentPermissionContract(policy) {
|
|
|
531
532
|
if (policy.mode === "all") {
|
|
532
533
|
return { allowed: true, allowedSubagents: ["*"], toolsMode: policy.mode };
|
|
533
534
|
}
|
|
534
|
-
if ((policy.mode === "planning-dispatch" || policy.mode === "verification") &&
|
|
535
|
+
if ((policy.mode === "planning-dispatch" || policy.mode === "verification" || policy.mode === "workflow-only") &&
|
|
535
536
|
Array.isArray(policy.allowedSubagents)) {
|
|
536
537
|
return {
|
|
537
538
|
allowed: policy.allowedSubagents.length > 0,
|