@opengsd/gsd-pi 1.5.0 → 1.6.0
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 +4 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +29 -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 +106 -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/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/rule-registry.js +106 -10
- 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 +13 -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 +29 -0
- package/dist/resources/extensions/shared/interview-ui.js +62 -9
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- 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.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +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/resize/route.js.nft.json +1 -1
- 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/captures/route.js.nft.json +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/doctor/route.js.nft.json +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/files/route.js.nft.json +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/git/route.js.nft.json +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/hooks/route.js.nft.json +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/knowledge/route.js.nft.json +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/mcp-connections/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +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/projects/route.js.nft.json +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/session/browser/route.js.nft.json +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/events/route.js.nft.json +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/settings-data/route.js.nft.json +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/skill-health/route.js.nft.json +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/switch-root/route.js.nft.json +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/stream/route.js.nft.json +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/visualizer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
- package/dist/web/standalone/.next/server/chunks/{1128.js → 1991.js} +1 -1
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +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/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 +4 -4
- 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/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 +25 -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 +4 -2
- package/src/resources/extensions/gsd/auto-prompts.ts +53 -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 +114 -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/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/rule-registry.ts +111 -9
- 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/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-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/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 +13 -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 +29 -0
- 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/{bCg3aYrFN1DKZr2dqgE7L → 6xYMOzxVhsQgryneJ5KRc}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{bCg3aYrFN1DKZr2dqgE7L → 6xYMOzxVhsQgryneJ5KRc}/_ssgManifest.js +0 -0
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// Exports: parseDecisionsTable, parseRequirementsSections, migrateFromMarkdown
|
|
6
6
|
|
|
7
7
|
import { readFileSync, readdirSync, existsSync, statSync } from 'node:fs';
|
|
8
|
-
import { join, relative, basename } from 'node:path';
|
|
8
|
+
import { join, relative, basename, dirname } from 'node:path';
|
|
9
9
|
import type { Decision, Requirement } from './types.js';
|
|
10
10
|
import {
|
|
11
11
|
upsertDecision,
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
resolveGsdRootFile,
|
|
25
25
|
resolveMilestoneFile,
|
|
26
26
|
resolveSliceFile,
|
|
27
|
+
resolveSlicePath,
|
|
27
28
|
resolveTasksDir,
|
|
28
29
|
legacyMilestonesDir,
|
|
29
30
|
gsdRoot,
|
|
@@ -33,7 +34,7 @@ import {
|
|
|
33
34
|
import { findMilestoneIds } from './guided-flow.js';
|
|
34
35
|
import { milestoneIdToPhaseNum } from './layout-policy.js';
|
|
35
36
|
import { parseRoadmap, parsePlan } from './parsers-legacy.js';
|
|
36
|
-
import { parseContextDependsOn } from './files.js';
|
|
37
|
+
import { parseContextDependsOn, parseSummary } from './files.js';
|
|
37
38
|
import { logWarning } from './workflow-logger.js';
|
|
38
39
|
|
|
39
40
|
// ─── DECISIONS.md Parser ───────────────────────────────────────────────────
|
|
@@ -816,23 +817,68 @@ export function migrateHierarchyToDb(basePath: string): {
|
|
|
816
817
|
// Per K002: use 'complete' not 'done'
|
|
817
818
|
let taskStatus: string = taskEntry.done ? 'complete' : 'pending';
|
|
818
819
|
|
|
819
|
-
//
|
|
820
|
-
//
|
|
821
|
-
//
|
|
822
|
-
//
|
|
823
|
-
//
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
820
|
+
// Resolve the per-task SUMMARY.md. Legacy layout keeps summaries under
|
|
821
|
+
// a tasks/ subdir; flat-phase writes TID-SUMMARY.md directly in the
|
|
822
|
+
// phase dir (execute-task's gsd_task_complete writes it there). A tasks/
|
|
823
|
+
// subdir may still exist in flat-phase for auxiliary artifacts — its
|
|
824
|
+
// mere existence must NOT redirect summary resolution into tasks/ (#1208).
|
|
825
|
+
const slicePath = resolveSlicePath(basePath, milestoneId, sliceEntry.id);
|
|
826
|
+
let taskSummaryFile: string | null = null;
|
|
827
|
+
let isLegacySlice = false;
|
|
828
|
+
// Legacy layout keeps per-task summaries under a tasks/ subdir. Its
|
|
829
|
+
// presence — not merely "is this a legacy slice" — is what makes a
|
|
830
|
+
// missing summary a downgrade signal. resolveTasksDir returns null when
|
|
831
|
+
// no such dir exists, so a legacy slice whose checkbox is the only
|
|
832
|
+
// completion signal (no tasks/ dir at all) is left complete on import.
|
|
833
|
+
let legacyTasksDir: string | null = null;
|
|
834
|
+
if (slicePath) {
|
|
835
|
+
isLegacySlice = basename(dirname(slicePath)) === 'slices';
|
|
836
|
+
legacyTasksDir = isLegacySlice
|
|
837
|
+
? resolveTasksDir(basePath, milestoneId, sliceEntry.id)
|
|
838
|
+
: null;
|
|
839
|
+
const summaryDir = legacyTasksDir ?? slicePath;
|
|
840
|
+
taskSummaryFile = join(summaryDir, `${taskEntry.id}-SUMMARY.md`);
|
|
841
|
+
}
|
|
842
|
+
const hasTaskSummary = taskSummaryFile !== null && existsSync(taskSummaryFile);
|
|
843
|
+
|
|
844
|
+
// Pre-migration consistency (legacy tasks/ layout only): if a task is
|
|
845
|
+
// marked done but its tasks/ dir has no per-task SUMMARY.md, import it
|
|
846
|
+
// as pending so it gets re-executed rather than silently entering the DB
|
|
847
|
+
// as complete. A legacy slice with no tasks/ dir (checkbox-only
|
|
848
|
+
// completion) and flat-phase layout are both left as-is here.
|
|
849
|
+
if (taskStatus === 'complete' && legacyTasksDir !== null && !hasTaskSummary) {
|
|
850
|
+
taskStatus = 'pending';
|
|
851
|
+
process.stderr.write(
|
|
852
|
+
`gsd-migrate: ${milestoneId}/${sliceEntry.id}/${taskEntry.id} marked done but missing summary — importing as pending\n`,
|
|
853
|
+
);
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
// Lost-update guard (#1222): a per-task SUMMARY.md is the durable
|
|
857
|
+
// completion attestation written by gsd_task_complete. When the plan
|
|
858
|
+
// checkbox is stale-unchecked but the SUMMARY exists on disk, a
|
|
859
|
+
// re-import must NOT downgrade the completed task back to pending — that
|
|
860
|
+
// silent revert is the lost-update that hard-stopped auto-mode after the
|
|
861
|
+
// first execute-task. The surviving SUMMARY wins over a stale checkbox.
|
|
862
|
+
// reopen-task removes the SUMMARY, so this never re-completes an
|
|
863
|
+
// intentionally reopened task.
|
|
864
|
+
// Flat-phase summaries are phase-scoped (T01-SUMMARY.md); when a milestone
|
|
865
|
+
// has multiple slices, require the summary parent frontmatter to match so
|
|
866
|
+
// one slice's completion does not attest a sibling's same-named task.
|
|
867
|
+
let summaryAttestsCompletion = hasTaskSummary;
|
|
868
|
+
if (summaryAttestsCompletion && !isLegacySlice && roadmap.slices.length > 1 && taskSummaryFile) {
|
|
869
|
+
try {
|
|
870
|
+
const summaryContent = readFileSync(taskSummaryFile, 'utf-8');
|
|
871
|
+
summaryAttestsCompletion = parseSummary(summaryContent).frontmatter.parent === sliceEntry.id;
|
|
872
|
+
} catch {
|
|
873
|
+
summaryAttestsCompletion = false;
|
|
834
874
|
}
|
|
835
875
|
}
|
|
876
|
+
if (taskStatus === 'pending' && summaryAttestsCompletion) {
|
|
877
|
+
taskStatus = 'complete';
|
|
878
|
+
process.stderr.write(
|
|
879
|
+
`gsd-migrate: ${milestoneId}/${sliceEntry.id}/${taskEntry.id} unchecked in plan but SUMMARY.md present — importing as complete (#1222)\n`,
|
|
880
|
+
);
|
|
881
|
+
}
|
|
836
882
|
|
|
837
883
|
insertTask({
|
|
838
884
|
id: taskEntry.id,
|
|
@@ -844,6 +890,12 @@ export function migrateHierarchyToDb(basePath: string): {
|
|
|
844
890
|
files: taskEntry.files ?? [],
|
|
845
891
|
verify: taskEntry.verify ?? '',
|
|
846
892
|
},
|
|
893
|
+
// #1222 (metadata half): re-import derives status from the plan/summary
|
|
894
|
+
// but has none of the execution prose gsd_task_complete wrote to the DB.
|
|
895
|
+
// Preserve the existing row's execution columns and completed_at so a
|
|
896
|
+
// re-import cannot blank a completed task's summary metadata or refresh
|
|
897
|
+
// its completion timestamp — the DB row is strictly richer than the plan.
|
|
898
|
+
preserveCompletionMetadata: true,
|
|
847
899
|
});
|
|
848
900
|
counts.tasks++;
|
|
849
901
|
}
|
|
@@ -857,12 +909,31 @@ export function migrateHierarchyToDb(basePath: string): {
|
|
|
857
909
|
if (!sliceEntry.done) {
|
|
858
910
|
const sliceSummaryPath = resolveSliceFile(basePath, milestoneId, sliceEntry.id, 'SUMMARY');
|
|
859
911
|
const hasSliceSummary = sliceSummaryPath !== null && existsSync(sliceSummaryPath);
|
|
912
|
+
const slicePathForTasks = resolveSlicePath(basePath, milestoneId, sliceEntry.id);
|
|
913
|
+
const isLegacySliceLayout = slicePathForTasks !== null
|
|
914
|
+
&& basename(dirname(slicePathForTasks)) === 'slices';
|
|
915
|
+
const taskSummaryDir = slicePathForTasks
|
|
916
|
+
? (isLegacySliceLayout
|
|
917
|
+
? (resolveTasksDir(basePath, milestoneId, sliceEntry.id) ?? slicePathForTasks)
|
|
918
|
+
: slicePathForTasks)
|
|
919
|
+
: null;
|
|
860
920
|
const allTasksDone = plan.tasks.length > 0 && plan.tasks.every(t => {
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
921
|
+
const taskSummaryFile = taskSummaryDir !== null
|
|
922
|
+
? join(taskSummaryDir, `${t.id}-SUMMARY.md`)
|
|
923
|
+
: null;
|
|
924
|
+
const hasTaskSummary = taskSummaryFile !== null && existsSync(taskSummaryFile);
|
|
925
|
+
let summaryAttestsCompletion = hasTaskSummary;
|
|
926
|
+
if (summaryAttestsCompletion && !isLegacySliceLayout && roadmap.slices.length > 1 && taskSummaryFile) {
|
|
927
|
+
try {
|
|
928
|
+
const summaryContent = readFileSync(taskSummaryFile, 'utf-8');
|
|
929
|
+
summaryAttestsCompletion = parseSummary(summaryContent).frontmatter.parent === sliceEntry.id;
|
|
930
|
+
} catch {
|
|
931
|
+
summaryAttestsCompletion = false;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
// Match per-task import rules above: SUMMARY attestation wins over a stale
|
|
935
|
+
// checkbox (#1222); flat-phase checkboxes are authoritative without summary.
|
|
936
|
+
return summaryAttestsCompletion || (t.done && !isLegacySliceLayout);
|
|
866
937
|
});
|
|
867
938
|
if (allTasksDone && hasSliceSummary) {
|
|
868
939
|
if (_getAdapter()) {
|
|
@@ -265,7 +265,7 @@ export function snapshotUnitMetrics(
|
|
|
265
265
|
}
|
|
266
266
|
saveLedger(basePath, ledger);
|
|
267
267
|
|
|
268
|
-
if (isUnifiedAuditEnabled()) {
|
|
268
|
+
if (isUnifiedAuditEnabled(basePath)) {
|
|
269
269
|
emitUokAuditEvent(
|
|
270
270
|
basePath,
|
|
271
271
|
buildAuditEnvelope({
|
|
@@ -458,7 +458,7 @@ export function snapshotUnitMetricsByScope(
|
|
|
458
458
|
}
|
|
459
459
|
saveLedger(base, scopedLedger);
|
|
460
460
|
|
|
461
|
-
if (isUnifiedAuditEnabled()) {
|
|
461
|
+
if (isUnifiedAuditEnabled(base)) {
|
|
462
462
|
emitUokAuditEvent(
|
|
463
463
|
base,
|
|
464
464
|
buildAuditEnvelope({
|
|
@@ -102,13 +102,41 @@ function replaceSetPrefix(values: Set<string>, from: string, to: string): void {
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Rewrite one milestone identity across EVERY markdown identity set. The
|
|
107
|
+
* roadmapless subset is a view of `milestones`, so it must speak the same
|
|
108
|
+
* aligned vocabulary; otherwise the discussion-phase exclusion below keys off
|
|
109
|
+
* the stale bare id, fails its `dbScan.milestones.has(...)` membership check,
|
|
110
|
+
* and decrements the milestone count even though the aligned identity remains
|
|
111
|
+
* in the set, reporting false drift for a milestone that is actually in sync.
|
|
112
|
+
* Centralising the set list here keeps every alignment path from silently
|
|
113
|
+
* missing a set (the defect that regressed the suffixed roadmapless case).
|
|
114
|
+
*/
|
|
115
|
+
function realignMilestonePrefix(markdownScan: HierarchyScan, from: string, to: string): void {
|
|
116
|
+
replaceSetPrefix(markdownScan.milestones, from, to);
|
|
117
|
+
replaceSetPrefix(markdownScan.slices, from, to);
|
|
118
|
+
replaceSetPrefix(markdownScan.tasks, from, to);
|
|
119
|
+
replaceSetPrefix(markdownScan.milestonesWithoutRoadmap, from, to);
|
|
120
|
+
}
|
|
121
|
+
|
|
105
122
|
function alignNumericMarkdownIdsWithDb(markdownScan: HierarchyScan, dbScan: HierarchyScan): void {
|
|
106
123
|
for (const dbId of dbScan.milestones) {
|
|
107
124
|
const paddedId = paddedMilestoneId(dbId);
|
|
108
125
|
if (!paddedId || dbScan.milestones.has(paddedId) || !markdownScan.milestones.has(paddedId)) continue;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
126
|
+
realignMilestonePrefix(markdownScan, paddedId, dbId);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function bareMilestoneId(id: string): string | null {
|
|
131
|
+
const match = id.match(/^(M\d{3})-[a-z0-9]{6}$/);
|
|
132
|
+
return match?.[1] ?? null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function alignBareMarkdownIdsWithSuffixedDb(markdownScan: HierarchyScan, dbScan: HierarchyScan): void {
|
|
136
|
+
for (const dbId of dbScan.milestones) {
|
|
137
|
+
const bareId = bareMilestoneId(dbId);
|
|
138
|
+
if (!bareId || dbScan.milestones.has(bareId) || !markdownScan.milestones.has(bareId)) continue;
|
|
139
|
+
realignMilestonePrefix(markdownScan, bareId, dbId);
|
|
112
140
|
}
|
|
113
141
|
}
|
|
114
142
|
|
|
@@ -208,6 +236,7 @@ export async function checkMarkdownHierarchyAgainstDb(
|
|
|
208
236
|
const dbScan = scanDbHierarchy();
|
|
209
237
|
const beforeDb = dbScan.counts;
|
|
210
238
|
alignNumericMarkdownIdsWithDb(markdownScan, dbScan);
|
|
239
|
+
alignBareMarkdownIdsWithSuffixedDb(markdownScan, dbScan);
|
|
211
240
|
|
|
212
241
|
// Discussion-phase scratch: a milestone dir with no ROADMAP and no DB row is
|
|
213
242
|
// a pre-registration discussion artifact (CONTEXT/CONTEXT-DRAFT only — the
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
2
|
// File Purpose: Process-level transaction wrapper for milestone merge closeout.
|
|
3
3
|
|
|
4
|
+
import { mergeMilestoneToMain } from "./auto-worktree-merge.js";
|
|
5
|
+
|
|
4
6
|
export interface MilestoneMergeTransactionResult {
|
|
5
7
|
pushed: boolean;
|
|
6
8
|
codeFilesChanged: boolean;
|
|
@@ -45,3 +47,16 @@ export function createMilestoneMergeTransaction(
|
|
|
45
47
|
);
|
|
46
48
|
};
|
|
47
49
|
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Production merge transaction adapter.
|
|
53
|
+
*
|
|
54
|
+
* This is the only production construction point that knows the legacy
|
|
55
|
+
* `auto-worktree.ts` merge primitive. Lifecycle callers depend on the
|
|
56
|
+
* transaction runner interface, not the legacy implementation module.
|
|
57
|
+
*/
|
|
58
|
+
export function createDefaultMilestoneMergeTransaction(
|
|
59
|
+
mergeMilestone: MilestoneMergeTransactionRunner = mergeMilestoneToMain,
|
|
60
|
+
): MilestoneMergeTransactionRunner {
|
|
61
|
+
return createMilestoneMergeTransaction(mergeMilestone);
|
|
62
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
2
|
// File Purpose: Milestone closeout settlement state across DB proof, artifacts, merge, and cleanup.
|
|
3
3
|
|
|
4
|
-
import { isInAutoWorktree } from "./auto-worktree.js";
|
|
4
|
+
import { isInAutoWorktree } from "./auto-worktree-entry.js";
|
|
5
5
|
import {
|
|
6
6
|
formatCloseoutProofBlock,
|
|
7
7
|
proveMilestoneCloseout,
|
|
@@ -10,7 +10,7 @@ import { join } from "node:path";
|
|
|
10
10
|
import { spawnSync } from "node:child_process";
|
|
11
11
|
import { resolveGsdPathContract } from "./paths.js";
|
|
12
12
|
import { worktreePathFor, worktreesDirs } from "./worktree-placement.js";
|
|
13
|
-
import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
13
|
+
import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
|
|
14
14
|
import { buildWorktreeLifecycleDeps } from "./auto.js";
|
|
15
15
|
import {
|
|
16
16
|
mergeMilestoneStandalone,
|
|
@@ -21,7 +21,9 @@ import { join, dirname } from "node:path";
|
|
|
21
21
|
import { fileURLToPath } from "node:url";
|
|
22
22
|
import { gsdRoot } from "./paths.js";
|
|
23
23
|
import { createWorktree, worktreePath } from "./worktree-manager.js";
|
|
24
|
-
import { autoWorktreeBranch, fastForwardReusedMilestoneBranchIfSafe
|
|
24
|
+
import { autoWorktreeBranch, fastForwardReusedMilestoneBranchIfSafe } from "./auto-worktree-branch-lifecycle.js";
|
|
25
|
+
import { syncGsdStateToWorktreeByScope } from "./auto-worktree-sync.js";
|
|
26
|
+
import { runWorktreePostCreateHook } from "./worktree-post-create-hook.js";
|
|
25
27
|
import { nativeBranchExists } from "./native-git-bridge.js";
|
|
26
28
|
import { readIntegrationBranch } from "./git-service.js";
|
|
27
29
|
import { createWorkspace, scopeMilestone } from "./workspace.js";
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { readdirSync, existsSync, realpathSync, statSync, Dirent } from "node:fs";
|
|
14
|
-
import { join, dirname, normalize, resolve } from "node:path";
|
|
14
|
+
import { join, dirname, normalize, relative, resolve } from "node:path";
|
|
15
15
|
import { homedir } from "node:os";
|
|
16
16
|
import { spawnSync } from "node:child_process";
|
|
17
17
|
import { nativeScanGsdTree, type GsdTreeEntry } from "./native-parser-bridge.js";
|
|
@@ -379,21 +379,26 @@ export function resolveGsdPathContract(
|
|
|
379
379
|
const resolvedWorkRoot = resolve(workRoot || process.cwd());
|
|
380
380
|
const isWorktree = isGsdWorktreePath(resolvedWorkRoot);
|
|
381
381
|
if (isWorktree && !originalProjectRoot?.trim()) {
|
|
382
|
-
const
|
|
383
|
-
if (
|
|
382
|
+
const rawProjectGsd = resolveExternalStateProjectGsdFromWorktreePath(resolvedWorkRoot);
|
|
383
|
+
if (rawProjectGsd) {
|
|
384
|
+
// Canonicalize the `.gsd` root so the DB path matches what every other
|
|
385
|
+
// accessor (gsdRoot/gsdProjectionRoot) returns — otherwise an unresolved
|
|
386
|
+
// symlink (e.g. `/mnt/c/.../.gsd` → native ext4 on WSL) selects the wrong
|
|
387
|
+
// journal mode and yields a fragile, move-prone handle. See issue #1239.
|
|
388
|
+
const projectGsd = normalizeRealPath(rawProjectGsd);
|
|
384
389
|
return {
|
|
385
390
|
projectRoot: dirname(dirname(projectGsd)),
|
|
386
391
|
workRoot: resolvedWorkRoot,
|
|
387
392
|
projectGsd,
|
|
388
|
-
worktreeGsd: join(resolvedWorkRoot, ".gsd"),
|
|
393
|
+
worktreeGsd: normalizeRealPath(join(resolvedWorkRoot, ".gsd")),
|
|
389
394
|
projectDb: join(projectGsd, "gsd.db"),
|
|
390
395
|
isWorktree,
|
|
391
396
|
};
|
|
392
397
|
}
|
|
393
398
|
}
|
|
394
399
|
const projectRoot = resolve(resolveWorktreeProjectRoot(resolvedWorkRoot, originalProjectRoot));
|
|
395
|
-
const projectGsd = join(projectRoot, ".gsd");
|
|
396
|
-
const worktreeGsd = isWorktree ? join(resolvedWorkRoot, ".gsd") : null;
|
|
400
|
+
const projectGsd = normalizeRealPath(join(projectRoot, ".gsd"));
|
|
401
|
+
const worktreeGsd = isWorktree ? normalizeRealPath(join(resolvedWorkRoot, ".gsd")) : null;
|
|
397
402
|
|
|
398
403
|
return {
|
|
399
404
|
projectRoot,
|
|
@@ -696,7 +701,16 @@ function pickPreferredPhaseDir(phasesDir: string, matches: string[]): string {
|
|
|
696
701
|
return best;
|
|
697
702
|
}
|
|
698
703
|
|
|
699
|
-
function
|
|
704
|
+
function slugLooksLikeTeamSuffixProjection(slugPart: string): boolean {
|
|
705
|
+
return /^[a-z0-9]{6}(-|$)/.test(slugPart);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
function phaseDirMatchesMilestoneId(
|
|
709
|
+
dirName: string,
|
|
710
|
+
milestoneId: string,
|
|
711
|
+
phaseNum: number,
|
|
712
|
+
allowTeamSuffixSlugs = false,
|
|
713
|
+
): boolean {
|
|
700
714
|
const numMatch = dirName.match(/^(\d+)-(.*)$/);
|
|
701
715
|
if (!numMatch || parseInt(numMatch[1]!, 10) !== phaseNum) return false;
|
|
702
716
|
const slugPart = numMatch[2]!;
|
|
@@ -704,8 +718,8 @@ function phaseDirMatchesMilestoneId(dirName: string, milestoneId: string, phaseN
|
|
|
704
718
|
if (suffix) {
|
|
705
719
|
return slugPart === suffix || slugPart.startsWith(`${suffix}-`);
|
|
706
720
|
}
|
|
707
|
-
|
|
708
|
-
return
|
|
721
|
+
if (slugLooksLikeTeamSuffixProjection(slugPart) && !allowTeamSuffixSlugs) return false;
|
|
722
|
+
return true;
|
|
709
723
|
}
|
|
710
724
|
|
|
711
725
|
function resolvePhaseDir(basePath: string, milestoneId: string): string | null {
|
|
@@ -726,6 +740,15 @@ function resolvePhaseDir(basePath: string, milestoneId: string): string | null {
|
|
|
726
740
|
matches.push(entry.name);
|
|
727
741
|
}
|
|
728
742
|
}
|
|
743
|
+
// Bare milestone ids may only have a suffixed team-mode projection on disk.
|
|
744
|
+
if (matches.length === 0 && !milestoneIdUniqueSuffix(milestoneId)) {
|
|
745
|
+
for (const entry of readdirSync(phasesDir, { withFileTypes: true })) {
|
|
746
|
+
if (!entry.isDirectory()) continue;
|
|
747
|
+
if (phaseDirMatchesMilestoneId(entry.name, milestoneId, phaseNum, true)) {
|
|
748
|
+
matches.push(entry.name);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
}
|
|
729
752
|
} catch {
|
|
730
753
|
// unreadable — fall through
|
|
731
754
|
}
|
|
@@ -898,10 +921,24 @@ export function resolveTaskFile(
|
|
|
898
921
|
basePath: string, milestoneId: string, sliceId: string,
|
|
899
922
|
taskId: string, suffix: string
|
|
900
923
|
): string | null {
|
|
924
|
+
const phaseDir = resolveMilestonePath(basePath, milestoneId);
|
|
925
|
+
if (!phaseDir) return null;
|
|
926
|
+
|
|
927
|
+
const legacyBase = legacyMilestonesDir(basePath);
|
|
928
|
+
const isLegacy = phaseDir.startsWith(legacyBase + "/") || phaseDir.startsWith(legacyBase + "\\");
|
|
929
|
+
|
|
930
|
+
if (suffix !== "PLAN" && !isLegacy) {
|
|
931
|
+
const flatPath = join(phaseDir, buildTaskFileName(taskId, suffix));
|
|
932
|
+
return existsSync(flatPath) ? flatPath : null;
|
|
933
|
+
}
|
|
934
|
+
|
|
901
935
|
const tDir = resolveTasksDir(basePath, milestoneId, sliceId);
|
|
902
|
-
if (
|
|
903
|
-
|
|
904
|
-
|
|
936
|
+
if (tDir) {
|
|
937
|
+
const file = resolveFile(tDir, taskId, suffix);
|
|
938
|
+
if (file) return join(tDir, file);
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
return null;
|
|
905
942
|
}
|
|
906
943
|
|
|
907
944
|
// ─── Relative Path Builders (for prompts — .gsd/milestones/...) ────────────
|
|
@@ -936,31 +973,41 @@ export function relMilestonePath(basePath: string, milestoneId: string, title?:
|
|
|
936
973
|
}
|
|
937
974
|
|
|
938
975
|
/**
|
|
939
|
-
* Build
|
|
940
|
-
*
|
|
941
|
-
*
|
|
942
|
-
* name when the file doesn't exist yet.
|
|
976
|
+
* Build the canonical absolute write target for a milestone file.
|
|
977
|
+
* Existing compatibility filenames are intentionally ignored; readers that need
|
|
978
|
+
* to preserve an existing file should call resolveMilestoneFile first.
|
|
943
979
|
*/
|
|
944
|
-
export function
|
|
945
|
-
basePath: string, milestoneId: string, suffix: string
|
|
980
|
+
export function targetMilestoneFile(
|
|
981
|
+
basePath: string, milestoneId: string, suffix: string, title?: string
|
|
946
982
|
): string {
|
|
947
|
-
const mRel = relMilestonePath(basePath, milestoneId);
|
|
948
|
-
// resolveMilestoneFile checks NN-SUFFIX.md (flat-phase) and MID-SUFFIX.md (legacy).
|
|
949
|
-
const absFile = resolveMilestoneFile(basePath, milestoneId, suffix);
|
|
950
|
-
if (absFile) {
|
|
951
|
-
const fileName = absFile.split(/[/\\]/).pop()!;
|
|
952
|
-
return `${mRel}/${fileName}`;
|
|
953
|
-
}
|
|
954
|
-
// File doesn't exist yet — use layout-aware fallback filename.
|
|
955
983
|
const mDir = resolveMilestonePath(basePath, milestoneId);
|
|
956
984
|
const legacyBase = legacyMilestonesDir(basePath);
|
|
957
985
|
const isLegacy = mDir
|
|
958
986
|
? mDir.startsWith(legacyBase + "/") || mDir.startsWith(legacyBase + "\\")
|
|
959
|
-
:
|
|
987
|
+
: isLegacyMilestonesLayout(basePath);
|
|
988
|
+
const dir = mDir ?? join(
|
|
989
|
+
isLegacy ? legacyBase : milestonesDir(basePath),
|
|
990
|
+
isLegacy ? milestoneId : canonicalPhaseDirName(milestoneId, title),
|
|
991
|
+
);
|
|
960
992
|
const fileName = isLegacy
|
|
961
993
|
? `${milestoneId}-${suffix}.md`
|
|
962
994
|
: `${String(milestoneIdToPhaseNum(milestoneId)).padStart(2, "0")}-${suffix}.md`;
|
|
963
|
-
return
|
|
995
|
+
return join(dir, fileName);
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
/**
|
|
999
|
+
* Build relative .gsd/ path to a milestone file.
|
|
1000
|
+
* Preserves an existing compatibility filename when present; otherwise falls
|
|
1001
|
+
* back to the canonical write target.
|
|
1002
|
+
*/
|
|
1003
|
+
export function relMilestoneFile(
|
|
1004
|
+
basePath: string, milestoneId: string, suffix: string, title?: string
|
|
1005
|
+
): string {
|
|
1006
|
+
const rel = relative(
|
|
1007
|
+
gsdProjectionRoot(basePath),
|
|
1008
|
+
resolveMilestoneFile(basePath, milestoneId, suffix) ?? targetMilestoneFile(basePath, milestoneId, suffix, title),
|
|
1009
|
+
).replace(/\\/g, "/");
|
|
1010
|
+
return `.gsd/${rel}`;
|
|
964
1011
|
}
|
|
965
1012
|
|
|
966
1013
|
/**
|
|
@@ -992,34 +1039,44 @@ export function relSlicePath(
|
|
|
992
1039
|
}
|
|
993
1040
|
|
|
994
1041
|
/**
|
|
995
|
-
* Build
|
|
996
|
-
*
|
|
997
|
-
*
|
|
998
|
-
* @param milestoneTitle - Optional milestone title forwarded to relSlicePath /
|
|
999
|
-
* relMilestonePath for title-aware flat-phase fallback dir naming. Only used
|
|
1000
|
-
* when the phase directory does not yet exist on disk.
|
|
1042
|
+
* Build the canonical absolute write target for a slice file.
|
|
1043
|
+
* Existing compatibility filenames are intentionally ignored; readers that need
|
|
1044
|
+
* to preserve an existing file should call resolveSliceFile first.
|
|
1001
1045
|
*/
|
|
1002
|
-
export function
|
|
1046
|
+
export function targetSliceFile(
|
|
1003
1047
|
basePath: string, milestoneId: string, sliceId: string, suffix: string, milestoneTitle?: string
|
|
1004
1048
|
): string {
|
|
1005
|
-
const sRel = relSlicePath(basePath, milestoneId, sliceId, milestoneTitle);
|
|
1006
|
-
const absPath = resolveSliceFile(basePath, milestoneId, sliceId, suffix);
|
|
1007
|
-
if (absPath) {
|
|
1008
|
-
const fileName = absPath.split(/[/\\]/).pop()!;
|
|
1009
|
-
return `${sRel}/${fileName}`;
|
|
1010
|
-
}
|
|
1011
|
-
// Fallback when file doesn't exist yet — use layout-aware filename.
|
|
1012
1049
|
const mDir = resolveMilestonePath(basePath, milestoneId);
|
|
1013
1050
|
const legacyBase = legacyMilestonesDir(basePath);
|
|
1014
1051
|
const isLegacy = mDir
|
|
1015
1052
|
? mDir.startsWith(legacyBase + "/") || mDir.startsWith(legacyBase + "\\")
|
|
1016
|
-
:
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
const
|
|
1021
|
-
|
|
1022
|
-
|
|
1053
|
+
: isLegacyMilestonesLayout(basePath);
|
|
1054
|
+
const milestoneDir = mDir
|
|
1055
|
+
?? dirname(targetMilestoneFile(basePath, milestoneId, "ROADMAP", milestoneTitle));
|
|
1056
|
+
const slicesDir = join(milestoneDir, "slices");
|
|
1057
|
+
const dir = isLegacy
|
|
1058
|
+
? join(slicesDir, resolveDir(slicesDir, sliceId) ?? sliceId)
|
|
1059
|
+
: milestoneDir;
|
|
1060
|
+
const fileName = isLegacy
|
|
1061
|
+
? `${sliceId}-${suffix}.md`
|
|
1062
|
+
: planFileName(milestoneIdToPhaseNum(milestoneId), sliceIdToPlanNum(sliceId), suffix);
|
|
1063
|
+
return join(dir, fileName);
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
/**
|
|
1067
|
+
* Build relative .gsd/ path to a slice file.
|
|
1068
|
+
* Preserves an existing compatibility filename when present; otherwise falls
|
|
1069
|
+
* back to the canonical write target.
|
|
1070
|
+
*/
|
|
1071
|
+
export function relSliceFile(
|
|
1072
|
+
basePath: string, milestoneId: string, sliceId: string, suffix: string, milestoneTitle?: string
|
|
1073
|
+
): string {
|
|
1074
|
+
const rel = relative(
|
|
1075
|
+
gsdProjectionRoot(basePath),
|
|
1076
|
+
resolveSliceFile(basePath, milestoneId, sliceId, suffix)
|
|
1077
|
+
?? targetSliceFile(basePath, milestoneId, sliceId, suffix, milestoneTitle),
|
|
1078
|
+
).replace(/\\/g, "/");
|
|
1079
|
+
return `.gsd/${rel}`;
|
|
1023
1080
|
}
|
|
1024
1081
|
|
|
1025
1082
|
/**
|
|
@@ -1031,7 +1088,7 @@ export function relSliceFile(
|
|
|
1031
1088
|
*/
|
|
1032
1089
|
export function relTaskFile(
|
|
1033
1090
|
basePath: string, milestoneId: string, sliceId: string,
|
|
1034
|
-
taskId: string, suffix: string
|
|
1091
|
+
taskId: string, suffix: string, milestoneTitle?: string
|
|
1035
1092
|
): string {
|
|
1036
1093
|
const sDir = resolveSlicePath(basePath, milestoneId, sliceId);
|
|
1037
1094
|
const phaseDir = resolveMilestonePath(basePath, milestoneId);
|
|
@@ -1044,6 +1101,6 @@ export function relTaskFile(
|
|
|
1044
1101
|
if (suffix === "PLAN") {
|
|
1045
1102
|
return relSliceFile(basePath, milestoneId, sliceId, "PLAN");
|
|
1046
1103
|
}
|
|
1047
|
-
const relS = relSlicePath(basePath, milestoneId, sliceId);
|
|
1104
|
+
const relS = relSlicePath(basePath, milestoneId, sliceId, milestoneTitle);
|
|
1048
1105
|
return `${relS}/${buildTaskFileName(taskId, suffix)}`;
|
|
1049
1106
|
}
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
HookStatusEntry,
|
|
12
12
|
PostUnitGateBlock,
|
|
13
13
|
} from "./types.js";
|
|
14
|
+
import type { SidecarItem } from "./auto/session.js";
|
|
14
15
|
import { getOrCreateRegistry, resolveHookArtifactPath } from "./rule-registry.js";
|
|
15
16
|
|
|
16
17
|
// Re-export resolveHookArtifactPath so existing importers still work.
|
|
@@ -75,6 +76,37 @@ export function restoreHookState(basePath: string): void {
|
|
|
75
76
|
getOrCreateRegistry().restoreState(basePath);
|
|
76
77
|
}
|
|
77
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Reconcile a restored `activeHook` against the session's sidecar queue.
|
|
81
|
+
*
|
|
82
|
+
* The registry persists `activeHook` to disk but the pending hook *dispatch*
|
|
83
|
+
* lives only on the non-persisted `s.sidecarQueue`. After a pause/resume or
|
|
84
|
+
* crash-recovery, `restoreHookState` re-hydrates `activeHook` while the dispatch
|
|
85
|
+
* is gone, so the registry believes a hook is in-flight but nothing will ever
|
|
86
|
+
* complete it — and the next unrelated unit's close-out is falsely charged
|
|
87
|
+
* against the stale hook and blocked. Re-enqueue the missing dispatch so the
|
|
88
|
+
* hook actually runs, restoring the invariant that a persisted `activeHook`
|
|
89
|
+
* always has a live dispatch (#1246).
|
|
90
|
+
*/
|
|
91
|
+
export function reconcileRestoredHookDispatch(
|
|
92
|
+
basePath: string,
|
|
93
|
+
sidecarQueue: SidecarItem[],
|
|
94
|
+
): void {
|
|
95
|
+
const dispatch = getOrCreateRegistry().getPendingHookDispatch(basePath);
|
|
96
|
+
if (!dispatch) return;
|
|
97
|
+
const alreadyQueued = sidecarQueue.some(
|
|
98
|
+
item => item.kind === "hook" && item.unitType === dispatch.unitType,
|
|
99
|
+
);
|
|
100
|
+
if (alreadyQueued) return;
|
|
101
|
+
sidecarQueue.push({
|
|
102
|
+
kind: "hook",
|
|
103
|
+
unitType: dispatch.unitType,
|
|
104
|
+
unitId: dispatch.unitId,
|
|
105
|
+
prompt: dispatch.prompt,
|
|
106
|
+
model: dispatch.model,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
78
110
|
export function clearPersistedHookState(basePath: string): void {
|
|
79
111
|
getOrCreateRegistry().clearPersistedState(basePath);
|
|
80
112
|
}
|