@opengsd/gsd-pi 1.5.0 → 1.6.0-dev.aa7f94e8
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 +10 -10
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/ask-user-questions.js +1 -1
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +114 -36
- package/dist/resources/extensions/gsd/activity-log.js +1 -1
- package/dist/resources/extensions/gsd/auto/closeout.js +97 -5
- package/dist/resources/extensions/gsd/auto/orchestrator.js +20 -13
- package/dist/resources/extensions/gsd/auto/pre-dispatch.js +6 -3
- package/dist/resources/extensions/gsd/auto/unit-phase.js +5 -9
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +14 -5
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -7
- package/dist/resources/extensions/gsd/auto-dispatch.js +69 -17
- package/dist/resources/extensions/gsd/auto-model-selection.js +28 -1
- package/dist/resources/extensions/gsd/auto-post-unit.js +23 -6
- package/dist/resources/extensions/gsd/auto-prompts.js +49 -117
- package/dist/resources/extensions/gsd/auto-recovery.js +50 -6
- package/dist/resources/extensions/gsd/auto-start.js +57 -33
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +12 -2
- package/dist/resources/extensions/gsd/auto-timers.js +9 -2
- 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 -2073
- package/dist/resources/extensions/gsd/auto.js +118 -34
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +20 -2
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +185 -27
- package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +68 -2
- package/dist/resources/extensions/gsd/codebase-generator.js +7 -1
- package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
- package/dist/resources/extensions/gsd/commands-workflow-templates.js +3 -3
- package/dist/resources/extensions/gsd/compat/compat-marker.js +44 -0
- package/dist/resources/extensions/gsd/config-overlay.js +7 -2
- package/dist/resources/extensions/gsd/db/engine.js +33 -0
- package/dist/resources/extensions/gsd/db/queries.js +9 -9
- package/dist/resources/extensions/gsd/db/writers/cascades.js +20 -2
- package/dist/resources/extensions/gsd/db-adapter.js +30 -3
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +3 -3
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +93 -11
- package/dist/resources/extensions/gsd/flat-phase-migration.js +32 -3
- 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 +45 -0
- package/dist/resources/extensions/gsd/gsd-db.js +23 -11
- package/dist/resources/extensions/gsd/guided-flow.js +22 -17
- package/dist/resources/extensions/gsd/journal.js +1 -1
- package/dist/resources/extensions/gsd/markdown-renderer.js +34 -79
- package/dist/resources/extensions/gsd/md-importer.js +89 -23
- package/dist/resources/extensions/gsd/metrics.js +2 -2
- package/dist/resources/extensions/gsd/migration-auto-check.js +30 -3
- package/dist/resources/extensions/gsd/milestone-merge-transaction.js +11 -0
- 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 +87 -52
- package/dist/resources/extensions/gsd/post-unit-hooks.js +27 -0
- package/dist/resources/extensions/gsd/preferences-models.js +66 -15
- 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 +148 -10
- package/dist/resources/extensions/gsd/preferences.js +20 -0
- package/dist/resources/extensions/gsd/prompts/system.md +6 -6
- package/dist/resources/extensions/gsd/quick.js +12 -3
- package/dist/resources/extensions/gsd/reopen-reason.js +98 -0
- package/dist/resources/extensions/gsd/rule-registry.js +106 -10
- package/dist/resources/extensions/gsd/session-status-io.js +31 -0
- package/dist/resources/extensions/gsd/skill-discovery.js +36 -23
- 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/state-reconciliation/drift/artifact-db.js +1 -10
- package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +3 -24
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +10 -0
- package/dist/resources/extensions/gsd/tool-contract.js +14 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -5
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +16 -10
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +5 -0
- package/dist/resources/extensions/gsd/tools/reopen-task.js +28 -5
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -8
- package/dist/resources/extensions/gsd/uat-dispatch.js +94 -0
- package/dist/resources/extensions/gsd/unit-registry.js +12 -2
- package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +1 -1
- package/dist/resources/extensions/gsd/uok/audit-toggle.js +31 -2
- package/dist/resources/extensions/gsd/uok/audit.js +3 -0
- package/dist/resources/extensions/gsd/uok/gate-runner.js +22 -30
- package/dist/resources/extensions/gsd/uok/gitops.js +18 -15
- package/dist/resources/extensions/gsd/uok/kernel.js +120 -46
- package/dist/resources/extensions/gsd/uok/model-policy.js +17 -14
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -1
- package/dist/resources/extensions/gsd/workflow-event-ledger.js +1 -1
- package/dist/resources/extensions/gsd/workflow-logger.js +1 -1
- package/dist/resources/extensions/gsd/workflow-projections.js +9 -26
- package/dist/resources/extensions/gsd/workspace-git-preflight.js +2 -2
- package/dist/resources/extensions/gsd/workspace.js +5 -14
- package/dist/resources/extensions/gsd/worktree-command.js +1 -1
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +14 -9
- package/dist/resources/extensions/gsd/worktree-reentry.js +2 -1
- package/dist/resources/extensions/shared/gsd-browser-cli.js +51 -5
- 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 +6 -6
- 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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +1 -1
- 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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +1 -1
- 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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +1 -1
- 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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +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.js.nft.json +1 -1
- 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.js.nft.json +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.js.nft.json +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 +6 -6
- package/dist/web/standalone/.next/server/chunks/{1128.js → 1991.js} +1 -1
- package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
- package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
- 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/worktree-cli-create.d.ts +10 -0
- package/dist/worktree-cli-create.js +11 -0
- package/dist/worktree-cli-format.d.ts +12 -0
- package/dist/worktree-cli-format.js +38 -0
- package/dist/worktree-cli-plan.d.ts +16 -0
- package/dist/worktree-cli-plan.js +19 -0
- package/dist/worktree-cli-session.d.ts +13 -0
- package/dist/worktree-cli-session.js +18 -0
- package/dist/worktree-cli-status.d.ts +35 -0
- package/dist/worktree-cli-status.js +54 -0
- package/dist/worktree-cli.d.ts +1 -16
- package/dist/worktree-cli.js +28 -122
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +25 -36
- package/integrations/hermes/pyproject.toml +1 -1
- package/integrations/hermes/tests/test_gsd_client_timeout.py +4 -4
- package/package.json +6 -6
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/dist/cloud-cli.d.ts +1 -1
- package/packages/daemon/dist/cloud-cli.d.ts.map +1 -1
- package/packages/daemon/dist/cloud-cli.js +42 -2
- package/packages/daemon/dist/cloud-cli.js.map +1 -1
- package/packages/daemon/dist/cloud-config.d.ts +1 -0
- package/packages/daemon/dist/cloud-config.d.ts.map +1 -1
- package/packages/daemon/dist/cloud-config.js +1 -1
- package/packages/daemon/dist/cloud-config.js.map +1 -1
- package/packages/daemon/dist/device-flow.d.ts +24 -0
- package/packages/daemon/dist/device-flow.d.ts.map +1 -0
- package/packages/daemon/dist/device-flow.js +128 -0
- package/packages/daemon/dist/device-flow.js.map +1 -0
- package/packages/daemon/dist/device-flow.test.d.ts +2 -0
- package/packages/daemon/dist/device-flow.test.d.ts.map +1 -0
- package/packages/daemon/dist/device-flow.test.js +172 -0
- package/packages/daemon/dist/device-flow.test.js.map +1 -0
- package/packages/daemon/dist/orchestrator-agent.d.ts +21 -0
- package/packages/daemon/dist/orchestrator-agent.d.ts.map +1 -0
- package/packages/daemon/dist/orchestrator-agent.js +113 -0
- package/packages/daemon/dist/orchestrator-agent.js.map +1 -0
- package/packages/daemon/dist/orchestrator-tools.d.ts +12 -0
- package/packages/daemon/dist/orchestrator-tools.d.ts.map +1 -0
- package/packages/daemon/dist/orchestrator-tools.js +137 -0
- package/packages/daemon/dist/orchestrator-tools.js.map +1 -0
- package/packages/daemon/dist/orchestrator.d.ts +4 -56
- package/packages/daemon/dist/orchestrator.d.ts.map +1 -1
- package/packages/daemon/dist/orchestrator.js +13 -303
- package/packages/daemon/dist/orchestrator.js.map +1 -1
- package/packages/daemon/dist/orchestrator.test.js +11 -1
- package/packages/daemon/dist/orchestrator.test.js.map +1 -1
- package/packages/daemon/package.json +5 -5
- package/packages/gsd-agent-core/dist/export-html/template.js +53 -4
- 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/package.json +7 -7
- package/packages/gsd-cloud/README.md +34 -0
- package/packages/gsd-cloud/bin/gsd-cloud.js +27 -0
- package/packages/gsd-cloud/package.json +38 -0
- 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/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 +8 -20
- 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/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/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/package.json +2 -2
- package/pkg/dist/core/export-html/template.js +53 -4
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +1 -1
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +146 -33
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +44 -0
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +93 -0
- package/src/resources/extensions/gsd/activity-log.ts +1 -1
- package/src/resources/extensions/gsd/auto/closeout.ts +114 -7
- package/src/resources/extensions/gsd/auto/orchestrator.ts +21 -14
- package/src/resources/extensions/gsd/auto/pre-dispatch.ts +6 -3
- package/src/resources/extensions/gsd/auto/unit-phase.ts +5 -9
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +14 -4
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +13 -7
- package/src/resources/extensions/gsd/auto-dispatch.ts +77 -16
- package/src/resources/extensions/gsd/auto-model-selection.ts +33 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +26 -5
- package/src/resources/extensions/gsd/auto-prompts.ts +73 -113
- package/src/resources/extensions/gsd/auto-recovery.ts +50 -6
- package/src/resources/extensions/gsd/auto-start.ts +62 -31
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -2
- package/src/resources/extensions/gsd/auto-timers.ts +9 -2
- 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 -2429
- package/src/resources/extensions/gsd/auto.ts +126 -47
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +20 -2
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +218 -27
- package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +77 -1
- package/src/resources/extensions/gsd/codebase-generator.ts +7 -1
- package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +3 -3
- package/src/resources/extensions/gsd/compat/compat-marker.ts +47 -0
- package/src/resources/extensions/gsd/config-overlay.ts +7 -1
- package/src/resources/extensions/gsd/db/engine.ts +36 -0
- package/src/resources/extensions/gsd/db/queries.ts +9 -9
- package/src/resources/extensions/gsd/db/writers/cascades.ts +23 -1
- package/src/resources/extensions/gsd/db-adapter.ts +29 -3
- package/src/resources/extensions/gsd/docs/preferences-reference.md +3 -3
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +109 -10
- package/src/resources/extensions/gsd/flat-phase-migration.ts +34 -3
- 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 +53 -0
- package/src/resources/extensions/gsd/gsd-db.ts +33 -11
- package/src/resources/extensions/gsd/guided-flow.ts +26 -18
- package/src/resources/extensions/gsd/journal.ts +1 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +52 -91
- package/src/resources/extensions/gsd/md-importer.ts +93 -22
- package/src/resources/extensions/gsd/metrics.ts +2 -2
- package/src/resources/extensions/gsd/migration-auto-check.ts +32 -3
- package/src/resources/extensions/gsd/milestone-merge-transaction.ts +15 -0
- package/src/resources/extensions/gsd/milestone-settlement.ts +1 -1
- 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 +108 -51
- package/src/resources/extensions/gsd/post-unit-hooks.ts +32 -0
- package/src/resources/extensions/gsd/preferences-models.ts +74 -20
- package/src/resources/extensions/gsd/preferences-skills.ts +10 -16
- package/src/resources/extensions/gsd/preferences-types.ts +54 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +146 -9
- package/src/resources/extensions/gsd/preferences.ts +20 -0
- package/src/resources/extensions/gsd/prompts/system.md +6 -6
- package/src/resources/extensions/gsd/quick.ts +11 -3
- package/src/resources/extensions/gsd/reopen-reason.ts +109 -0
- package/src/resources/extensions/gsd/rule-registry.ts +111 -9
- package/src/resources/extensions/gsd/session-status-io.ts +34 -0
- package/src/resources/extensions/gsd/skill-discovery.ts +47 -23
- 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/state-reconciliation/drift/artifact-db.ts +1 -9
- package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +2 -22
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +14 -0
- 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-orchestrator.test.ts +41 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +57 -0
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/auto-timeout-recovery-supervisor-inflight-guard.test.ts +159 -0
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +2 -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/browser-daemon-auto-prep.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/compat-marker.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/db-adapter.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/db-writable-probe.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +174 -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 +71 -1
- package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +46 -1
- package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +72 -32
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +40 -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/paths.test.ts +88 -1
- 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/merge-closeout-consistency-gate.test.ts +1 -1
- 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/migration-auto-check.test.ts +91 -0
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +439 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +24 -0
- 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/parsers-legacy-importers.test.ts +0 -1
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +269 -0
- package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +1 -4
- package/src/resources/extensions/gsd/tests/preferences.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/read-uat-gate-verdict.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +49 -1
- package/src/resources/extensions/gsd/tests/reopen-reason.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +95 -1
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/sibling-model-fallbacks.test.ts +189 -0
- package/src/resources/extensions/gsd/tests/single-field-model-thinking.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +3 -5
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +32 -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/steer-worktree-path.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/supervisor-model-swap-inflight-guard.test.ts +181 -0
- package/src/resources/extensions/gsd/tests/supervisor-model-swap-thinking-clamp.test.ts +122 -0
- 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/tool-call-loop-guard.test.ts +196 -0
- package/src/resources/extensions/gsd/tests/uat-dispatch.test.ts +211 -0
- package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +26 -1
- package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +226 -2
- package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/worker-resume-wait.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +213 -2
- 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-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 +5 -2
- 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/tool-contract.ts +29 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +9 -5
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +19 -8
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +5 -0
- package/src/resources/extensions/gsd/tools/reopen-task.ts +28 -5
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +13 -9
- package/src/resources/extensions/gsd/types.ts +23 -4
- package/src/resources/extensions/gsd/uat-dispatch.ts +176 -0
- package/src/resources/extensions/gsd/unit-registry.ts +16 -2
- package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +1 -1
- package/src/resources/extensions/gsd/uok/audit-toggle.ts +32 -2
- package/src/resources/extensions/gsd/uok/audit.ts +2 -0
- package/src/resources/extensions/gsd/uok/gate-runner.ts +26 -36
- package/src/resources/extensions/gsd/uok/gitops.ts +21 -18
- package/src/resources/extensions/gsd/uok/kernel.ts +169 -48
- package/src/resources/extensions/gsd/uok/model-policy.ts +20 -17
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -1
- package/src/resources/extensions/gsd/workflow-event-ledger.ts +1 -1
- package/src/resources/extensions/gsd/workflow-logger.ts +1 -1
- package/src/resources/extensions/gsd/workflow-projections.ts +9 -24
- package/src/resources/extensions/gsd/workspace-git-preflight.ts +2 -2
- package/src/resources/extensions/gsd/workspace.ts +5 -21
- package/src/resources/extensions/gsd/worktree-command.ts +1 -1
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +19 -15
- package/src/resources/extensions/gsd/worktree-reentry.ts +2 -1
- package/src/resources/extensions/shared/gsd-browser-cli.ts +64 -7
- 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/{bCg3aYrFN1DKZr2dqgE7L → XFuMvz26Zb_lrrR-8dvkd}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{bCg3aYrFN1DKZr2dqgE7L → XFuMvz26Zb_lrrR-8dvkd}/_ssgManifest.js +0 -0
|
@@ -9,10 +9,19 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
resolveGsdBrowserCliAvailability,
|
|
11
11
|
resolveGsdBrowserDaemonStartInvocation,
|
|
12
|
+
resolveGsdBrowserDaemonStopInvocation,
|
|
12
13
|
} from "../shared/gsd-browser-cli.js";
|
|
13
14
|
import { uatTypeIncludesBrowser, type UatType } from "./uat-policy.js";
|
|
14
15
|
|
|
15
16
|
const DEFAULT_DAEMON_START_TIMEOUT_MS = 30_000;
|
|
17
|
+
const DEFAULT_DAEMON_STOP_TIMEOUT_MS = 15_000;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Project roots whose gsd-browser daemon this process warmed via
|
|
21
|
+
* {@link prepareBrowserDaemonForUat}. Teardown only stops daemons we actually
|
|
22
|
+
* started, so non-browser auto-mode sessions never spawn a stray `daemon stop`.
|
|
23
|
+
*/
|
|
24
|
+
const warmedDaemonProjectRoots = new Set<string>();
|
|
16
25
|
|
|
17
26
|
function isEnvDisabled(value: string | undefined): boolean {
|
|
18
27
|
if (!value) return false;
|
|
@@ -102,7 +111,74 @@ export function prepareBrowserDaemonForUat(ctx: BrowserDaemonWarmContext): strin
|
|
|
102
111
|
if (!shouldWarmBrowserDaemonForUat(ctx)) return null;
|
|
103
112
|
|
|
104
113
|
const result = ensureBrowserDaemonStarted(ctx.projectRoot, { env: ctx.env });
|
|
105
|
-
if (result.ok)
|
|
114
|
+
if (result.ok) {
|
|
115
|
+
warmedDaemonProjectRoots.add(resolve(ctx.projectRoot));
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
106
118
|
|
|
107
119
|
return `Cannot dispatch browser-backed run-uat: gsd-browser daemon failed to start (${result.error}). Ensure Chrome/Chromium is installed, run \`gsd-browser daemon health\` with the project session flags from .mcp.json, or set GSD_BROWSER_PATH to a Chromium binary.`;
|
|
108
120
|
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Best-effort stop of a gsd-browser session daemon warmed for browser UAT.
|
|
124
|
+
* Mirrors {@link ensureBrowserDaemonStarted}; returns the failure detail rather
|
|
125
|
+
* than throwing so teardown can stay non-fatal.
|
|
126
|
+
*/
|
|
127
|
+
export function stopBrowserDaemon(
|
|
128
|
+
projectRoot: string,
|
|
129
|
+
options: { env?: NodeJS.ProcessEnv; timeoutMs?: number } = {},
|
|
130
|
+
): { ok: true } | { ok: false; error: string } {
|
|
131
|
+
const env = options.env ?? process.env;
|
|
132
|
+
const availability = resolveGsdBrowserCliAvailability(env);
|
|
133
|
+
if (!availability.available) {
|
|
134
|
+
return { ok: false, error: availability.detail };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
let invocation: ReturnType<typeof resolveGsdBrowserDaemonStopInvocation>;
|
|
138
|
+
try {
|
|
139
|
+
invocation = resolveGsdBrowserDaemonStopInvocation(projectRoot, env);
|
|
140
|
+
} catch (error) {
|
|
141
|
+
return {
|
|
142
|
+
ok: false,
|
|
143
|
+
error: error instanceof Error ? error.message : String(error),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
execFileSync(invocation.command, invocation.args, {
|
|
149
|
+
cwd: invocation.cwd,
|
|
150
|
+
env: { ...process.env, ...env, ...(invocation.env ?? {}) },
|
|
151
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
152
|
+
timeout: options.timeoutMs ?? DEFAULT_DAEMON_STOP_TIMEOUT_MS,
|
|
153
|
+
encoding: "utf-8",
|
|
154
|
+
});
|
|
155
|
+
return { ok: true };
|
|
156
|
+
} catch (error) {
|
|
157
|
+
return {
|
|
158
|
+
ok: false,
|
|
159
|
+
error: error instanceof Error ? error.message : String(error),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Tear down every gsd-browser daemon this process warmed for browser UAT,
|
|
166
|
+
* clearing the tracked set. Called on auto-mode loop exit so the Chrome process
|
|
167
|
+
* does not survive session/task completion (mirrors the warm-up preflight).
|
|
168
|
+
* Best-effort: returns the project roots whose stop failed for logging.
|
|
169
|
+
*/
|
|
170
|
+
export function teardownWarmedBrowserDaemons(
|
|
171
|
+
options: { env?: NodeJS.ProcessEnv } = {},
|
|
172
|
+
): { projectRoot: string; error: string }[] {
|
|
173
|
+
if (warmedDaemonProjectRoots.size === 0) return [];
|
|
174
|
+
|
|
175
|
+
const failures: { projectRoot: string; error: string }[] = [];
|
|
176
|
+
for (const projectRoot of warmedDaemonProjectRoots) {
|
|
177
|
+
const result = stopBrowserDaemon(projectRoot, { env: options.env });
|
|
178
|
+
if (!result.ok) {
|
|
179
|
+
failures.push({ projectRoot, error: result.error });
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
warmedDaemonProjectRoots.clear();
|
|
183
|
+
return failures;
|
|
184
|
+
}
|
|
@@ -675,10 +675,16 @@ export function ensureCodebaseMapFresh(
|
|
|
675
675
|
|
|
676
676
|
const metadata = parseCodebaseMapMetadata(existing);
|
|
677
677
|
const existingDescriptions = parseCodebaseMap(existing);
|
|
678
|
+
// Compare against the truncated count: when the repository has more tracked
|
|
679
|
+
// files than maxFiles, the map only lists the first maxFiles entries, so a
|
|
680
|
+
// stored fileCount above the cap (e.g. from an older map that recorded the
|
|
681
|
+
// full count) still matches the current truncated listing. Comparing raw
|
|
682
|
+
// values would flag "file-count-changed" on every turn, rewriting the
|
|
683
|
+
// timestamp and invalidating the provider KV cache prefix.
|
|
678
684
|
const staleReason =
|
|
679
685
|
!metadata ? "missing-metadata"
|
|
680
686
|
: metadata.fingerprint !== fingerprint ? "files-changed"
|
|
681
|
-
: metadata.fileCount !== listed.files.length ? "file-count-changed"
|
|
687
|
+
: Math.min(metadata.fileCount, resolved.maxFiles) !== listed.files.length ? "file-count-changed"
|
|
682
688
|
: metadata.truncated !== listed.truncated ? "truncation-changed"
|
|
683
689
|
: undefined;
|
|
684
690
|
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
filterDoctorIssues,
|
|
26
26
|
} from "./doctor.js";
|
|
27
27
|
import { isAutoActive, checkRemoteAutoSession } from "./auto.js";
|
|
28
|
-
import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
28
|
+
import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
|
|
29
29
|
import { currentDirectoryRoot, projectRoot } from "./commands/context.js";
|
|
30
30
|
import { loadPrompt } from "./prompt-loader.js";
|
|
31
31
|
import { buildClaudeRuntimeFloorAdvisory } from "../../shared/claude-runtime-floor.js";
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
} from "./workflow-templates.js";
|
|
24
24
|
import { loadPrompt } from "./prompt-loader.js";
|
|
25
25
|
import { gsdRoot } from "./paths.js";
|
|
26
|
-
import { createGitService, runGit } from "./git-service.js";
|
|
26
|
+
import { createGitService, runGit, taskBranchArgs } from "./git-service.js";
|
|
27
27
|
import { isAutoActive, isAutoPaused } from "./auto.js";
|
|
28
28
|
import { getErrorMessage } from "./error-utils.js";
|
|
29
29
|
import { resolvePlugin, type WorkflowPlugin } from "./workflow-plugins.js";
|
|
@@ -464,7 +464,7 @@ export async function handleStart(
|
|
|
464
464
|
try {
|
|
465
465
|
git.autoCommit("workflow-template", templateId, []);
|
|
466
466
|
} catch { /* nothing to commit */ }
|
|
467
|
-
runGit(basePath,
|
|
467
|
+
runGit(basePath, taskBranchArgs(basePath, branchName, current, git.getMainBranch()));
|
|
468
468
|
branchCreated = true;
|
|
469
469
|
}
|
|
470
470
|
} catch (err) {
|
|
@@ -636,7 +636,7 @@ export function dispatchMarkdownPhasePlugin(
|
|
|
636
636
|
const current = git.getCurrentBranch();
|
|
637
637
|
if (current !== branchName) {
|
|
638
638
|
try { git.autoCommit("workflow-template", templateId, []); } catch { /* nothing to commit */ }
|
|
639
|
-
runGit(basePath,
|
|
639
|
+
runGit(basePath, taskBranchArgs(basePath, branchName, current, git.getMainBranch()));
|
|
640
640
|
branchCreated = true;
|
|
641
641
|
}
|
|
642
642
|
} catch (err) {
|
|
@@ -148,6 +148,53 @@ export function writeCompatMarker(basePath: string, marker: CompatMarker): void
|
|
|
148
148
|
renameSync(tmp, path);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
/**
|
|
152
|
+
* Remove projection entries whose backing file no longer exists on disk.
|
|
153
|
+
*
|
|
154
|
+
* gsd-pi never deletes marker entries on its own: both drift detectors skip
|
|
155
|
+
* files missing from disk (`if (!existsSync(abs)) continue;`) and the write-time
|
|
156
|
+
* flush only ever adds or refreshes entries. So when a phase directory is
|
|
157
|
+
* renamed or removed (e.g. `phases/29-new-milestone-m029/` →
|
|
158
|
+
* `phases/29-frontend-code-debt-cleanup/`), the old projection paths linger in
|
|
159
|
+
* `.compat.json` forever as phantom entries pointing at directories that no
|
|
160
|
+
* longer exist (#1257). They never reconcile, and `.compat.json` keeps drifting
|
|
161
|
+
* from disk reality so `git status` stops being a reliable proxy for "did the
|
|
162
|
+
* engine touch my plans?".
|
|
163
|
+
*
|
|
164
|
+
* This prunes those orphaned entries across the `.gsd/` projections and the
|
|
165
|
+
* `.planning/` projections/passthrough maps. It is safe: a missing-file entry is
|
|
166
|
+
* inert (every detector already ignores it), and if the file is later
|
|
167
|
+
* re-projected the write-time flush / unseeded-file detection re-seeds an
|
|
168
|
+
* accurate baseline.
|
|
169
|
+
*
|
|
170
|
+
* Returns the number of entries removed; when nothing is orphaned the marker is
|
|
171
|
+
* left untouched (no needless write, no `lastProjectedAt` churn).
|
|
172
|
+
*/
|
|
173
|
+
export function pruneOrphanedProjectionEntries(basePath: string): number {
|
|
174
|
+
if (!existsSync(compatMarkerPath(basePath))) return 0;
|
|
175
|
+
|
|
176
|
+
const marker = readCompatMarker(basePath);
|
|
177
|
+
let removed = 0;
|
|
178
|
+
|
|
179
|
+
const pruneMap = (map: Record<string, ProjectionEntry>, root: string): void => {
|
|
180
|
+
for (const relPath of Object.keys(map)) {
|
|
181
|
+
if (!existsSync(join(basePath, root, relPath))) {
|
|
182
|
+
delete map[relPath];
|
|
183
|
+
removed++;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
pruneMap(marker.projections, ".gsd");
|
|
189
|
+
if (marker.planning) {
|
|
190
|
+
pruneMap(marker.planning.projections, ".planning");
|
|
191
|
+
pruneMap(marker.planning.passthrough, ".planning");
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (removed > 0) writeCompatMarker(basePath, marker);
|
|
195
|
+
return removed;
|
|
196
|
+
}
|
|
197
|
+
|
|
151
198
|
function quarantine(basePath: string, raw: string): void {
|
|
152
199
|
const path = compatMarkerPath(basePath);
|
|
153
200
|
const badPath = `${path}.bad-${Date.now()}`;
|
|
@@ -150,7 +150,13 @@ function collectConfigSections(options?: CollectConfigOptions): ConfigSection[]
|
|
|
150
150
|
if (prefs?.auto_supervisor) {
|
|
151
151
|
const sup = resolveAutoSupervisorConfig();
|
|
152
152
|
const supRows: ConfigSection["rows"] = [];
|
|
153
|
-
if (sup.model)
|
|
153
|
+
if (sup.model) {
|
|
154
|
+
let modelVal = sup.model;
|
|
155
|
+
if (sup.modelFallbacks && sup.modelFallbacks.length > 0) {
|
|
156
|
+
modelVal += ` \u2192 ${sup.modelFallbacks.join(" \u2192 ")}`;
|
|
157
|
+
}
|
|
158
|
+
supRows.push({ label: "Model", value: modelVal });
|
|
159
|
+
}
|
|
154
160
|
supRows.push({ label: "Soft timeout", value: `${sup.soft_timeout_minutes}m` });
|
|
155
161
|
supRows.push({ label: "Idle timeout", value: `${sup.idle_timeout_minutes}m` });
|
|
156
162
|
supRows.push({ label: "Stalled tool timeout", value: `${sup.stalled_tool_timeout_minutes}m` });
|
|
@@ -860,3 +860,39 @@ export function getDb(): DbAdapter {
|
|
|
860
860
|
export function getDbOrNull(): DbAdapter | null {
|
|
861
861
|
return currentDb;
|
|
862
862
|
}
|
|
863
|
+
|
|
864
|
+
export interface DbWritableProbeResult {
|
|
865
|
+
ok: boolean;
|
|
866
|
+
detail?: string;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* Confirm the open handle can actually write, not just that it opened.
|
|
871
|
+
*
|
|
872
|
+
* A schema-current database performs zero writes during open, so a handle that
|
|
873
|
+
* opened successfully but is not writable (read-only file, WAL/SHM permission
|
|
874
|
+
* mismatch, or a stale/moved handle → SQLITE_READONLY_DBMOVED) otherwise passes
|
|
875
|
+
* the open-only availability check and only fails much later at the first real
|
|
876
|
+
* write. The probe forces a genuine page write by re-writing the current
|
|
877
|
+
* `PRAGMA user_version` value back inside an IMMEDIATE transaction: a bare
|
|
878
|
+
* `BEGIN IMMEDIATE; ROLLBACK` is not sufficient because a moved handle does not
|
|
879
|
+
* fail until a page is actually dirtied. The value is unchanged, so the probe
|
|
880
|
+
* is idempotent, and the transaction is rolled back so nothing persists.
|
|
881
|
+
*/
|
|
882
|
+
export function probeDbWritable(): DbWritableProbeResult {
|
|
883
|
+
const db = currentDb;
|
|
884
|
+
if (!db) return { ok: false, detail: "No database is open." };
|
|
885
|
+
try {
|
|
886
|
+
const row = db.prepare("PRAGMA user_version").get() as { user_version?: number } | undefined;
|
|
887
|
+
const current = typeof row?.user_version === "number" ? row.user_version : 0;
|
|
888
|
+
db.exec("BEGIN IMMEDIATE");
|
|
889
|
+
try {
|
|
890
|
+
db.exec(`PRAGMA user_version = ${current}`);
|
|
891
|
+
} finally {
|
|
892
|
+
db.exec("ROLLBACK");
|
|
893
|
+
}
|
|
894
|
+
return { ok: true };
|
|
895
|
+
} catch (err) {
|
|
896
|
+
return { ok: false, detail: (err as Error).message };
|
|
897
|
+
}
|
|
898
|
+
}
|
|
@@ -281,7 +281,7 @@ export function getMilestone(id: string): MilestoneRow | null {
|
|
|
281
281
|
export function getActiveMilestoneFromDb(): MilestoneRow | null {
|
|
282
282
|
if (!getDbOrNull()!) return null;
|
|
283
283
|
const row = getDbOrNull()!.prepare(
|
|
284
|
-
|
|
284
|
+
`SELECT * FROM milestones WHERE status NOT IN (${TERMINAL_STATUS_SQL}, 'parked') ORDER BY id LIMIT 1`,
|
|
285
285
|
).get();
|
|
286
286
|
if (!row) return null;
|
|
287
287
|
return rowToMilestone(row);
|
|
@@ -295,11 +295,11 @@ export function getActiveSliceFromDb(milestoneId: string): SliceRow | null {
|
|
|
295
295
|
const row = getDbOrNull()!.prepare(
|
|
296
296
|
`SELECT s.* FROM slices s
|
|
297
297
|
WHERE s.milestone_id = :mid
|
|
298
|
-
AND s.status NOT IN (
|
|
298
|
+
AND s.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
299
299
|
AND NOT EXISTS (
|
|
300
300
|
SELECT 1 FROM json_each(s.depends) AS dep
|
|
301
301
|
WHERE dep.value NOT IN (
|
|
302
|
-
SELECT id FROM slices WHERE milestone_id = :mid AND status IN (
|
|
302
|
+
SELECT id FROM slices WHERE milestone_id = :mid AND status IN (${TERMINAL_STATUS_SQL})
|
|
303
303
|
)
|
|
304
304
|
)
|
|
305
305
|
ORDER BY s.sequence, s.id
|
|
@@ -312,7 +312,7 @@ export function getActiveSliceFromDb(milestoneId: string): SliceRow | null {
|
|
|
312
312
|
export function getActiveTaskFromDb(milestoneId: string, sliceId: string): TaskRow | null {
|
|
313
313
|
if (!getDbOrNull()!) return null;
|
|
314
314
|
const row = getDbOrNull()!.prepare(
|
|
315
|
-
|
|
315
|
+
`SELECT * FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND status NOT IN (${TERMINAL_STATUS_SQL}) ORDER BY sequence, id LIMIT 1`,
|
|
316
316
|
).get({ ":mid": milestoneId, ":sid": sliceId });
|
|
317
317
|
if (!row) return null;
|
|
318
318
|
return rowToTask(row);
|
|
@@ -339,7 +339,7 @@ export function getParallelMonitorSliceProgress(milestoneId: string): ParallelMo
|
|
|
339
339
|
s.id AS id,
|
|
340
340
|
s.status AS status,
|
|
341
341
|
COUNT(t.id) AS total,
|
|
342
|
-
COALESCE(SUM(CASE WHEN t.status
|
|
342
|
+
COALESCE(SUM(CASE WHEN t.status IN (${TERMINAL_STATUS_SQL}) THEN 1 ELSE 0 END), 0) AS done
|
|
343
343
|
FROM slices s
|
|
344
344
|
LEFT JOIN tasks t ON s.milestone_id=t.milestone_id AND s.id=t.slice_id
|
|
345
345
|
WHERE s.milestone_id=:mid
|
|
@@ -518,7 +518,7 @@ export function getSliceScopedArtifacts(milestoneId: string, sliceId: string): A
|
|
|
518
518
|
export function getActiveMilestoneIdFromDb(): IdStatusSummary | null {
|
|
519
519
|
if (!getDbOrNull()!) return null;
|
|
520
520
|
const row = getDbOrNull()!.prepare(
|
|
521
|
-
|
|
521
|
+
`SELECT id, status FROM milestones WHERE status NOT IN (${TERMINAL_STATUS_SQL}, 'parked') ORDER BY id LIMIT 1`,
|
|
522
522
|
).get();
|
|
523
523
|
if (!row) return null;
|
|
524
524
|
return rowToIdStatusSummary(row);
|
|
@@ -536,7 +536,7 @@ export function getSliceStatusSummary(milestoneId: string): IdStatusSummary[] {
|
|
|
536
536
|
export function getActiveTaskIdFromDb(milestoneId: string, sliceId: string): ActiveTaskSummary | null {
|
|
537
537
|
if (!getDbOrNull()!) return null;
|
|
538
538
|
const row = getDbOrNull()!.prepare(
|
|
539
|
-
|
|
539
|
+
`SELECT id, status, title FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND status NOT IN (${TERMINAL_STATUS_SQL}) ORDER BY sequence, id LIMIT 1`,
|
|
540
540
|
).get({ ":mid": milestoneId, ":sid": sliceId });
|
|
541
541
|
if (!row) return null;
|
|
542
542
|
return rowToActiveTaskSummary(row);
|
|
@@ -548,8 +548,8 @@ export function getSliceTaskCounts(milestoneId: string, sliceId: string): TaskSt
|
|
|
548
548
|
const row = getDbOrNull()!.prepare(
|
|
549
549
|
`SELECT
|
|
550
550
|
COUNT(*) as total,
|
|
551
|
-
SUM(CASE WHEN status IN (
|
|
552
|
-
SUM(CASE WHEN status NOT IN (
|
|
551
|
+
SUM(CASE WHEN status IN (${TERMINAL_STATUS_SQL}) THEN 1 ELSE 0 END) as done,
|
|
552
|
+
SUM(CASE WHEN status NOT IN (${TERMINAL_STATUS_SQL}) THEN 1 ELSE 0 END) as pending
|
|
553
553
|
FROM tasks WHERE milestone_id = :mid AND slice_id = :sid`,
|
|
554
554
|
).get({ ":mid": milestoneId, ":sid": sliceId });
|
|
555
555
|
return rowToTaskStatusCounts(row);
|
|
@@ -38,6 +38,17 @@ export type ReopenSliceOutcome =
|
|
|
38
38
|
* completion timestamps cleared, in one commit. Folds the hand-rolled
|
|
39
39
|
* transaction-plus-cascade previously in tools/reopen-slice.ts. Guards run
|
|
40
40
|
* inside the transaction (TOCTOU-safe).
|
|
41
|
+
*
|
|
42
|
+
* A closed slice is always reopenable. An open slice is only reopenable when it
|
|
43
|
+
* carries a completed-task state desync (#1205): a UAT→planning fallback can
|
|
44
|
+
* leave the slice "pending" while *all* its tasks stay "complete", which
|
|
45
|
+
* deadlocks every recovery path (plan-slice/replan-slice/complete-task all
|
|
46
|
+
* reject the still-closed tasks, and slice_reopen historically rejected the
|
|
47
|
+
* still-open slice). Resetting those tasks to pending gives the planner the
|
|
48
|
+
* clean slate it needs. An open slice that still has any unfinished
|
|
49
|
+
* (pending/in-progress) task is a normal in-flight slice, not the desync, and
|
|
50
|
+
* stays rejected as "slice-not-complete" so a full reset can't wipe its
|
|
51
|
+
* legitimate progress.
|
|
41
52
|
*/
|
|
42
53
|
export function reopenSliceCascade(milestoneId: string, sliceId: string): ReopenSliceOutcome {
|
|
43
54
|
requireDb();
|
|
@@ -48,9 +59,20 @@ export function reopenSliceCascade(milestoneId: string, sliceId: string): Reopen
|
|
|
48
59
|
if (isClosedStatus(milestone.status)) { outcome = { ok: false, reason: "milestone-closed", status: milestone.status }; return; }
|
|
49
60
|
const slice = getSlice(milestoneId, sliceId);
|
|
50
61
|
if (!slice) { outcome = { ok: false, reason: "slice-not-found" }; return; }
|
|
51
|
-
if (!isClosedStatus(slice.status)) { outcome = { ok: false, reason: "slice-not-complete", status: slice.status }; return; }
|
|
52
62
|
|
|
53
63
|
const tasks = getSliceTasks(milestoneId, sliceId);
|
|
64
|
+
// A closed slice is always reopenable. An open slice is only the #1205
|
|
65
|
+
// desync when EVERY task is already closed (a UAT→planning fallback left the
|
|
66
|
+
// slice open with all tasks still "complete"). Requiring *all* tasks closed
|
|
67
|
+
// (not merely one) means a normal in-flight slice — which keeps at least one
|
|
68
|
+
// pending/in-progress task — is rejected, so a full reset can't wipe its
|
|
69
|
+
// legitimate progress.
|
|
70
|
+
const allTasksClosed = tasks.length > 0 && tasks.every((t) => isClosedStatus(t.status));
|
|
71
|
+
if (!isClosedStatus(slice.status) && !allTasksClosed) {
|
|
72
|
+
outcome = { ok: false, reason: "slice-not-complete", status: slice.status };
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
54
76
|
getDbOrNull()!.prepare(
|
|
55
77
|
`UPDATE slices SET status = 'in_progress', completed_at = NULL WHERE milestone_id = :mid AND id = :sid`,
|
|
56
78
|
).run({ ":mid": milestoneId, ":sid": sliceId });
|
|
@@ -25,6 +25,32 @@ export function normalizeDbRows(rows: unknown[]): Record<string, unknown>[] {
|
|
|
25
25
|
return rows.map((row) => normalizeDbRow(row)!);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
29
|
+
if (value === null || typeof value !== "object") return false;
|
|
30
|
+
const proto = Object.getPrototypeOf(value);
|
|
31
|
+
return proto === Object.prototype || proto === null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// node:sqlite accepts binding-object keys with or without the ':'/'@'/'$'
|
|
35
|
+
// prefix, but better-sqlite3 accepts only bare keys — strip the prefix so
|
|
36
|
+
// call sites written against node:sqlite also work on the fallback provider.
|
|
37
|
+
function normalizeBindParams(params: unknown[]): unknown[] {
|
|
38
|
+
return params.map((param) => {
|
|
39
|
+
if (!isPlainObject(param)) return param;
|
|
40
|
+
let changed = false;
|
|
41
|
+
const normalized: Record<string, unknown> = {};
|
|
42
|
+
for (const [key, value] of Object.entries(param)) {
|
|
43
|
+
if (key.length > 1 && (key[0] === ":" || key[0] === "@" || key[0] === "$")) {
|
|
44
|
+
normalized[key.slice(1)] = value;
|
|
45
|
+
changed = true;
|
|
46
|
+
} else {
|
|
47
|
+
normalized[key] = value;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return changed ? normalized : param;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
28
54
|
export function createDbAdapter(rawDb: unknown): DbAdapter {
|
|
29
55
|
const db = rawDb as {
|
|
30
56
|
exec(sql: string): void;
|
|
@@ -45,13 +71,13 @@ export function createDbAdapter(rawDb: unknown): DbAdapter {
|
|
|
45
71
|
}): DbStatement {
|
|
46
72
|
return {
|
|
47
73
|
run(...params: unknown[]): unknown {
|
|
48
|
-
return raw.run(...params);
|
|
74
|
+
return raw.run(...normalizeBindParams(params));
|
|
49
75
|
},
|
|
50
76
|
get(...params: unknown[]): Record<string, unknown> | undefined {
|
|
51
|
-
return normalizeDbRow(raw.get(...params));
|
|
77
|
+
return normalizeDbRow(raw.get(...normalizeBindParams(params)));
|
|
52
78
|
},
|
|
53
79
|
all(...params: unknown[]): Record<string, unknown>[] {
|
|
54
|
-
return normalizeDbRows(raw.all(...params));
|
|
80
|
+
return normalizeDbRows(raw.all(...normalizeBindParams(params)));
|
|
55
81
|
},
|
|
56
82
|
};
|
|
57
83
|
}
|
|
@@ -138,7 +138,7 @@ Diagnostics record the file path, scope (global/project), severity (error/warnin
|
|
|
138
138
|
- `off` — skill discovery is disabled entirely.
|
|
139
139
|
|
|
140
140
|
- `auto_supervisor`: configures the auto-mode supervisor that monitors agent progress and enforces timeouts. Keys:
|
|
141
|
-
- `model`: model
|
|
141
|
+
- `model`: model to use for the supervisor process (defaults to the currently active model). Accepts a bare model ID **or** the same `{ model, provider?, fallbacks? }` object form as `models.<phase>`, so it honors `fallbacks[]` on a transient provider trip.
|
|
142
142
|
- `soft_timeout_minutes`: minutes before the supervisor issues a soft warning (default: 20).
|
|
143
143
|
- `idle_timeout_minutes`: minutes of inactivity before the supervisor intervenes (default: 10).
|
|
144
144
|
- `hard_timeout_minutes`: minutes before the supervisor forces termination (default: 30).
|
|
@@ -228,7 +228,7 @@ In `"parent"` mode, slice/task `targetRepositories` default to the declared chil
|
|
|
228
228
|
- `enabled`: boolean — set `false` to force sequential task execution. Default: `true`.
|
|
229
229
|
- `max_parallel`: number — maximum tasks to dispatch in one batch, range `1`-`8`. Default: `2`.
|
|
230
230
|
- `isolation_mode`: `"same-tree"` — currently the only supported value.
|
|
231
|
-
- `subagent_model`:
|
|
231
|
+
- `subagent_model`: optional model override for reactive task subagents. Accepts a bare model ID **or** the `{ model, provider?, fallbacks? }` object form (parity with `models.<phase>`). Falls back to the `models.subagent` routing when omitted.
|
|
232
232
|
|
|
233
233
|
- `remote_questions`: route interactive questions to Slack/Discord for headless auto-mode. Keys:
|
|
234
234
|
- `channel`: `"slack"` or `"discord"` — channel type.
|
|
@@ -326,7 +326,7 @@ In `"parent"` mode, slice/task `targetRepositories` default to the declared chil
|
|
|
326
326
|
- `after`: string[] — unit types that trigger this hook (e.g., `["execute-task"]`).
|
|
327
327
|
- `prompt`: string — prompt sent to the LLM. Supports `{milestoneId}`, `{sliceId}`, `{taskId}` substitutions.
|
|
328
328
|
- `max_cycles`: number — max times this hook fires per trigger (default: 1, max: 10).
|
|
329
|
-
- `model`:
|
|
329
|
+
- `model`: optional model override. Accepts a bare model ID **or** the same `{ model, provider?, fallbacks? }` object form as `models.<phase>`. With `fallbacks[]`, a transient trip of the primary provider falls back to the next entry instead of hard-failing the hook — which, for a `blocking` hook with `on_block: { action: pause }`, would otherwise pause the whole run.
|
|
330
330
|
- `artifact`: string — expected output file name (relative to task/slice dir). Hook is skipped if file already exists (idempotent).
|
|
331
331
|
- `criticality`: `"advisory"` or `"blocking"` — advisory preserves current best-effort behavior; blocking requires clean hook completion plus a valid outcome verdict before auto-mode advances. Default: `"advisory"`.
|
|
332
332
|
- `retry_on`: string — if this file is produced instead of the artifact, re-run the trigger unit then re-run hooks.
|
|
@@ -14,7 +14,15 @@ import {
|
|
|
14
14
|
} from "./gsd-db.js";
|
|
15
15
|
import { MEMORIES_FTS_REBUILT_KEY } from "./db-memory-fts-schema.js";
|
|
16
16
|
import { isAfter, latestExplicitReopenAt } from "./milestone-reopen-events.js";
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
buildTaskFileName,
|
|
19
|
+
gsdProjectionRoot,
|
|
20
|
+
gsdRoot,
|
|
21
|
+
resolveGsdPathContract,
|
|
22
|
+
resolveMilestoneFile,
|
|
23
|
+
resolveMilestonePath,
|
|
24
|
+
resolveSliceFile,
|
|
25
|
+
} from "./paths.js";
|
|
18
26
|
import { deriveState } from "./state.js";
|
|
19
27
|
import { isClosedStatus } from "./status-guards.js";
|
|
20
28
|
import { workflowEventLogPath } from "./workflow-event-ledger.js";
|
|
@@ -23,6 +31,7 @@ import { flushWorkflowProjections } from "./projection-flush.js";
|
|
|
23
31
|
import { parseRoadmapSlices } from "./roadmap-slices.js";
|
|
24
32
|
import { parsePlan } from "./parsers-legacy.js";
|
|
25
33
|
import { parseSummary } from "./files.js";
|
|
34
|
+
import { LAYOUT_SEGMENTS } from "./layout-policy.js";
|
|
26
35
|
|
|
27
36
|
const USER_AUTHORED_ARTIFACT_TYPES = new Set(["CONTEXT", "RESEARCH"]);
|
|
28
37
|
|
|
@@ -160,11 +169,11 @@ function isClearedByMilestoneShellProjectionFlush(
|
|
|
160
169
|
return issue.file === relativeFile(basePath, roadmapPath);
|
|
161
170
|
}
|
|
162
171
|
|
|
163
|
-
function artifactExistsOnDisk(basePath: string, artifactPath: string): boolean {
|
|
164
|
-
return resolveArtifactDiskPath(basePath, artifactPath) !== null;
|
|
172
|
+
function artifactExistsOnDisk(basePath: string, artifactPath: string, row?: ArtifactRow): boolean {
|
|
173
|
+
return resolveArtifactDiskPath(basePath, artifactPath, row) !== null;
|
|
165
174
|
}
|
|
166
175
|
|
|
167
|
-
function
|
|
176
|
+
function resolveLiteralArtifactDiskPath(basePath: string, artifactPath: string): string | null {
|
|
168
177
|
const relativeArtifactPath = artifactPathRelativeToGsd(artifactPath);
|
|
169
178
|
if (isAbsolute(relativeArtifactPath)) {
|
|
170
179
|
return existsSync(relativeArtifactPath) ? relativeArtifactPath : null;
|
|
@@ -176,6 +185,50 @@ function resolveArtifactDiskPath(basePath: string, artifactPath: string): string
|
|
|
176
185
|
return null;
|
|
177
186
|
}
|
|
178
187
|
|
|
188
|
+
function relativeToGsdRoot(basePath: string, diskPath: string): string | null {
|
|
189
|
+
for (const root of [gsdProjectionRoot(basePath), gsdRoot(basePath)]) {
|
|
190
|
+
if (!isPathInside(root, diskPath)) continue;
|
|
191
|
+
return relative(root, diskPath).split("\\").join("/");
|
|
192
|
+
}
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function isFlatPhaseDiskPath(basePath: string, diskPath: string): boolean {
|
|
197
|
+
return relativeToGsdRoot(basePath, diskPath)?.startsWith(`${LAYOUT_SEGMENTS.level1}/`) ?? false;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function hasFlatPhaseLayout(basePath: string): boolean {
|
|
201
|
+
return existsSync(join(gsdProjectionRoot(basePath), LAYOUT_SEGMENTS.level1));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function resolveFlatPhaseArtifactDiskPath(basePath: string, row: ArtifactRow): string | null {
|
|
205
|
+
if (!hasFlatPhaseLayout(basePath)) return null;
|
|
206
|
+
if (!row.milestone_id) return null;
|
|
207
|
+
const artifactType = normalizedArtifactType(row.artifact_type);
|
|
208
|
+
if (!artifactType) return null;
|
|
209
|
+
|
|
210
|
+
if (row.slice_id && row.task_id) {
|
|
211
|
+
const phaseDir = resolveMilestonePath(basePath, row.milestone_id);
|
|
212
|
+
if (!phaseDir || !isFlatPhaseDiskPath(basePath, phaseDir)) return null;
|
|
213
|
+
const candidate = join(phaseDir, buildTaskFileName(row.task_id, artifactType));
|
|
214
|
+
return existsSync(candidate) ? candidate : null;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const candidate = row.slice_id
|
|
218
|
+
? resolveSliceFile(basePath, row.milestone_id, row.slice_id, artifactType)
|
|
219
|
+
: resolveMilestoneFile(basePath, row.milestone_id, artifactType);
|
|
220
|
+
|
|
221
|
+
return candidate && isFlatPhaseDiskPath(basePath, candidate) ? candidate : null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function resolveArtifactDiskPath(basePath: string, artifactPath: string, row?: ArtifactRow): string | null {
|
|
225
|
+
if (row && isMilestonesArtifactPath(row.path)) {
|
|
226
|
+
const flatPath = resolveFlatPhaseArtifactDiskPath(basePath, row);
|
|
227
|
+
if (flatPath) return flatPath;
|
|
228
|
+
}
|
|
229
|
+
return resolveLiteralArtifactDiskPath(basePath, artifactPath);
|
|
230
|
+
}
|
|
231
|
+
|
|
179
232
|
function taskExistsInPlan(basePath: string, milestoneId: string, sliceId: string, taskId: string): boolean {
|
|
180
233
|
const planPath = resolveSliceFile(basePath, milestoneId, sliceId, "PLAN");
|
|
181
234
|
if (!planPath || !existsSync(planPath)) return false;
|
|
@@ -228,7 +281,7 @@ function readTaskCompletionEvidenceFromSummary(
|
|
|
228
281
|
if (!row.task_status && Number(row.task_count) > 0 && !taskExistsInPlan(basePath, row.milestone_id, row.slice_id, row.task_id)) {
|
|
229
282
|
return null;
|
|
230
283
|
}
|
|
231
|
-
const diskPath = resolveArtifactDiskPath(basePath, row.path);
|
|
284
|
+
const diskPath = resolveArtifactDiskPath(basePath, row.path, { ...row, artifact_type: "SUMMARY" });
|
|
232
285
|
if (!diskPath) return null;
|
|
233
286
|
try {
|
|
234
287
|
const fullSummaryMd = readFileSync(diskPath, "utf-8");
|
|
@@ -262,6 +315,7 @@ function repairTaskArtifactDbStatusDivergence(
|
|
|
262
315
|
basePath: string,
|
|
263
316
|
row: {
|
|
264
317
|
path: string;
|
|
318
|
+
artifact_type?: string;
|
|
265
319
|
milestone_id: string;
|
|
266
320
|
slice_id: string | null;
|
|
267
321
|
task_id: string | null;
|
|
@@ -353,6 +407,49 @@ function hasPresentMilestonesReplacement(basePath: string, row: ArtifactRow, art
|
|
|
353
407
|
);
|
|
354
408
|
}
|
|
355
409
|
|
|
410
|
+
function hasPresentFlatPhaseReplacement(basePath: string, row: ArtifactRow, artifactRows: ArtifactRow[]): boolean {
|
|
411
|
+
if (resolveFlatPhaseArtifactDiskPath(basePath, row)) return true;
|
|
412
|
+
|
|
413
|
+
return artifactRows.some(
|
|
414
|
+
(other) =>
|
|
415
|
+
other.path !== row.path &&
|
|
416
|
+
!isMilestonesArtifactPath(other.path) &&
|
|
417
|
+
sameArtifactIdentity(row, other) &&
|
|
418
|
+
artifactExistsOnDisk(basePath, other.path, other),
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function hasNoFlatPhaseFileEquivalent(row: ArtifactRow): boolean {
|
|
423
|
+
const artifactType = normalizedArtifactType(row.artifact_type);
|
|
424
|
+
if (row.slice_id && row.task_id) {
|
|
425
|
+
return artifactType === "PLAN" || artifactType === "SUMMARY";
|
|
426
|
+
}
|
|
427
|
+
return Boolean(row.slice_id && !row.task_id && artifactType === "SUMMARY");
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function staleMilestonesArtifactRowFixable(basePath: string, row: ArtifactRow, artifactRows: ArtifactRow[]): boolean {
|
|
431
|
+
if (!isMilestonesArtifactPath(row.path)) return false;
|
|
432
|
+
if (!hasFlatPhaseLayout(basePath)) return false;
|
|
433
|
+
if (hasPresentFlatPhaseReplacement(basePath, row, artifactRows)) return true;
|
|
434
|
+
return hasNoFlatPhaseFileEquivalent(row) && !resolveLiteralArtifactDiskPath(basePath, row.path);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function stalePhasesArtifactRowFixable(basePath: string, row: ArtifactRow, artifactRows: ArtifactRow[]): boolean {
|
|
438
|
+
const issuePath = artifactPathRelativeToGsd(row.path);
|
|
439
|
+
return issuePath.startsWith(`${LAYOUT_SEGMENTS.level1}/`) && hasPresentMilestonesReplacement(basePath, row, artifactRows);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
function staleArtifactRowFixable(basePath: string, row: ArtifactRow, artifactRows: ArtifactRow[]): boolean {
|
|
443
|
+
return staleMilestonesArtifactRowFixable(basePath, row, artifactRows) ||
|
|
444
|
+
stalePhasesArtifactRowFixable(basePath, row, artifactRows);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function staleArtifactPruneMessage(row: ArtifactRow): string {
|
|
448
|
+
return isMilestonesArtifactPath(row.path)
|
|
449
|
+
? `pruned stale legacy artifact row ${row.path}`
|
|
450
|
+
: `pruned stale flat-phase artifact row ${row.path}`;
|
|
451
|
+
}
|
|
452
|
+
|
|
356
453
|
export async function checkEngineHealth(
|
|
357
454
|
basePath: string,
|
|
358
455
|
issues: DoctorIssue[],
|
|
@@ -579,17 +676,18 @@ export async function checkEngineHealth(
|
|
|
579
676
|
.all() as ArtifactRow[];
|
|
580
677
|
|
|
581
678
|
for (const row of artifactRows) {
|
|
582
|
-
if (artifactExistsOnDisk(basePath, row.path)) continue;
|
|
583
679
|
const unitId = artifactUnitId(row);
|
|
584
680
|
const issuePath = artifactPathRelativeToGsd(row.path);
|
|
585
|
-
if (
|
|
681
|
+
if (artifactExistsOnDisk(basePath, row.path)) continue;
|
|
682
|
+
if (options?.repair && staleArtifactRowFixable(basePath, row, artifactRows)) {
|
|
586
683
|
// Route the write through the Single Writer owner (gsd-db.ts) instead
|
|
587
684
|
// of issuing raw DELETE SQL here — doctor is a read-only consumer and
|
|
588
685
|
// the single-writer invariant forbids write SQL outside the allowlist.
|
|
589
686
|
deleteArtifactByPath(row.path);
|
|
590
|
-
fixesApplied.push(
|
|
687
|
+
fixesApplied.push(staleArtifactPruneMessage(row));
|
|
591
688
|
continue;
|
|
592
689
|
}
|
|
690
|
+
if (artifactExistsOnDisk(basePath, row.path, row)) continue;
|
|
593
691
|
if (isUserAuthoredArtifactType(row.artifact_type)) {
|
|
594
692
|
const artifactType = normalizedArtifactType(row.artifact_type);
|
|
595
693
|
missingUserContentArtifacts.push({ path: issuePath, artifactType });
|
|
@@ -611,7 +709,7 @@ export async function checkEngineHealth(
|
|
|
611
709
|
unitId,
|
|
612
710
|
message: `Artifact ${issuePath} is recorded in the database as ${row.artifact_type || "UNKNOWN"} but no matching file exists on disk`,
|
|
613
711
|
file: issuePath,
|
|
614
|
-
fixable:
|
|
712
|
+
fixable: staleArtifactRowFixable(basePath, row, artifactRows),
|
|
615
713
|
});
|
|
616
714
|
}
|
|
617
715
|
} catch {
|
|
@@ -643,6 +741,7 @@ export async function checkEngineHealth(
|
|
|
643
741
|
)
|
|
644
742
|
.all() as Array<{
|
|
645
743
|
path: string;
|
|
744
|
+
artifact_type: string;
|
|
646
745
|
milestone_id: string;
|
|
647
746
|
slice_id: string | null;
|
|
648
747
|
task_id: string | null;
|
|
@@ -654,7 +753,7 @@ export async function checkEngineHealth(
|
|
|
654
753
|
|
|
655
754
|
const seen = new Set<string>();
|
|
656
755
|
for (const row of rows) {
|
|
657
|
-
if (!artifactExistsOnDisk(basePath, row.path)) continue;
|
|
756
|
+
if (!artifactExistsOnDisk(basePath, row.path, row)) continue;
|
|
658
757
|
const reopenAt = latestExplicitReopenAt(basePath, row.milestone_id);
|
|
659
758
|
if (!isAfter(row.imported_at, reopenAt)) continue;
|
|
660
759
|
const isSliceSummary = row.slice_id && !row.task_id && row.slice_status && !["complete", "done", "skipped", "closed"].includes(row.slice_status);
|