@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
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { execFileSync } from "node:child_process";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { resolveAmbientBrowserEngineResolution, resolveBrowserEngineResolution, } from "../browser-tools/engine/selection.js";
|
|
4
|
-
import { resolveGsdBrowserCliAvailability, resolveGsdBrowserDaemonStartInvocation, } from "../shared/gsd-browser-cli.js";
|
|
4
|
+
import { resolveGsdBrowserCliAvailability, resolveGsdBrowserDaemonStartInvocation, resolveGsdBrowserDaemonStopInvocation, } from "../shared/gsd-browser-cli.js";
|
|
5
5
|
import { uatTypeIncludesBrowser } from "./uat-policy.js";
|
|
6
6
|
const DEFAULT_DAEMON_START_TIMEOUT_MS = 30_000;
|
|
7
|
+
const DEFAULT_DAEMON_STOP_TIMEOUT_MS = 15_000;
|
|
8
|
+
/**
|
|
9
|
+
* Project roots whose gsd-browser daemon this process warmed via
|
|
10
|
+
* {@link prepareBrowserDaemonForUat}. Teardown only stops daemons we actually
|
|
11
|
+
* started, so non-browser auto-mode sessions never spawn a stray `daemon stop`.
|
|
12
|
+
*/
|
|
13
|
+
const warmedDaemonProjectRoots = new Set();
|
|
7
14
|
function isEnvDisabled(value) {
|
|
8
15
|
if (!value)
|
|
9
16
|
return false;
|
|
@@ -77,7 +84,66 @@ export function prepareBrowserDaemonForUat(ctx) {
|
|
|
77
84
|
if (!shouldWarmBrowserDaemonForUat(ctx))
|
|
78
85
|
return null;
|
|
79
86
|
const result = ensureBrowserDaemonStarted(ctx.projectRoot, { env: ctx.env });
|
|
80
|
-
if (result.ok)
|
|
87
|
+
if (result.ok) {
|
|
88
|
+
warmedDaemonProjectRoots.add(resolve(ctx.projectRoot));
|
|
81
89
|
return null;
|
|
90
|
+
}
|
|
82
91
|
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.`;
|
|
83
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Best-effort stop of a gsd-browser session daemon warmed for browser UAT.
|
|
95
|
+
* Mirrors {@link ensureBrowserDaemonStarted}; returns the failure detail rather
|
|
96
|
+
* than throwing so teardown can stay non-fatal.
|
|
97
|
+
*/
|
|
98
|
+
export function stopBrowserDaemon(projectRoot, options = {}) {
|
|
99
|
+
const env = options.env ?? process.env;
|
|
100
|
+
const availability = resolveGsdBrowserCliAvailability(env);
|
|
101
|
+
if (!availability.available) {
|
|
102
|
+
return { ok: false, error: availability.detail };
|
|
103
|
+
}
|
|
104
|
+
let invocation;
|
|
105
|
+
try {
|
|
106
|
+
invocation = resolveGsdBrowserDaemonStopInvocation(projectRoot, env);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
return {
|
|
110
|
+
ok: false,
|
|
111
|
+
error: error instanceof Error ? error.message : String(error),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
execFileSync(invocation.command, invocation.args, {
|
|
116
|
+
cwd: invocation.cwd,
|
|
117
|
+
env: { ...process.env, ...env, ...(invocation.env ?? {}) },
|
|
118
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
119
|
+
timeout: options.timeoutMs ?? DEFAULT_DAEMON_STOP_TIMEOUT_MS,
|
|
120
|
+
encoding: "utf-8",
|
|
121
|
+
});
|
|
122
|
+
return { ok: true };
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
return {
|
|
126
|
+
ok: false,
|
|
127
|
+
error: error instanceof Error ? error.message : String(error),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Tear down every gsd-browser daemon this process warmed for browser UAT,
|
|
133
|
+
* clearing the tracked set. Called on auto-mode loop exit so the Chrome process
|
|
134
|
+
* does not survive session/task completion (mirrors the warm-up preflight).
|
|
135
|
+
* Best-effort: returns the project roots whose stop failed for logging.
|
|
136
|
+
*/
|
|
137
|
+
export function teardownWarmedBrowserDaemons(options = {}) {
|
|
138
|
+
if (warmedDaemonProjectRoots.size === 0)
|
|
139
|
+
return [];
|
|
140
|
+
const failures = [];
|
|
141
|
+
for (const projectRoot of warmedDaemonProjectRoots) {
|
|
142
|
+
const result = stopBrowserDaemon(projectRoot, { env: options.env });
|
|
143
|
+
if (!result.ok) {
|
|
144
|
+
failures.push({ projectRoot, error: result.error });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
warmedDaemonProjectRoots.clear();
|
|
148
|
+
return failures;
|
|
149
|
+
}
|
|
@@ -506,9 +506,15 @@ export function ensureCodebaseMapFresh(basePath, options, ensureOptions) {
|
|
|
506
506
|
}
|
|
507
507
|
const metadata = parseCodebaseMapMetadata(existing);
|
|
508
508
|
const existingDescriptions = parseCodebaseMap(existing);
|
|
509
|
+
// Compare against the truncated count: when the repository has more tracked
|
|
510
|
+
// files than maxFiles, the map only lists the first maxFiles entries, so a
|
|
511
|
+
// stored fileCount above the cap (e.g. from an older map that recorded the
|
|
512
|
+
// full count) still matches the current truncated listing. Comparing raw
|
|
513
|
+
// values would flag "file-count-changed" on every turn, rewriting the
|
|
514
|
+
// timestamp and invalidating the provider KV cache prefix.
|
|
509
515
|
const staleReason = !metadata ? "missing-metadata"
|
|
510
516
|
: metadata.fingerprint !== fingerprint ? "files-changed"
|
|
511
|
-
: metadata.fileCount !== listed.files.length ? "file-count-changed"
|
|
517
|
+
: Math.min(metadata.fileCount, resolved.maxFiles) !== listed.files.length ? "file-count-changed"
|
|
512
518
|
: metadata.truncated !== listed.truncated ? "truncation-changed"
|
|
513
519
|
: undefined;
|
|
514
520
|
if (!staleReason) {
|
|
@@ -16,7 +16,7 @@ import { appendCapture, hasPendingCaptures, loadPendingCaptures } from "./captur
|
|
|
16
16
|
import { appendOverride, appendKnowledge } from "./files.js";
|
|
17
17
|
import { formatDoctorIssuesForPrompt, formatDoctorReport, formatDoctorReportJson, runGSDDoctor, selectDoctorScope, filterDoctorIssues, } from "./doctor.js";
|
|
18
18
|
import { isAutoActive, checkRemoteAutoSession } from "./auto.js";
|
|
19
|
-
import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
19
|
+
import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
|
|
20
20
|
import { currentDirectoryRoot, projectRoot } from "./commands/context.js";
|
|
21
21
|
import { loadPrompt } from "./prompt-loader.js";
|
|
22
22
|
import { buildClaudeRuntimeFloorAdvisory } from "../../shared/claude-runtime-floor.js";
|
|
@@ -5,7 +5,7 @@ import { join } from "node:path";
|
|
|
5
5
|
import { resolveByName, autoDetect, listTemplates, getTemplateInfo, loadWorkflowTemplate, loadRegistry, isLegacyWorkflowMode, } from "./workflow-templates.js";
|
|
6
6
|
import { loadPrompt } from "./prompt-loader.js";
|
|
7
7
|
import { gsdRoot } from "./paths.js";
|
|
8
|
-
import { createGitService, runGit } from "./git-service.js";
|
|
8
|
+
import { createGitService, runGit, taskBranchArgs } from "./git-service.js";
|
|
9
9
|
import { isAutoActive, isAutoPaused } from "./auto.js";
|
|
10
10
|
import { getErrorMessage } from "./error-utils.js";
|
|
11
11
|
import { resolvePlugin } from "./workflow-plugins.js";
|
|
@@ -349,7 +349,7 @@ export async function handleStart(args, ctx, pi) {
|
|
|
349
349
|
git.autoCommit("workflow-template", templateId, []);
|
|
350
350
|
}
|
|
351
351
|
catch { /* nothing to commit */ }
|
|
352
|
-
runGit(basePath,
|
|
352
|
+
runGit(basePath, taskBranchArgs(basePath, branchName, current, git.getMainBranch()));
|
|
353
353
|
branchCreated = true;
|
|
354
354
|
}
|
|
355
355
|
}
|
|
@@ -481,7 +481,7 @@ export function dispatchMarkdownPhasePlugin(plugin, description, ctx, pi) {
|
|
|
481
481
|
git.autoCommit("workflow-template", templateId, []);
|
|
482
482
|
}
|
|
483
483
|
catch { /* nothing to commit */ }
|
|
484
|
-
runGit(basePath,
|
|
484
|
+
runGit(basePath, taskBranchArgs(basePath, branchName, current, git.getMainBranch()));
|
|
485
485
|
branchCreated = true;
|
|
486
486
|
}
|
|
487
487
|
}
|
|
@@ -98,6 +98,50 @@ export function writeCompatMarker(basePath, marker) {
|
|
|
98
98
|
writeFileSync(tmp, JSON.stringify(marker, null, 2), "utf-8");
|
|
99
99
|
renameSync(tmp, path);
|
|
100
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Remove projection entries whose backing file no longer exists on disk.
|
|
103
|
+
*
|
|
104
|
+
* gsd-pi never deletes marker entries on its own: both drift detectors skip
|
|
105
|
+
* files missing from disk (`if (!existsSync(abs)) continue;`) and the write-time
|
|
106
|
+
* flush only ever adds or refreshes entries. So when a phase directory is
|
|
107
|
+
* renamed or removed (e.g. `phases/29-new-milestone-m029/` →
|
|
108
|
+
* `phases/29-frontend-code-debt-cleanup/`), the old projection paths linger in
|
|
109
|
+
* `.compat.json` forever as phantom entries pointing at directories that no
|
|
110
|
+
* longer exist (#1257). They never reconcile, and `.compat.json` keeps drifting
|
|
111
|
+
* from disk reality so `git status` stops being a reliable proxy for "did the
|
|
112
|
+
* engine touch my plans?".
|
|
113
|
+
*
|
|
114
|
+
* This prunes those orphaned entries across the `.gsd/` projections and the
|
|
115
|
+
* `.planning/` projections/passthrough maps. It is safe: a missing-file entry is
|
|
116
|
+
* inert (every detector already ignores it), and if the file is later
|
|
117
|
+
* re-projected the write-time flush / unseeded-file detection re-seeds an
|
|
118
|
+
* accurate baseline.
|
|
119
|
+
*
|
|
120
|
+
* Returns the number of entries removed; when nothing is orphaned the marker is
|
|
121
|
+
* left untouched (no needless write, no `lastProjectedAt` churn).
|
|
122
|
+
*/
|
|
123
|
+
export function pruneOrphanedProjectionEntries(basePath) {
|
|
124
|
+
if (!existsSync(compatMarkerPath(basePath)))
|
|
125
|
+
return 0;
|
|
126
|
+
const marker = readCompatMarker(basePath);
|
|
127
|
+
let removed = 0;
|
|
128
|
+
const pruneMap = (map, root) => {
|
|
129
|
+
for (const relPath of Object.keys(map)) {
|
|
130
|
+
if (!existsSync(join(basePath, root, relPath))) {
|
|
131
|
+
delete map[relPath];
|
|
132
|
+
removed++;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
pruneMap(marker.projections, ".gsd");
|
|
137
|
+
if (marker.planning) {
|
|
138
|
+
pruneMap(marker.planning.projections, ".planning");
|
|
139
|
+
pruneMap(marker.planning.passthrough, ".planning");
|
|
140
|
+
}
|
|
141
|
+
if (removed > 0)
|
|
142
|
+
writeCompatMarker(basePath, marker);
|
|
143
|
+
return removed;
|
|
144
|
+
}
|
|
101
145
|
function quarantine(basePath, raw) {
|
|
102
146
|
const path = compatMarkerPath(basePath);
|
|
103
147
|
const badPath = `${path}.bad-${Date.now()}`;
|
|
@@ -121,8 +121,13 @@ function collectConfigSections(options) {
|
|
|
121
121
|
if (prefs?.auto_supervisor) {
|
|
122
122
|
const sup = resolveAutoSupervisorConfig();
|
|
123
123
|
const supRows = [];
|
|
124
|
-
if (sup.model)
|
|
125
|
-
|
|
124
|
+
if (sup.model) {
|
|
125
|
+
let modelVal = sup.model;
|
|
126
|
+
if (sup.modelFallbacks && sup.modelFallbacks.length > 0) {
|
|
127
|
+
modelVal += ` \u2192 ${sup.modelFallbacks.join(" \u2192 ")}`;
|
|
128
|
+
}
|
|
129
|
+
supRows.push({ label: "Model", value: modelVal });
|
|
130
|
+
}
|
|
126
131
|
supRows.push({ label: "Soft timeout", value: `${sup.soft_timeout_minutes}m` });
|
|
127
132
|
supRows.push({ label: "Idle timeout", value: `${sup.idle_timeout_minutes}m` });
|
|
128
133
|
supRows.push({ label: "Stalled tool timeout", value: `${sup.stalled_tool_timeout_minutes}m` });
|
|
@@ -801,3 +801,36 @@ export function getDb() {
|
|
|
801
801
|
export function getDbOrNull() {
|
|
802
802
|
return currentDb;
|
|
803
803
|
}
|
|
804
|
+
/**
|
|
805
|
+
* Confirm the open handle can actually write, not just that it opened.
|
|
806
|
+
*
|
|
807
|
+
* A schema-current database performs zero writes during open, so a handle that
|
|
808
|
+
* opened successfully but is not writable (read-only file, WAL/SHM permission
|
|
809
|
+
* mismatch, or a stale/moved handle → SQLITE_READONLY_DBMOVED) otherwise passes
|
|
810
|
+
* the open-only availability check and only fails much later at the first real
|
|
811
|
+
* write. The probe forces a genuine page write by re-writing the current
|
|
812
|
+
* `PRAGMA user_version` value back inside an IMMEDIATE transaction: a bare
|
|
813
|
+
* `BEGIN IMMEDIATE; ROLLBACK` is not sufficient because a moved handle does not
|
|
814
|
+
* fail until a page is actually dirtied. The value is unchanged, so the probe
|
|
815
|
+
* is idempotent, and the transaction is rolled back so nothing persists.
|
|
816
|
+
*/
|
|
817
|
+
export function probeDbWritable() {
|
|
818
|
+
const db = currentDb;
|
|
819
|
+
if (!db)
|
|
820
|
+
return { ok: false, detail: "No database is open." };
|
|
821
|
+
try {
|
|
822
|
+
const row = db.prepare("PRAGMA user_version").get();
|
|
823
|
+
const current = typeof row?.user_version === "number" ? row.user_version : 0;
|
|
824
|
+
db.exec("BEGIN IMMEDIATE");
|
|
825
|
+
try {
|
|
826
|
+
db.exec(`PRAGMA user_version = ${current}`);
|
|
827
|
+
}
|
|
828
|
+
finally {
|
|
829
|
+
db.exec("ROLLBACK");
|
|
830
|
+
}
|
|
831
|
+
return { ok: true };
|
|
832
|
+
}
|
|
833
|
+
catch (err) {
|
|
834
|
+
return { ok: false, detail: err.message };
|
|
835
|
+
}
|
|
836
|
+
}
|
|
@@ -218,7 +218,7 @@ export function getMilestone(id) {
|
|
|
218
218
|
export function getActiveMilestoneFromDb() {
|
|
219
219
|
if (!getDbOrNull())
|
|
220
220
|
return null;
|
|
221
|
-
const row = getDbOrNull().prepare(
|
|
221
|
+
const row = getDbOrNull().prepare(`SELECT * FROM milestones WHERE status NOT IN (${TERMINAL_STATUS_SQL}, 'parked') ORDER BY id LIMIT 1`).get();
|
|
222
222
|
if (!row)
|
|
223
223
|
return null;
|
|
224
224
|
return rowToMilestone(row);
|
|
@@ -230,11 +230,11 @@ export function getActiveSliceFromDb(milestoneId) {
|
|
|
230
230
|
// Uses json_each() to expand the JSON depends array and checks each dep is complete.
|
|
231
231
|
const row = getDbOrNull().prepare(`SELECT s.* FROM slices s
|
|
232
232
|
WHERE s.milestone_id = :mid
|
|
233
|
-
AND s.status NOT IN (
|
|
233
|
+
AND s.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
234
234
|
AND NOT EXISTS (
|
|
235
235
|
SELECT 1 FROM json_each(s.depends) AS dep
|
|
236
236
|
WHERE dep.value NOT IN (
|
|
237
|
-
SELECT id FROM slices WHERE milestone_id = :mid AND status IN (
|
|
237
|
+
SELECT id FROM slices WHERE milestone_id = :mid AND status IN (${TERMINAL_STATUS_SQL})
|
|
238
238
|
)
|
|
239
239
|
)
|
|
240
240
|
ORDER BY s.sequence, s.id
|
|
@@ -246,7 +246,7 @@ export function getActiveSliceFromDb(milestoneId) {
|
|
|
246
246
|
export function getActiveTaskFromDb(milestoneId, sliceId) {
|
|
247
247
|
if (!getDbOrNull())
|
|
248
248
|
return null;
|
|
249
|
-
const row = getDbOrNull().prepare(
|
|
249
|
+
const row = getDbOrNull().prepare(`SELECT * FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND status NOT IN (${TERMINAL_STATUS_SQL}) ORDER BY sequence, id LIMIT 1`).get({ ":mid": milestoneId, ":sid": sliceId });
|
|
250
250
|
if (!row)
|
|
251
251
|
return null;
|
|
252
252
|
return rowToTask(row);
|
|
@@ -265,7 +265,7 @@ export function getParallelMonitorSliceProgress(milestoneId) {
|
|
|
265
265
|
s.id AS id,
|
|
266
266
|
s.status AS status,
|
|
267
267
|
COUNT(t.id) AS total,
|
|
268
|
-
COALESCE(SUM(CASE WHEN t.status
|
|
268
|
+
COALESCE(SUM(CASE WHEN t.status IN (${TERMINAL_STATUS_SQL}) THEN 1 ELSE 0 END), 0) AS done
|
|
269
269
|
FROM slices s
|
|
270
270
|
LEFT JOIN tasks t ON s.milestone_id=t.milestone_id AND s.id=t.slice_id
|
|
271
271
|
WHERE s.milestone_id=:mid
|
|
@@ -417,7 +417,7 @@ export function getSliceScopedArtifacts(milestoneId, sliceId) {
|
|
|
417
417
|
export function getActiveMilestoneIdFromDb() {
|
|
418
418
|
if (!getDbOrNull())
|
|
419
419
|
return null;
|
|
420
|
-
const row = getDbOrNull().prepare(
|
|
420
|
+
const row = getDbOrNull().prepare(`SELECT id, status FROM milestones WHERE status NOT IN (${TERMINAL_STATUS_SQL}, 'parked') ORDER BY id LIMIT 1`).get();
|
|
421
421
|
if (!row)
|
|
422
422
|
return null;
|
|
423
423
|
return rowToIdStatusSummary(row);
|
|
@@ -432,7 +432,7 @@ export function getSliceStatusSummary(milestoneId) {
|
|
|
432
432
|
export function getActiveTaskIdFromDb(milestoneId, sliceId) {
|
|
433
433
|
if (!getDbOrNull())
|
|
434
434
|
return null;
|
|
435
|
-
const row = getDbOrNull().prepare(
|
|
435
|
+
const row = getDbOrNull().prepare(`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`).get({ ":mid": milestoneId, ":sid": sliceId });
|
|
436
436
|
if (!row)
|
|
437
437
|
return null;
|
|
438
438
|
return rowToActiveTaskSummary(row);
|
|
@@ -443,8 +443,8 @@ export function getSliceTaskCounts(milestoneId, sliceId) {
|
|
|
443
443
|
return emptyTaskStatusCounts();
|
|
444
444
|
const row = getDbOrNull().prepare(`SELECT
|
|
445
445
|
COUNT(*) as total,
|
|
446
|
-
SUM(CASE WHEN status IN (
|
|
447
|
-
SUM(CASE WHEN status NOT IN (
|
|
446
|
+
SUM(CASE WHEN status IN (${TERMINAL_STATUS_SQL}) THEN 1 ELSE 0 END) as done,
|
|
447
|
+
SUM(CASE WHEN status NOT IN (${TERMINAL_STATUS_SQL}) THEN 1 ELSE 0 END) as pending
|
|
448
448
|
FROM tasks WHERE milestone_id = :mid AND slice_id = :sid`).get({ ":mid": milestoneId, ":sid": sliceId });
|
|
449
449
|
return rowToTaskStatusCounts(row);
|
|
450
450
|
}
|
|
@@ -24,6 +24,17 @@ function requireDb() {
|
|
|
24
24
|
* completion timestamps cleared, in one commit. Folds the hand-rolled
|
|
25
25
|
* transaction-plus-cascade previously in tools/reopen-slice.ts. Guards run
|
|
26
26
|
* inside the transaction (TOCTOU-safe).
|
|
27
|
+
*
|
|
28
|
+
* A closed slice is always reopenable. An open slice is only reopenable when it
|
|
29
|
+
* carries a completed-task state desync (#1205): a UAT→planning fallback can
|
|
30
|
+
* leave the slice "pending" while *all* its tasks stay "complete", which
|
|
31
|
+
* deadlocks every recovery path (plan-slice/replan-slice/complete-task all
|
|
32
|
+
* reject the still-closed tasks, and slice_reopen historically rejected the
|
|
33
|
+
* still-open slice). Resetting those tasks to pending gives the planner the
|
|
34
|
+
* clean slate it needs. An open slice that still has any unfinished
|
|
35
|
+
* (pending/in-progress) task is a normal in-flight slice, not the desync, and
|
|
36
|
+
* stays rejected as "slice-not-complete" so a full reset can't wipe its
|
|
37
|
+
* legitimate progress.
|
|
27
38
|
*/
|
|
28
39
|
export function reopenSliceCascade(milestoneId, sliceId) {
|
|
29
40
|
requireDb();
|
|
@@ -43,11 +54,18 @@ export function reopenSliceCascade(milestoneId, sliceId) {
|
|
|
43
54
|
outcome = { ok: false, reason: "slice-not-found" };
|
|
44
55
|
return;
|
|
45
56
|
}
|
|
46
|
-
|
|
57
|
+
const tasks = getSliceTasks(milestoneId, sliceId);
|
|
58
|
+
// A closed slice is always reopenable. An open slice is only the #1205
|
|
59
|
+
// desync when EVERY task is already closed (a UAT→planning fallback left the
|
|
60
|
+
// slice open with all tasks still "complete"). Requiring *all* tasks closed
|
|
61
|
+
// (not merely one) means a normal in-flight slice — which keeps at least one
|
|
62
|
+
// pending/in-progress task — is rejected, so a full reset can't wipe its
|
|
63
|
+
// legitimate progress.
|
|
64
|
+
const allTasksClosed = tasks.length > 0 && tasks.every((t) => isClosedStatus(t.status));
|
|
65
|
+
if (!isClosedStatus(slice.status) && !allTasksClosed) {
|
|
47
66
|
outcome = { ok: false, reason: "slice-not-complete", status: slice.status };
|
|
48
67
|
return;
|
|
49
68
|
}
|
|
50
|
-
const tasks = getSliceTasks(milestoneId, sliceId);
|
|
51
69
|
getDbOrNull().prepare(`UPDATE slices SET status = 'in_progress', completed_at = NULL WHERE milestone_id = :mid AND id = :sid`).run({ ":mid": milestoneId, ":sid": sliceId });
|
|
52
70
|
getDbOrNull().prepare(`UPDATE tasks SET status = 'pending', completed_at = NULL WHERE milestone_id = :mid AND slice_id = :sid`).run({ ":mid": milestoneId, ":sid": sliceId });
|
|
53
71
|
outcome = { ok: true, tasksReset: tasks.length };
|
|
@@ -11,19 +11,46 @@ export function normalizeDbRow(row) {
|
|
|
11
11
|
export function normalizeDbRows(rows) {
|
|
12
12
|
return rows.map((row) => normalizeDbRow(row));
|
|
13
13
|
}
|
|
14
|
+
function isPlainObject(value) {
|
|
15
|
+
if (value === null || typeof value !== "object")
|
|
16
|
+
return false;
|
|
17
|
+
const proto = Object.getPrototypeOf(value);
|
|
18
|
+
return proto === Object.prototype || proto === null;
|
|
19
|
+
}
|
|
20
|
+
// node:sqlite accepts binding-object keys with or without the ':'/'@'/'$'
|
|
21
|
+
// prefix, but better-sqlite3 accepts only bare keys — strip the prefix so
|
|
22
|
+
// call sites written against node:sqlite also work on the fallback provider.
|
|
23
|
+
function normalizeBindParams(params) {
|
|
24
|
+
return params.map((param) => {
|
|
25
|
+
if (!isPlainObject(param))
|
|
26
|
+
return param;
|
|
27
|
+
let changed = false;
|
|
28
|
+
const normalized = {};
|
|
29
|
+
for (const [key, value] of Object.entries(param)) {
|
|
30
|
+
if (key.length > 1 && (key[0] === ":" || key[0] === "@" || key[0] === "$")) {
|
|
31
|
+
normalized[key.slice(1)] = value;
|
|
32
|
+
changed = true;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
normalized[key] = value;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return changed ? normalized : param;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
14
41
|
export function createDbAdapter(rawDb) {
|
|
15
42
|
const db = rawDb;
|
|
16
43
|
const stmtCache = new Map();
|
|
17
44
|
function wrapStmt(raw) {
|
|
18
45
|
return {
|
|
19
46
|
run(...params) {
|
|
20
|
-
return raw.run(...params);
|
|
47
|
+
return raw.run(...normalizeBindParams(params));
|
|
21
48
|
},
|
|
22
49
|
get(...params) {
|
|
23
|
-
return normalizeDbRow(raw.get(...params));
|
|
50
|
+
return normalizeDbRow(raw.get(...normalizeBindParams(params)));
|
|
24
51
|
},
|
|
25
52
|
all(...params) {
|
|
26
|
-
return normalizeDbRows(raw.all(...params));
|
|
53
|
+
return normalizeDbRows(raw.all(...normalizeBindParams(params)));
|
|
27
54
|
},
|
|
28
55
|
};
|
|
29
56
|
}
|
|
@@ -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.
|
|
@@ -3,7 +3,7 @@ import { isAbsolute, join, relative, sep } from "node:path";
|
|
|
3
3
|
import { deleteArtifactByPath, getAllMilestones, getMilestoneSlices, getSliceTasks, isDbAvailable, isMemoriesFtsAvailable, repairTaskCompletionFromSummary, _getAdapter, } from "./gsd-db.js";
|
|
4
4
|
import { MEMORIES_FTS_REBUILT_KEY } from "./db-memory-fts-schema.js";
|
|
5
5
|
import { isAfter, latestExplicitReopenAt } from "./milestone-reopen-events.js";
|
|
6
|
-
import { gsdProjectionRoot, gsdRoot, resolveGsdPathContract, resolveMilestoneFile, resolveSliceFile } from "./paths.js";
|
|
6
|
+
import { buildTaskFileName, gsdProjectionRoot, gsdRoot, resolveGsdPathContract, resolveMilestoneFile, resolveMilestonePath, resolveSliceFile, } from "./paths.js";
|
|
7
7
|
import { deriveState } from "./state.js";
|
|
8
8
|
import { isClosedStatus } from "./status-guards.js";
|
|
9
9
|
import { workflowEventLogPath } from "./workflow-event-ledger.js";
|
|
@@ -12,6 +12,7 @@ import { flushWorkflowProjections } from "./projection-flush.js";
|
|
|
12
12
|
import { parseRoadmapSlices } from "./roadmap-slices.js";
|
|
13
13
|
import { parsePlan } from "./parsers-legacy.js";
|
|
14
14
|
import { parseSummary } from "./files.js";
|
|
15
|
+
import { LAYOUT_SEGMENTS } from "./layout-policy.js";
|
|
15
16
|
const USER_AUTHORED_ARTIFACT_TYPES = new Set(["CONTEXT", "RESEARCH"]);
|
|
16
17
|
function escapeRegExp(value) {
|
|
17
18
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -113,10 +114,10 @@ function isClearedByMilestoneShellProjectionFlush(basePath, issue, reRenderedMil
|
|
|
113
114
|
return false;
|
|
114
115
|
return issue.file === relativeFile(basePath, roadmapPath);
|
|
115
116
|
}
|
|
116
|
-
function artifactExistsOnDisk(basePath, artifactPath) {
|
|
117
|
-
return resolveArtifactDiskPath(basePath, artifactPath) !== null;
|
|
117
|
+
function artifactExistsOnDisk(basePath, artifactPath, row) {
|
|
118
|
+
return resolveArtifactDiskPath(basePath, artifactPath, row) !== null;
|
|
118
119
|
}
|
|
119
|
-
function
|
|
120
|
+
function resolveLiteralArtifactDiskPath(basePath, artifactPath) {
|
|
120
121
|
const relativeArtifactPath = artifactPathRelativeToGsd(artifactPath);
|
|
121
122
|
if (isAbsolute(relativeArtifactPath)) {
|
|
122
123
|
return existsSync(relativeArtifactPath) ? relativeArtifactPath : null;
|
|
@@ -128,6 +129,48 @@ function resolveArtifactDiskPath(basePath, artifactPath) {
|
|
|
128
129
|
}
|
|
129
130
|
return null;
|
|
130
131
|
}
|
|
132
|
+
function relativeToGsdRoot(basePath, diskPath) {
|
|
133
|
+
for (const root of [gsdProjectionRoot(basePath), gsdRoot(basePath)]) {
|
|
134
|
+
if (!isPathInside(root, diskPath))
|
|
135
|
+
continue;
|
|
136
|
+
return relative(root, diskPath).split("\\").join("/");
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
function isFlatPhaseDiskPath(basePath, diskPath) {
|
|
141
|
+
return relativeToGsdRoot(basePath, diskPath)?.startsWith(`${LAYOUT_SEGMENTS.level1}/`) ?? false;
|
|
142
|
+
}
|
|
143
|
+
function hasFlatPhaseLayout(basePath) {
|
|
144
|
+
return existsSync(join(gsdProjectionRoot(basePath), LAYOUT_SEGMENTS.level1));
|
|
145
|
+
}
|
|
146
|
+
function resolveFlatPhaseArtifactDiskPath(basePath, row) {
|
|
147
|
+
if (!hasFlatPhaseLayout(basePath))
|
|
148
|
+
return null;
|
|
149
|
+
if (!row.milestone_id)
|
|
150
|
+
return null;
|
|
151
|
+
const artifactType = normalizedArtifactType(row.artifact_type);
|
|
152
|
+
if (!artifactType)
|
|
153
|
+
return null;
|
|
154
|
+
if (row.slice_id && row.task_id) {
|
|
155
|
+
const phaseDir = resolveMilestonePath(basePath, row.milestone_id);
|
|
156
|
+
if (!phaseDir || !isFlatPhaseDiskPath(basePath, phaseDir))
|
|
157
|
+
return null;
|
|
158
|
+
const candidate = join(phaseDir, buildTaskFileName(row.task_id, artifactType));
|
|
159
|
+
return existsSync(candidate) ? candidate : null;
|
|
160
|
+
}
|
|
161
|
+
const candidate = row.slice_id
|
|
162
|
+
? resolveSliceFile(basePath, row.milestone_id, row.slice_id, artifactType)
|
|
163
|
+
: resolveMilestoneFile(basePath, row.milestone_id, artifactType);
|
|
164
|
+
return candidate && isFlatPhaseDiskPath(basePath, candidate) ? candidate : null;
|
|
165
|
+
}
|
|
166
|
+
function resolveArtifactDiskPath(basePath, artifactPath, row) {
|
|
167
|
+
if (row && isMilestonesArtifactPath(row.path)) {
|
|
168
|
+
const flatPath = resolveFlatPhaseArtifactDiskPath(basePath, row);
|
|
169
|
+
if (flatPath)
|
|
170
|
+
return flatPath;
|
|
171
|
+
}
|
|
172
|
+
return resolveLiteralArtifactDiskPath(basePath, artifactPath);
|
|
173
|
+
}
|
|
131
174
|
function taskExistsInPlan(basePath, milestoneId, sliceId, taskId) {
|
|
132
175
|
const planPath = resolveSliceFile(basePath, milestoneId, sliceId, "PLAN");
|
|
133
176
|
if (!planPath || !existsSync(planPath))
|
|
@@ -156,7 +199,7 @@ function readTaskCompletionEvidenceFromSummary(basePath, row) {
|
|
|
156
199
|
if (!row.task_status && Number(row.task_count) > 0 && !taskExistsInPlan(basePath, row.milestone_id, row.slice_id, row.task_id)) {
|
|
157
200
|
return null;
|
|
158
201
|
}
|
|
159
|
-
const diskPath = resolveArtifactDiskPath(basePath, row.path);
|
|
202
|
+
const diskPath = resolveArtifactDiskPath(basePath, row.path, { ...row, artifact_type: "SUMMARY" });
|
|
160
203
|
if (!diskPath)
|
|
161
204
|
return null;
|
|
162
205
|
try {
|
|
@@ -256,6 +299,43 @@ function hasPresentMilestonesReplacement(basePath, row, artifactRows) {
|
|
|
256
299
|
sameArtifactIdentity(row, other) &&
|
|
257
300
|
artifactExistsOnDisk(basePath, other.path));
|
|
258
301
|
}
|
|
302
|
+
function hasPresentFlatPhaseReplacement(basePath, row, artifactRows) {
|
|
303
|
+
if (resolveFlatPhaseArtifactDiskPath(basePath, row))
|
|
304
|
+
return true;
|
|
305
|
+
return artifactRows.some((other) => other.path !== row.path &&
|
|
306
|
+
!isMilestonesArtifactPath(other.path) &&
|
|
307
|
+
sameArtifactIdentity(row, other) &&
|
|
308
|
+
artifactExistsOnDisk(basePath, other.path, other));
|
|
309
|
+
}
|
|
310
|
+
function hasNoFlatPhaseFileEquivalent(row) {
|
|
311
|
+
const artifactType = normalizedArtifactType(row.artifact_type);
|
|
312
|
+
if (row.slice_id && row.task_id) {
|
|
313
|
+
return artifactType === "PLAN" || artifactType === "SUMMARY";
|
|
314
|
+
}
|
|
315
|
+
return Boolean(row.slice_id && !row.task_id && artifactType === "SUMMARY");
|
|
316
|
+
}
|
|
317
|
+
function staleMilestonesArtifactRowFixable(basePath, row, artifactRows) {
|
|
318
|
+
if (!isMilestonesArtifactPath(row.path))
|
|
319
|
+
return false;
|
|
320
|
+
if (!hasFlatPhaseLayout(basePath))
|
|
321
|
+
return false;
|
|
322
|
+
if (hasPresentFlatPhaseReplacement(basePath, row, artifactRows))
|
|
323
|
+
return true;
|
|
324
|
+
return hasNoFlatPhaseFileEquivalent(row) && !resolveLiteralArtifactDiskPath(basePath, row.path);
|
|
325
|
+
}
|
|
326
|
+
function stalePhasesArtifactRowFixable(basePath, row, artifactRows) {
|
|
327
|
+
const issuePath = artifactPathRelativeToGsd(row.path);
|
|
328
|
+
return issuePath.startsWith(`${LAYOUT_SEGMENTS.level1}/`) && hasPresentMilestonesReplacement(basePath, row, artifactRows);
|
|
329
|
+
}
|
|
330
|
+
function staleArtifactRowFixable(basePath, row, artifactRows) {
|
|
331
|
+
return staleMilestonesArtifactRowFixable(basePath, row, artifactRows) ||
|
|
332
|
+
stalePhasesArtifactRowFixable(basePath, row, artifactRows);
|
|
333
|
+
}
|
|
334
|
+
function staleArtifactPruneMessage(row) {
|
|
335
|
+
return isMilestonesArtifactPath(row.path)
|
|
336
|
+
? `pruned stale legacy artifact row ${row.path}`
|
|
337
|
+
: `pruned stale flat-phase artifact row ${row.path}`;
|
|
338
|
+
}
|
|
259
339
|
export async function checkEngineHealth(basePath, issues, fixesApplied, options) {
|
|
260
340
|
const dbPath = resolveGsdPathContract(basePath).projectDb;
|
|
261
341
|
if (!isDbAvailable() && existsSync(dbPath)) {
|
|
@@ -456,18 +536,20 @@ export async function checkEngineHealth(basePath, issues, fixesApplied, options)
|
|
|
456
536
|
ORDER BY path`)
|
|
457
537
|
.all();
|
|
458
538
|
for (const row of artifactRows) {
|
|
459
|
-
if (artifactExistsOnDisk(basePath, row.path))
|
|
460
|
-
continue;
|
|
461
539
|
const unitId = artifactUnitId(row);
|
|
462
540
|
const issuePath = artifactPathRelativeToGsd(row.path);
|
|
463
|
-
if (
|
|
541
|
+
if (artifactExistsOnDisk(basePath, row.path))
|
|
542
|
+
continue;
|
|
543
|
+
if (options?.repair && staleArtifactRowFixable(basePath, row, artifactRows)) {
|
|
464
544
|
// Route the write through the Single Writer owner (gsd-db.ts) instead
|
|
465
545
|
// of issuing raw DELETE SQL here — doctor is a read-only consumer and
|
|
466
546
|
// the single-writer invariant forbids write SQL outside the allowlist.
|
|
467
547
|
deleteArtifactByPath(row.path);
|
|
468
|
-
fixesApplied.push(
|
|
548
|
+
fixesApplied.push(staleArtifactPruneMessage(row));
|
|
469
549
|
continue;
|
|
470
550
|
}
|
|
551
|
+
if (artifactExistsOnDisk(basePath, row.path, row))
|
|
552
|
+
continue;
|
|
471
553
|
if (isUserAuthoredArtifactType(row.artifact_type)) {
|
|
472
554
|
const artifactType = normalizedArtifactType(row.artifact_type);
|
|
473
555
|
missingUserContentArtifacts.push({ path: issuePath, artifactType });
|
|
@@ -489,7 +571,7 @@ export async function checkEngineHealth(basePath, issues, fixesApplied, options)
|
|
|
489
571
|
unitId,
|
|
490
572
|
message: `Artifact ${issuePath} is recorded in the database as ${row.artifact_type || "UNKNOWN"} but no matching file exists on disk`,
|
|
491
573
|
file: issuePath,
|
|
492
|
-
fixable:
|
|
574
|
+
fixable: staleArtifactRowFixable(basePath, row, artifactRows),
|
|
493
575
|
});
|
|
494
576
|
}
|
|
495
577
|
}
|
|
@@ -518,7 +600,7 @@ export async function checkEngineHealth(basePath, issues, fixesApplied, options)
|
|
|
518
600
|
.all();
|
|
519
601
|
const seen = new Set();
|
|
520
602
|
for (const row of rows) {
|
|
521
|
-
if (!artifactExistsOnDisk(basePath, row.path))
|
|
603
|
+
if (!artifactExistsOnDisk(basePath, row.path, row))
|
|
522
604
|
continue;
|
|
523
605
|
const reopenAt = latestExplicitReopenAt(basePath, row.milestone_id);
|
|
524
606
|
if (!isAfter(row.imported_at, reopenAt))
|