@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
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
writeCompatMarker,
|
|
13
13
|
normalizeForHash,
|
|
14
14
|
computeProjectionSha,
|
|
15
|
+
pruneOrphanedProjectionEntries,
|
|
15
16
|
EMPTY_MARKER,
|
|
16
17
|
compatMarkerPath,
|
|
17
18
|
} from "../compat/compat-marker.ts";
|
|
@@ -103,3 +104,87 @@ test("compatMarkerPath resolves under .gsd", () => {
|
|
|
103
104
|
const base = makeTmpBase();
|
|
104
105
|
assert.equal(compatMarkerPath(base), join(base, ".gsd", ".compat.json"));
|
|
105
106
|
});
|
|
107
|
+
|
|
108
|
+
test("pruneOrphanedProjectionEntries drops entries whose backing file is gone (#1257)", () => {
|
|
109
|
+
const base = makeTmpBase();
|
|
110
|
+
// Live projection: file exists on disk.
|
|
111
|
+
const liveRel = "phases/29-frontend-code-debt-cleanup/29-ROADMAP.md";
|
|
112
|
+
mkdirSync(join(base, ".gsd", "phases", "29-frontend-code-debt-cleanup"), { recursive: true });
|
|
113
|
+
writeFileSync(join(base, ".gsd", liveRel), "# M029\n", "utf-8");
|
|
114
|
+
// Phantom projection: directory was renamed, file no longer exists.
|
|
115
|
+
const ghostRel = "phases/29-new-milestone-m029/29-ROADMAP.md";
|
|
116
|
+
|
|
117
|
+
writeCompatMarker(base, {
|
|
118
|
+
schema: 2,
|
|
119
|
+
lastWriter: "gsd-pi",
|
|
120
|
+
lastProjectedAt: "2026-07-05T05:35:19.379Z",
|
|
121
|
+
projections: {
|
|
122
|
+
[liveRel]: { sha: "live000000000000", entities: ["M029"] },
|
|
123
|
+
[ghostRel]: { sha: "ghost00000000000", entities: ["M029"] },
|
|
124
|
+
},
|
|
125
|
+
piVersion: "1.4.0",
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const removed = pruneOrphanedProjectionEntries(base);
|
|
129
|
+
assert.equal(removed, 1);
|
|
130
|
+
|
|
131
|
+
const marker = readCompatMarker(base);
|
|
132
|
+
assert.ok(marker.projections[liveRel], "live projection must survive");
|
|
133
|
+
assert.equal(marker.projections[ghostRel], undefined, "phantom projection must be pruned");
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test("pruneOrphanedProjectionEntries also prunes .planning projections/passthrough", () => {
|
|
137
|
+
const base = makeTmpBase();
|
|
138
|
+
mkdirSync(join(base, ".planning"), { recursive: true });
|
|
139
|
+
writeFileSync(join(base, ".planning", "ROADMAP.md"), "# roadmap\n", "utf-8");
|
|
140
|
+
|
|
141
|
+
writeCompatMarker(base, {
|
|
142
|
+
schema: 2,
|
|
143
|
+
lastWriter: "gsd-pi",
|
|
144
|
+
lastProjectedAt: "2026-07-05T05:35:19.379Z",
|
|
145
|
+
projections: {},
|
|
146
|
+
planning: {
|
|
147
|
+
active: true,
|
|
148
|
+
layout: "flat-phases",
|
|
149
|
+
projections: {
|
|
150
|
+
"ROADMAP.md": { sha: "live000000000000", entities: [] },
|
|
151
|
+
"gone/PLAN.md": { sha: "ghost00000000000", entities: [] },
|
|
152
|
+
},
|
|
153
|
+
passthrough: {
|
|
154
|
+
"gone/PATTERNS.md": { sha: "ghost11111111111", entities: [] },
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
piVersion: "1.4.0",
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const removed = pruneOrphanedProjectionEntries(base);
|
|
161
|
+
assert.equal(removed, 2);
|
|
162
|
+
|
|
163
|
+
const marker = readCompatMarker(base);
|
|
164
|
+
assert.ok(marker.planning!.projections["ROADMAP.md"], "live planning projection must survive");
|
|
165
|
+
assert.equal(marker.planning!.projections["gone/PLAN.md"], undefined);
|
|
166
|
+
assert.equal(marker.planning!.passthrough["gone/PATTERNS.md"], undefined);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test("pruneOrphanedProjectionEntries is a no-op when nothing is orphaned", () => {
|
|
170
|
+
const base = makeTmpBase();
|
|
171
|
+
const rel = "phases/01-phase/01-01-PLAN.md";
|
|
172
|
+
mkdirSync(join(base, ".gsd", "phases", "01-phase"), { recursive: true });
|
|
173
|
+
writeFileSync(join(base, ".gsd", rel), "# plan\n", "utf-8");
|
|
174
|
+
writeCompatMarker(base, {
|
|
175
|
+
schema: 2,
|
|
176
|
+
lastWriter: "gsd-pi",
|
|
177
|
+
lastProjectedAt: "2026-07-05T05:35:19.379Z",
|
|
178
|
+
projections: { [rel]: { sha: "abc000000000000", entities: ["M001"] } },
|
|
179
|
+
piVersion: "1.4.0",
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
assert.equal(pruneOrphanedProjectionEntries(base), 0);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test("pruneOrphanedProjectionEntries returns 0 and writes nothing when marker is missing", () => {
|
|
186
|
+
const base = makeTmpBase();
|
|
187
|
+
assert.equal(pruneOrphanedProjectionEntries(base), 0);
|
|
188
|
+
const files = readdirSync(join(base, ".gsd"));
|
|
189
|
+
assert.ok(!files.includes(".compat.json"), "must not create a marker where none existed");
|
|
190
|
+
});
|
|
@@ -422,6 +422,51 @@ console.log('\n=== complete-milestone: existing SUMMARY.md preserved (#4598) ===
|
|
|
422
422
|
cleanup(dbPath);
|
|
423
423
|
}
|
|
424
424
|
|
|
425
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
426
|
+
// complete-milestone: flat-phase compatibility SUMMARY.md is not hidden
|
|
427
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
428
|
+
|
|
429
|
+
console.log('\n=== complete-milestone: flat-phase legacy-named SUMMARY.md preserved (#4598) ===');
|
|
430
|
+
{
|
|
431
|
+
const dbPath = tempDbPath();
|
|
432
|
+
openDatabase(dbPath);
|
|
433
|
+
const basePath = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-flat-complete-milestone-'));
|
|
434
|
+
const phaseDir = path.join(basePath, '.gsd', 'phases', '01-test-milestone');
|
|
435
|
+
fs.mkdirSync(path.join(phaseDir, 'slices', 'S01', 'tasks'), { recursive: true });
|
|
436
|
+
seedCompletedMilestone({ basePath, validationVerdict: 'pass' });
|
|
437
|
+
|
|
438
|
+
// Flat-phase projects may still contain legacy-named compatibility files.
|
|
439
|
+
// The no-overwrite guard must preserve those richer summaries instead of
|
|
440
|
+
// generating a canonical sibling that later readers would prefer.
|
|
441
|
+
const summaryPath = path.join(phaseDir, 'M001-SUMMARY.md');
|
|
442
|
+
const canonicalSummaryPath = path.join(phaseDir, '01-SUMMARY.md');
|
|
443
|
+
const sentinel = '# M001: Pre-existing flat-phase richer summary\n\nDO NOT OVERWRITE ME\n';
|
|
444
|
+
fs.writeFileSync(summaryPath, sentinel, 'utf-8');
|
|
445
|
+
|
|
446
|
+
const result = await handleCompleteMilestone(makeValidParams(), basePath);
|
|
447
|
+
assertTrue(!('error' in result), 'completion should still succeed when flat-phase compatibility SUMMARY.md exists');
|
|
448
|
+
if (!('error' in result)) {
|
|
449
|
+
assertEq(
|
|
450
|
+
result.summaryPath,
|
|
451
|
+
fs.realpathSync(summaryPath),
|
|
452
|
+
'completion should report the preserved existing SUMMARY path',
|
|
453
|
+
);
|
|
454
|
+
assertEq(
|
|
455
|
+
fs.readFileSync(summaryPath, 'utf-8'),
|
|
456
|
+
sentinel,
|
|
457
|
+
'flat-phase compatibility SUMMARY.md must be preserved, not hidden by a canonical rewrite',
|
|
458
|
+
);
|
|
459
|
+
assertTrue(
|
|
460
|
+
!fs.existsSync(canonicalSummaryPath),
|
|
461
|
+
'completion must not create a canonical sibling over an existing compatibility summary',
|
|
462
|
+
);
|
|
463
|
+
assertEq(getMilestone('M001')!.status, 'complete', 'milestone should still be marked complete in DB');
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
cleanupDir(basePath);
|
|
467
|
+
cleanup(dbPath);
|
|
468
|
+
}
|
|
469
|
+
|
|
425
470
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
426
471
|
|
|
427
472
|
report();
|
|
@@ -7,7 +7,7 @@ import assert from "node:assert/strict";
|
|
|
7
7
|
import { readFileSync, mkdtempSync, mkdirSync, writeFileSync, existsSync, cpSync, rmSync } from "node:fs";
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
import { tmpdir } from "node:os";
|
|
10
|
-
import { syncStateToProjectRoot } from "../auto-worktree.ts";
|
|
10
|
+
import { syncStateToProjectRoot } from "../auto-worktree-sync.ts";
|
|
11
11
|
|
|
12
12
|
test("#2313: syncStateToProjectRoot copies metrics and completed-units to the project root", () => {
|
|
13
13
|
const root = mkdtempSync(join(tmpdir(), "gsd-sync-metrics-"));
|
|
@@ -33,6 +33,45 @@ test("normalizeDbRows normalizes every row", () => {
|
|
|
33
33
|
assert.deepEqual(normalizeDbRows([first, second]), [{ id: "S01" }, { id: "S02" }]);
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
+
test("createDbAdapter strips named-parameter key prefixes for provider compatibility", () => {
|
|
37
|
+
const received: unknown[][] = [];
|
|
38
|
+
const rawStatement = {
|
|
39
|
+
run: (...params: unknown[]) => {
|
|
40
|
+
received.push(params);
|
|
41
|
+
return { changes: 1 };
|
|
42
|
+
},
|
|
43
|
+
get: (...params: unknown[]) => {
|
|
44
|
+
received.push(params);
|
|
45
|
+
return undefined;
|
|
46
|
+
},
|
|
47
|
+
all: (...params: unknown[]) => {
|
|
48
|
+
received.push(params);
|
|
49
|
+
return [];
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
const rawDb = {
|
|
53
|
+
exec: () => {},
|
|
54
|
+
prepare: () => rawStatement,
|
|
55
|
+
close: () => {},
|
|
56
|
+
};
|
|
57
|
+
const adapter = createDbAdapter(rawDb);
|
|
58
|
+
const stmt = adapter.prepare("INSERT INTO t (version, applied_at) VALUES (:version, :applied_at)");
|
|
59
|
+
|
|
60
|
+
stmt.run({ ":version": 1, "@name": "a", "$flag": true, bare: "kept" });
|
|
61
|
+
assert.deepEqual(received.pop(), [{ version: 1, name: "a", flag: true, bare: "kept" }]);
|
|
62
|
+
|
|
63
|
+
// Non-binding params pass through untouched: positional scalars, arrays,
|
|
64
|
+
// and binary blobs must not be treated as named-binding objects.
|
|
65
|
+
const blob = new Uint8Array([1, 2, 3]);
|
|
66
|
+
stmt.get("T01", blob);
|
|
67
|
+
const passthrough = received.pop() as unknown[];
|
|
68
|
+
assert.equal(passthrough[0], "T01");
|
|
69
|
+
assert.equal(passthrough[1], blob);
|
|
70
|
+
|
|
71
|
+
stmt.all({ plain: "unchanged" });
|
|
72
|
+
assert.deepEqual(received.pop(), [{ plain: "unchanged" }]);
|
|
73
|
+
});
|
|
74
|
+
|
|
36
75
|
test("createDbAdapter caches prepared statements and clears cache on close", () => {
|
|
37
76
|
const calls: unknown[] = [];
|
|
38
77
|
const rawStatement = {
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// gsd-pi — DB writability probe regression tests (#1234).
|
|
2
|
+
//
|
|
3
|
+
// Auto-start's DB gate only checked that the provider opened, not that the
|
|
4
|
+
// handle can actually write. A schema-current DB does zero writes during open,
|
|
5
|
+
// so a read-only / DBMOVED handle passed the open-only check and failed much
|
|
6
|
+
// later at the first authoritative write with an opaque "readonly database"
|
|
7
|
+
// error. `probeDbWritable` forces a real page write so that failure class is
|
|
8
|
+
// caught at the natural checkpoint.
|
|
9
|
+
|
|
10
|
+
import { test } from "node:test";
|
|
11
|
+
import assert from "node:assert/strict";
|
|
12
|
+
import { mkdtempSync, mkdirSync, rmSync } from "node:fs";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { tmpdir } from "node:os";
|
|
15
|
+
|
|
16
|
+
import { openDatabase, closeDatabase, probeDbWritable, _getAdapter } from "../gsd-db.ts";
|
|
17
|
+
import type { DbAdapter } from "../db-adapter.ts";
|
|
18
|
+
|
|
19
|
+
function makeBase(): string {
|
|
20
|
+
const dir = mkdtempSync(join(tmpdir(), "gsd-db-writable-probe-"));
|
|
21
|
+
mkdirSync(join(dir, ".gsd"), { recursive: true });
|
|
22
|
+
return dir;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
test("probeDbWritable succeeds against a freshly opened writable database", () => {
|
|
26
|
+
const base = makeBase();
|
|
27
|
+
assert.equal(openDatabase(join(base, ".gsd", "gsd.db")), true);
|
|
28
|
+
try {
|
|
29
|
+
assert.deepEqual(probeDbWritable(), { ok: true });
|
|
30
|
+
} finally {
|
|
31
|
+
closeDatabase();
|
|
32
|
+
rmSync(base, { recursive: true, force: true });
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("probeDbWritable reports not-ok with detail when no database is open", () => {
|
|
37
|
+
closeDatabase();
|
|
38
|
+
const result = probeDbWritable();
|
|
39
|
+
assert.equal(result.ok, false);
|
|
40
|
+
assert.match(result.detail ?? "", /No database is open/u);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("probeDbWritable reports not-ok when the page write fails (simulating a read-only handle)", () => {
|
|
44
|
+
const base = makeBase();
|
|
45
|
+
assert.equal(openDatabase(join(base, ".gsd", "gsd.db")), true);
|
|
46
|
+
const adapter = _getAdapter() as DbAdapter;
|
|
47
|
+
assert.ok(adapter);
|
|
48
|
+
|
|
49
|
+
// The read (prepare/get) still works; only the page-dirtying write throws,
|
|
50
|
+
// mirroring SQLITE_READONLY_DBMOVED which fails once a page is dirtied.
|
|
51
|
+
const origExec = adapter.exec.bind(adapter);
|
|
52
|
+
adapter.exec = (sql: string): void => {
|
|
53
|
+
if (sql.includes("user_version =")) throw new Error("attempt to write a readonly database");
|
|
54
|
+
return origExec(sql);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const result = probeDbWritable();
|
|
59
|
+
assert.equal(result.ok, false);
|
|
60
|
+
assert.match(result.detail ?? "", /readonly database/u);
|
|
61
|
+
} finally {
|
|
62
|
+
adapter.exec = origExec;
|
|
63
|
+
closeDatabase();
|
|
64
|
+
rmSync(base, { recursive: true, force: true });
|
|
65
|
+
}
|
|
66
|
+
});
|
|
@@ -1034,6 +1034,10 @@ describe('derive-state-db', async () => {
|
|
|
1034
1034
|
|
|
1035
1035
|
assert.deepStrictEqual(dbState.phase, 'replanning-slice', 'replan-db: phase is replanning-slice');
|
|
1036
1036
|
assert.deepStrictEqual(dbState.phase, fileState.phase, 'replan-db: phase matches filesystem');
|
|
1037
|
+
assert.ok(
|
|
1038
|
+
Object.hasOwn(dbState, 'activeWorkspace'),
|
|
1039
|
+
'replan-db: state preserves explicit activeWorkspace field for auto-loop consumers',
|
|
1040
|
+
);
|
|
1037
1041
|
|
|
1038
1042
|
closeDatabase();
|
|
1039
1043
|
} finally {
|
|
@@ -428,6 +428,52 @@ test("checkEngineHealth repair prunes stale phases artifact rows with present mi
|
|
|
428
428
|
assert.deepEqual(rows.map((row) => row.path), []);
|
|
429
429
|
});
|
|
430
430
|
|
|
431
|
+
test("checkEngineHealth repair keeps phases rows whose own file is still present", async (t) => {
|
|
432
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-keep-present-phase-artifact-"));
|
|
433
|
+
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
434
|
+
|
|
435
|
+
const gsdDir = join(base, ".gsd");
|
|
436
|
+
const livePath = "phases/01-m001/01-01-PLAN.md";
|
|
437
|
+
const replacementPath = "milestones/M001/slices/S01/S01-PLAN.md";
|
|
438
|
+
// Both the active phases/ file AND a legacy milestones/ copy exist on disk.
|
|
439
|
+
// The row is "fixable" (a milestones replacement is present), but its own
|
|
440
|
+
// file is present too — repair must not drop the live row.
|
|
441
|
+
mkdirSync(join(gsdDir, "phases", "01-m001"), { recursive: true });
|
|
442
|
+
writeFileSync(join(gsdDir, livePath), "# Plan\n", "utf-8");
|
|
443
|
+
mkdirSync(join(gsdDir, "milestones", "M001", "slices", "S01"), { recursive: true });
|
|
444
|
+
writeFileSync(join(gsdDir, replacementPath), "# Plan\n", "utf-8");
|
|
445
|
+
|
|
446
|
+
openDatabase(join(gsdDir, "gsd.db"));
|
|
447
|
+
insertArtifact({
|
|
448
|
+
path: livePath,
|
|
449
|
+
artifact_type: "PLAN",
|
|
450
|
+
milestone_id: "M001",
|
|
451
|
+
slice_id: "S01",
|
|
452
|
+
task_id: null,
|
|
453
|
+
full_content: "# plan\n",
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
const issues: any[] = [];
|
|
457
|
+
const fixes: string[] = [];
|
|
458
|
+
await checkEngineHealth(base, issues, fixes, { repair: true });
|
|
459
|
+
|
|
460
|
+
assert.equal(
|
|
461
|
+
fixes.some((fix) => fix.includes(livePath)),
|
|
462
|
+
false,
|
|
463
|
+
"repair must not prune a row whose own file is present on disk",
|
|
464
|
+
);
|
|
465
|
+
assert.equal(
|
|
466
|
+
issues.some((issue) => issue.code === "artifact_file_missing" && issue.file === livePath),
|
|
467
|
+
false,
|
|
468
|
+
"a present artifact must not be reported missing",
|
|
469
|
+
);
|
|
470
|
+
|
|
471
|
+
const rows = _getAdapter()!
|
|
472
|
+
.prepare("SELECT path FROM artifacts ORDER BY path")
|
|
473
|
+
.all() as Array<{ path: string }>;
|
|
474
|
+
assert.deepEqual(rows.map((row) => row.path), [livePath]);
|
|
475
|
+
});
|
|
476
|
+
|
|
431
477
|
test("checkEngineHealth repair prunes stale phases task rows against tasks/<T>-<TYPE>.md replacements", async (t) => {
|
|
432
478
|
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-prune-stale-task-phase-artifact-"));
|
|
433
479
|
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
@@ -540,6 +586,134 @@ test("checkEngineHealth marks escaped phases rows fixable when a milestones repl
|
|
|
540
586
|
assert.equal(issue.fixable, true, "escaped phases rows with a milestones replacement must be marked fixable");
|
|
541
587
|
});
|
|
542
588
|
|
|
589
|
+
test("checkEngineHealth resolves legacy milestones rows through flat-phase files", async (t) => {
|
|
590
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-flat-fallback-"));
|
|
591
|
+
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
592
|
+
|
|
593
|
+
const gsdDir = join(base, ".gsd");
|
|
594
|
+
const flatPath = "phases/01-foundation/01-01-PLAN.md";
|
|
595
|
+
const legacyPath = "milestones/M001/slices/S01/S01-PLAN.md";
|
|
596
|
+
mkdirSync(join(gsdDir, "phases", "01-foundation"), { recursive: true });
|
|
597
|
+
writeFileSync(join(gsdDir, flatPath), "# Plan\n", "utf-8");
|
|
598
|
+
|
|
599
|
+
openDatabase(join(gsdDir, "gsd.db"));
|
|
600
|
+
insertArtifact({
|
|
601
|
+
path: legacyPath,
|
|
602
|
+
artifact_type: "PLAN",
|
|
603
|
+
milestone_id: "M001",
|
|
604
|
+
slice_id: "S01",
|
|
605
|
+
task_id: null,
|
|
606
|
+
full_content: "# legacy plan row\n",
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
const issues: any[] = [];
|
|
610
|
+
await checkEngineHealth(base, issues, []);
|
|
611
|
+
|
|
612
|
+
assert.equal(
|
|
613
|
+
issues.some((issue) => issue.code === "artifact_file_missing" && issue.file === legacyPath),
|
|
614
|
+
false,
|
|
615
|
+
"legacy milestones rows should not be reported missing when the flat-phase file exists",
|
|
616
|
+
);
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
test("checkEngineHealth repair prunes stale milestones rows with present flat-phase files", async (t) => {
|
|
620
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-prune-stale-legacy-artifact-"));
|
|
621
|
+
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
622
|
+
|
|
623
|
+
const gsdDir = join(base, ".gsd");
|
|
624
|
+
const flatPath = "phases/01-foundation/01-01-PLAN.md";
|
|
625
|
+
const stalePath = "milestones/M001/slices/S01/S01-PLAN.md";
|
|
626
|
+
mkdirSync(join(gsdDir, "phases", "01-foundation"), { recursive: true });
|
|
627
|
+
writeFileSync(join(gsdDir, flatPath), "# Plan\n", "utf-8");
|
|
628
|
+
|
|
629
|
+
openDatabase(join(gsdDir, "gsd.db"));
|
|
630
|
+
insertArtifact({
|
|
631
|
+
path: stalePath,
|
|
632
|
+
artifact_type: "PLAN",
|
|
633
|
+
milestone_id: "M001",
|
|
634
|
+
slice_id: "S01",
|
|
635
|
+
task_id: null,
|
|
636
|
+
full_content: "# stale plan row\n",
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
const issues: any[] = [];
|
|
640
|
+
const fixes: string[] = [];
|
|
641
|
+
await checkEngineHealth(base, issues, fixes, { repair: true });
|
|
642
|
+
|
|
643
|
+
assert.equal(
|
|
644
|
+
issues.some((issue) => issue.code === "artifact_file_missing" && issue.file === stalePath),
|
|
645
|
+
false,
|
|
646
|
+
"repair should not report stale legacy rows it pruned",
|
|
647
|
+
);
|
|
648
|
+
assert.ok(fixes.includes(`pruned stale legacy artifact row ${stalePath}`));
|
|
649
|
+
|
|
650
|
+
const rows = _getAdapter()!
|
|
651
|
+
.prepare("SELECT path FROM artifacts ORDER BY path")
|
|
652
|
+
.all() as Array<{ path: string }>;
|
|
653
|
+
assert.deepEqual(rows.map((row) => row.path), []);
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
test("checkEngineHealth marks stale milestones task rows without flat files fixable", async (t) => {
|
|
657
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-fixable-stale-legacy-task-artifact-"));
|
|
658
|
+
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
659
|
+
|
|
660
|
+
const gsdDir = join(base, ".gsd");
|
|
661
|
+
const stalePath = "milestones/M001/slices/S01/tasks/T01-PLAN.md";
|
|
662
|
+
mkdirSync(join(gsdDir, "phases", "01-foundation"), { recursive: true });
|
|
663
|
+
|
|
664
|
+
openDatabase(join(gsdDir, "gsd.db"));
|
|
665
|
+
insertArtifact({
|
|
666
|
+
path: stalePath,
|
|
667
|
+
artifact_type: "PLAN",
|
|
668
|
+
milestone_id: "M001",
|
|
669
|
+
slice_id: "S01",
|
|
670
|
+
task_id: "T01",
|
|
671
|
+
full_content: "# stale task plan row\n",
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
const issues: any[] = [];
|
|
675
|
+
await checkEngineHealth(base, issues, []);
|
|
676
|
+
|
|
677
|
+
const issue = issues.find((candidate) => candidate.code === "artifact_file_missing" && candidate.file === stalePath);
|
|
678
|
+
assert.ok(issue, "missing stale legacy task row should still be reported when repair is off");
|
|
679
|
+
assert.equal(issue.fixable, true, "stale legacy task rows without flat files should be fixable");
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
test("checkEngineHealth repair prunes stale milestones task rows without flat files", async (t) => {
|
|
683
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-prune-stale-legacy-task-artifact-"));
|
|
684
|
+
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
685
|
+
|
|
686
|
+
const gsdDir = join(base, ".gsd");
|
|
687
|
+
const stalePath = "milestones/M001/slices/S01/tasks/T01-PLAN.md";
|
|
688
|
+
mkdirSync(join(gsdDir, "phases", "01-foundation"), { recursive: true });
|
|
689
|
+
|
|
690
|
+
openDatabase(join(gsdDir, "gsd.db"));
|
|
691
|
+
insertArtifact({
|
|
692
|
+
path: stalePath,
|
|
693
|
+
artifact_type: "PLAN",
|
|
694
|
+
milestone_id: "M001",
|
|
695
|
+
slice_id: "S01",
|
|
696
|
+
task_id: "T01",
|
|
697
|
+
full_content: "# stale task plan row\n",
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
const issues: any[] = [];
|
|
701
|
+
const fixes: string[] = [];
|
|
702
|
+
await checkEngineHealth(base, issues, fixes, { repair: true });
|
|
703
|
+
|
|
704
|
+
assert.equal(
|
|
705
|
+
issues.some((issue) => issue.code === "artifact_file_missing" && issue.file === stalePath),
|
|
706
|
+
false,
|
|
707
|
+
"repair should prune stale legacy task rows that have no flat file representation",
|
|
708
|
+
);
|
|
709
|
+
assert.ok(fixes.includes(`pruned stale legacy artifact row ${stalePath}`));
|
|
710
|
+
|
|
711
|
+
const rows = _getAdapter()!
|
|
712
|
+
.prepare("SELECT path FROM artifacts ORDER BY path")
|
|
713
|
+
.all() as Array<{ path: string }>;
|
|
714
|
+
assert.deepEqual(rows.map((row) => row.path), []);
|
|
715
|
+
});
|
|
716
|
+
|
|
543
717
|
function taskSummary(id: string, verificationResult = "passed"): string {
|
|
544
718
|
return [
|
|
545
719
|
"---",
|
|
@@ -13,7 +13,7 @@ import { basename, join } from "node:path";
|
|
|
13
13
|
import {
|
|
14
14
|
fastForwardReusedMilestoneBranchIfSafe,
|
|
15
15
|
_isBranchCheckedOutElsewhere,
|
|
16
|
-
} from "../auto-worktree.js";
|
|
16
|
+
} from "../auto-worktree-branch-lifecycle.js";
|
|
17
17
|
|
|
18
18
|
const NO_PROMPT_ENV = {
|
|
19
19
|
...process.env,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
needsFlatPhaseMigration,
|
|
14
14
|
pruneStaleFlatPhaseBackups,
|
|
15
15
|
} from "../flat-phase-migration.ts";
|
|
16
|
-
import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertTask, getAllMilestones, getMilestoneSlices, getSliceTasks } from "../gsd-db.ts";
|
|
16
|
+
import { openDatabase, closeDatabase, insertArtifact, insertMilestone, insertSlice, insertTask, getAllMilestones, getMilestoneSlices, getSliceTasks, _getAdapter } from "../gsd-db.ts";
|
|
17
17
|
|
|
18
18
|
const tmpDirs: string[] = [];
|
|
19
19
|
function makeTmp(options: { withTask?: boolean } = {}): string {
|
|
@@ -109,6 +109,33 @@ test("migrateToFlatPhase creates a backup", async () => {
|
|
|
109
109
|
assert.ok(backups.length >= 1, "at least one migrate-* backup dir should exist");
|
|
110
110
|
});
|
|
111
111
|
|
|
112
|
+
test("failed migration rolls back without leaking a .gsd-backups/migrate-* dir", async (t) => {
|
|
113
|
+
const base = makeTmp();
|
|
114
|
+
const milestonesPath = join(base, ".gsd", "milestones");
|
|
115
|
+
const phasesPath = join(base, ".gsd", "phases");
|
|
116
|
+
|
|
117
|
+
// Fail the pre-render clear of phases/ to drive the rollback path, which by
|
|
118
|
+
// this point has already created the .gsd-backups/migrate-<ts>/ backup.
|
|
119
|
+
const restoreFsOps = _setFlatPhaseMigrationFsOpsForTest({
|
|
120
|
+
rmSync(target, opts) {
|
|
121
|
+
if (target === phasesPath) {
|
|
122
|
+
throw Object.assign(new Error("simulated locked phases/"), { code: "EPERM" });
|
|
123
|
+
}
|
|
124
|
+
return rmSync(target, opts as never);
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
t.after(restoreFsOps);
|
|
128
|
+
|
|
129
|
+
await assert.rejects(migrateToFlatPhase(base), /simulated locked/);
|
|
130
|
+
|
|
131
|
+
assert.ok(existsSync(milestonesPath), "legacy milestones/ should be restored on rollback");
|
|
132
|
+
const backupRoot = join(base, ".gsd-backups");
|
|
133
|
+
const leaked = existsSync(backupRoot)
|
|
134
|
+
? readdirSync(backupRoot).filter((d) => d.startsWith("migrate-"))
|
|
135
|
+
: [];
|
|
136
|
+
assert.equal(leaked.length, 0, "rollback must delete the migrate-* backup it created");
|
|
137
|
+
});
|
|
138
|
+
|
|
112
139
|
test("migrateToFlatPhase preserves milestone/slice/task counts in DB", async () => {
|
|
113
140
|
const base = makeTmp();
|
|
114
141
|
const msBefore = getAllMilestones().length;
|
|
@@ -120,6 +147,49 @@ test("migrateToFlatPhase preserves milestone/slice/task counts in DB", async ()
|
|
|
120
147
|
assert.equal(getSliceTasks("M001", "S01").length, tasksBefore);
|
|
121
148
|
});
|
|
122
149
|
|
|
150
|
+
test("migrateToFlatPhase prunes legacy milestones artifact rows after flat render", async () => {
|
|
151
|
+
const base = makeTmp();
|
|
152
|
+
insertArtifact({
|
|
153
|
+
path: "milestones/M001/M001-ROADMAP.md",
|
|
154
|
+
artifact_type: "ROADMAP",
|
|
155
|
+
milestone_id: "M001",
|
|
156
|
+
slice_id: null,
|
|
157
|
+
task_id: null,
|
|
158
|
+
full_content: "# M001: Foundation\n",
|
|
159
|
+
});
|
|
160
|
+
insertArtifact({
|
|
161
|
+
path: "milestones/M001/slices/S01/S01-PLAN.md",
|
|
162
|
+
artifact_type: "PLAN",
|
|
163
|
+
milestone_id: "M001",
|
|
164
|
+
slice_id: "S01",
|
|
165
|
+
task_id: null,
|
|
166
|
+
full_content: "# Plan\n",
|
|
167
|
+
});
|
|
168
|
+
insertArtifact({
|
|
169
|
+
path: "milestones/M001/slices/S01/tasks/T01-PLAN.md",
|
|
170
|
+
artifact_type: "PLAN",
|
|
171
|
+
milestone_id: "M001",
|
|
172
|
+
slice_id: "S01",
|
|
173
|
+
task_id: "T01",
|
|
174
|
+
full_content: "# Task Plan\n",
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
await migrateToFlatPhase(base);
|
|
178
|
+
|
|
179
|
+
const rows = _getAdapter()!
|
|
180
|
+
.prepare("SELECT path FROM artifacts ORDER BY path")
|
|
181
|
+
.all() as Array<{ path: string }>;
|
|
182
|
+
assert.equal(
|
|
183
|
+
rows.some((row) => row.path.startsWith("milestones/")),
|
|
184
|
+
false,
|
|
185
|
+
"legacy milestones/ artifact rows should be pruned after successful flat migration",
|
|
186
|
+
);
|
|
187
|
+
assert.ok(
|
|
188
|
+
rows.some((row) => row.path.startsWith("phases/")),
|
|
189
|
+
"flat-phase render should leave replacement projection rows in the artifacts table",
|
|
190
|
+
);
|
|
191
|
+
});
|
|
192
|
+
|
|
123
193
|
test("migrateToFlatPhase is idempotent (second run is a no-op)", async () => {
|
|
124
194
|
const base = makeTmp();
|
|
125
195
|
await migrateToFlatPhase(base);
|
|
@@ -7,7 +7,8 @@ import { join } from "node:path";
|
|
|
7
7
|
import { tmpdir } from "node:os";
|
|
8
8
|
import { randomUUID } from "node:crypto";
|
|
9
9
|
|
|
10
|
-
import { renderPlanFromDb, renderRoadmapFromDb } from "../markdown-renderer.ts";
|
|
10
|
+
import { renderPlanFromDb, renderRoadmapFromDb, renderAssessmentFromDb, renderReplanFromDb } from "../markdown-renderer.ts";
|
|
11
|
+
import { clearPathCache } from "../paths.ts";
|
|
11
12
|
import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertTask } from "../gsd-db.ts";
|
|
12
13
|
|
|
13
14
|
const tmpDirs: string[] = [];
|
|
@@ -81,3 +82,47 @@ test("renderPlanFromDb does NOT write per-task plan files", async () => {
|
|
|
81
82
|
// taskPlanPaths should be empty — no per-task files written
|
|
82
83
|
assert.equal(result.taskPlanPaths.length, 0);
|
|
83
84
|
});
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
// Replan uses the same slice-level target rules as assessment: flat-phase
|
|
88
|
+
// writes must stay at the phase root even if an old slices/SID/ dir exists.
|
|
89
|
+
test("renderReplanFromDb writes to the phase root even when a stray slices/SID/ dir exists", async () => {
|
|
90
|
+
const base = makeTmp();
|
|
91
|
+
const plan = await renderPlanFromDb(base, "M001", "S01");
|
|
92
|
+
const phaseDir = plan.planPath.slice(0, plan.planPath.lastIndexOf("01-01-PLAN.md"));
|
|
93
|
+
mkdirSync(join(phaseDir, "slices", "S01"), { recursive: true });
|
|
94
|
+
clearPathCache();
|
|
95
|
+
|
|
96
|
+
const result = await renderReplanFromDb(base, "M001", "S01", {
|
|
97
|
+
blockerTaskId: "T01",
|
|
98
|
+
blockerDescription: "Need a better path target.",
|
|
99
|
+
whatChanged: "Centralized slice writer path resolution.",
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
assert.match(result.replanPath, /phases[/\\]01-[^/\\]+[/\\]01-01-REPLAN\.md$/);
|
|
103
|
+
assert.ok(!result.replanPath.includes(join("slices", "S01")), "must not write under slices/S01/");
|
|
104
|
+
assert.ok(existsSync(result.replanPath), "replan file should exist at the phase root");
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Regression for #1190: a stray slices/SID/ subdir inside a flat-phase milestone
|
|
108
|
+
// must not divert the ASSESSMENT write into slices/SID/ (a hybrid path that
|
|
109
|
+
// auto-mode verification cannot find). It must land at the phase root.
|
|
110
|
+
test("renderAssessmentFromDb writes to the phase root even when a stray slices/SID/ dir exists", async () => {
|
|
111
|
+
const base = makeTmp();
|
|
112
|
+
const plan = await renderPlanFromDb(base, "M001", "S01");
|
|
113
|
+
const phaseDir = plan.planPath.slice(0, plan.planPath.lastIndexOf("01-01-PLAN.md"));
|
|
114
|
+
|
|
115
|
+
// Simulate the anomaly: an earlier planning step created slices/S01/ inside
|
|
116
|
+
// the flat-phase dir.
|
|
117
|
+
mkdirSync(join(phaseDir, "slices", "S01"), { recursive: true });
|
|
118
|
+
clearPathCache();
|
|
119
|
+
|
|
120
|
+
const result = await renderAssessmentFromDb(base, "M001", "S01", {
|
|
121
|
+
verdict: "on-track",
|
|
122
|
+
assessment: "Roadmap is on track.",
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
assert.match(result.assessmentPath, /phases[/\\]01-[^/\\]+[/\\]01-01-ASSESSMENT\.md$/);
|
|
126
|
+
assert.ok(!result.assessmentPath.includes(join("slices", "S01")), "must not write under slices/S01/");
|
|
127
|
+
assert.ok(existsSync(result.assessmentPath), "assessment file should exist at the phase root");
|
|
128
|
+
});
|