@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
|
@@ -352,17 +352,17 @@ export function insertTask(t) {
|
|
|
352
352
|
ON CONFLICT(milestone_id, slice_id, id) DO UPDATE SET
|
|
353
353
|
title = CASE WHEN NULLIF(:title, '') IS NOT NULL THEN :title ELSE tasks.title END,
|
|
354
354
|
status = :status,
|
|
355
|
-
one_liner = :one_liner,
|
|
356
|
-
narrative = :narrative,
|
|
357
|
-
verification_result = :verification_result,
|
|
358
|
-
duration = :duration,
|
|
359
|
-
completed_at = :completed_at,
|
|
360
|
-
blocker_discovered = :blocker_discovered,
|
|
361
|
-
deviations = :deviations,
|
|
362
|
-
known_issues = :known_issues,
|
|
363
|
-
key_files = :key_files,
|
|
364
|
-
key_decisions = :key_decisions,
|
|
365
|
-
full_summary_md = :full_summary_md,
|
|
355
|
+
one_liner = CASE WHEN :preserve_completion = 1 AND NULLIF(:one_liner, '') IS NULL THEN tasks.one_liner ELSE :one_liner END,
|
|
356
|
+
narrative = CASE WHEN :preserve_completion = 1 AND NULLIF(:narrative, '') IS NULL THEN tasks.narrative ELSE :narrative END,
|
|
357
|
+
verification_result = CASE WHEN :preserve_completion = 1 AND NULLIF(:verification_result, '') IS NULL THEN tasks.verification_result ELSE :verification_result END,
|
|
358
|
+
duration = CASE WHEN :preserve_completion = 1 AND NULLIF(:duration, '') IS NULL THEN tasks.duration ELSE :duration END,
|
|
359
|
+
completed_at = CASE WHEN :preserve_completion = 1 AND tasks.completed_at IS NOT NULL THEN tasks.completed_at ELSE :completed_at END,
|
|
360
|
+
blocker_discovered = CASE WHEN :preserve_completion = 1 AND :blocker_discovered = 0 THEN tasks.blocker_discovered ELSE :blocker_discovered END,
|
|
361
|
+
deviations = CASE WHEN :preserve_completion = 1 AND NULLIF(:deviations, '') IS NULL THEN tasks.deviations ELSE :deviations END,
|
|
362
|
+
known_issues = CASE WHEN :preserve_completion = 1 AND NULLIF(:known_issues, '') IS NULL THEN tasks.known_issues ELSE :known_issues END,
|
|
363
|
+
key_files = CASE WHEN :preserve_completion = 1 AND NULLIF(:key_files, '[]') IS NULL THEN tasks.key_files ELSE :key_files END,
|
|
364
|
+
key_decisions = CASE WHEN :preserve_completion = 1 AND NULLIF(:key_decisions, '[]') IS NULL THEN tasks.key_decisions ELSE :key_decisions END,
|
|
365
|
+
full_summary_md = CASE WHEN :preserve_completion = 1 AND NULLIF(:full_summary_md, '') IS NULL THEN tasks.full_summary_md ELSE :full_summary_md END,
|
|
366
366
|
description = CASE WHEN NULLIF(:description, '') IS NOT NULL THEN :description ELSE tasks.description END,
|
|
367
367
|
estimate = CASE WHEN NULLIF(:estimate, '') IS NOT NULL THEN :estimate ELSE tasks.estimate END,
|
|
368
368
|
files = CASE WHEN NULLIF(:files, '[]') IS NOT NULL THEN :files ELSE tasks.files END,
|
|
@@ -401,6 +401,7 @@ export function insertTask(t) {
|
|
|
401
401
|
":observability_impact": t.planning?.observabilityImpact ?? "",
|
|
402
402
|
":full_plan_md": t.planning?.fullPlanMd ?? "",
|
|
403
403
|
":sequence": t.sequence ?? 0,
|
|
404
|
+
":preserve_completion": t.preserveCompletionMetadata && (t.status === "complete" || t.status === "done") ? 1 : 0,
|
|
404
405
|
":target_repositories": JSON.stringify(t.planning?.targetRepositories ?? []),
|
|
405
406
|
":raw_target_repositories": t.planning && "targetRepositories" in t.planning
|
|
406
407
|
? JSON.stringify(t.planning.targetRepositories ?? [])
|
|
@@ -1000,6 +1001,17 @@ export function deleteArtifactByPath(path) {
|
|
|
1000
1001
|
throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
|
|
1001
1002
|
getDbOrNull().prepare("DELETE FROM artifacts WHERE path = :path").run({ ":path": path });
|
|
1002
1003
|
}
|
|
1004
|
+
/** Delete artifact rows whose paths share a DB-relative prefix. */
|
|
1005
|
+
export function deleteArtifactsByPathPrefix(prefix) {
|
|
1006
|
+
if (!getDbOrNull())
|
|
1007
|
+
throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
|
|
1008
|
+
return transaction(() => {
|
|
1009
|
+
const likePrefix = `${prefix}%`;
|
|
1010
|
+
const countRow = getDbOrNull().prepare("SELECT COUNT(*) AS count FROM artifacts WHERE path LIKE :prefix").get({ ":prefix": likePrefix });
|
|
1011
|
+
getDbOrNull().prepare("DELETE FROM artifacts WHERE path LIKE :prefix").run({ ":prefix": likePrefix });
|
|
1012
|
+
return Number(countRow?.["count"] ?? 0);
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
1003
1015
|
/**
|
|
1004
1016
|
* Drop hierarchy rows in dependency order inside a transaction. Used by
|
|
1005
1017
|
* `gsd recover --confirm` to rebuild engine state from markdown.
|
|
@@ -27,8 +27,8 @@ import { readSessionLockData, isSessionLockProcessAlive } from "./session-lock.j
|
|
|
27
27
|
import { nativeAddAll, nativeCommit, nativeHasCommittedHead, nativeIsRepo, nativeInit } from "./native-git-bridge.js";
|
|
28
28
|
import { isInheritedRepo } from "./repo-identity.js";
|
|
29
29
|
import { ensureGitignore, ensurePreferences, untrackRuntimeFiles } from "./gitignore.js";
|
|
30
|
-
import { getIsolationMode, loadEffectiveGSDPreferences } from "./preferences.js";
|
|
31
|
-
import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
30
|
+
import { getIsolationMode, loadEffectiveGSDPreferences, renderLanguageDirectiveForPrompt } from "./preferences.js";
|
|
31
|
+
import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
|
|
32
32
|
import { resolveUokFlags } from "./uok/flags.js";
|
|
33
33
|
import { ensurePlanV2Graph, isMissingFinalizedContextResult } from "./uok/plan-v2.js";
|
|
34
34
|
import { detectProjectState, hasGsdBootstrapArtifacts } from "./detection.js";
|
|
@@ -50,7 +50,7 @@ import { getCachedWorkflowMcpProbe, probeAndCacheWorkflowMcp, warmWorkflowMcpPro
|
|
|
50
50
|
import { probeCoversRequiredWorkflowTools } from "./tool-surface-readiness.js";
|
|
51
51
|
import { getRequiredWorkflowToolsForUnit } from "./unit-tool-contracts.js";
|
|
52
52
|
import { isWorkflowToolSurfaceName } from "./workflow-tool-surface.js";
|
|
53
|
-
import {
|
|
53
|
+
import { getUnitWorkflowDispatchReadinessErrorForModel } from "./tool-contract.js";
|
|
54
54
|
import { runPreparation, formatCodebaseBrief, formatPriorContextBrief, } from "./preparation.js";
|
|
55
55
|
import { verifyExpectedArtifact } from "./auto-recovery.js";
|
|
56
56
|
import { countPlanMilestoneRoadmapSlices } from "./artifact-verification.js";
|
|
@@ -491,7 +491,7 @@ async function dispatchWorkflow(pi, note, customType = "gsd-run", ctx, unitType,
|
|
|
491
491
|
const loadPreferences = resolvedOptions.deps?.loadPreferences ?? loadEffectiveGSDPreferences;
|
|
492
492
|
const selectModel = resolvedOptions.deps?.selectModel ?? selectAndApplyModel;
|
|
493
493
|
const getDispatchReadinessError = resolvedOptions.deps?.getDispatchReadinessError
|
|
494
|
-
??
|
|
494
|
+
?? getUnitWorkflowDispatchReadinessErrorForModel;
|
|
495
495
|
// Route through the dynamic routing pipeline (complexity classification,
|
|
496
496
|
// tier downgrade, fallback chains) — same path as auto-mode dispatches (#2958).
|
|
497
497
|
if (ctx && unitType) {
|
|
@@ -506,16 +506,12 @@ async function dispatchWorkflow(pi, note, customType = "gsd-run", ctx, unitType,
|
|
|
506
506
|
});
|
|
507
507
|
}
|
|
508
508
|
const compatibilityError = getDispatchReadinessError({
|
|
509
|
-
|
|
509
|
+
model: result.appliedModel,
|
|
510
|
+
fallbackModel: ctx.model,
|
|
511
|
+
getProviderAuthMode: (provider) => ctx.modelRegistry.getProviderAuthMode(provider),
|
|
510
512
|
projectRoot,
|
|
511
513
|
surface: "guided flow",
|
|
512
514
|
unitType,
|
|
513
|
-
authMode: result.appliedModel?.provider
|
|
514
|
-
? ctx.modelRegistry.getProviderAuthMode(result.appliedModel.provider)
|
|
515
|
-
: ctx.model?.provider
|
|
516
|
-
? ctx.modelRegistry.getProviderAuthMode(ctx.model.provider)
|
|
517
|
-
: undefined,
|
|
518
|
-
baseUrl: result.appliedModel?.baseUrl ?? ctx.model?.baseUrl,
|
|
519
515
|
// Guided flow starts the MCP workflow server as part of dispatch, so the
|
|
520
516
|
// parent session's activeTools doesn't include MCP tools yet. The MCP
|
|
521
517
|
// launch config check (detectWorkflowMcpLaunchConfig) is the right gate
|
|
@@ -646,7 +642,7 @@ function resolveAvailableModel(modelId, availableModels, currentProvider) {
|
|
|
646
642
|
* Build the discuss-and-plan prompt for a new milestone.
|
|
647
643
|
* Used by all three "new milestone" paths (first ever, no active, all complete).
|
|
648
644
|
*/
|
|
649
|
-
function buildDiscussPrompt(nextId, preamble,
|
|
645
|
+
function buildDiscussPrompt(nextId, preamble, basePath, pi, ctx, preparationContext) {
|
|
650
646
|
const milestoneRel = `.gsd/milestones/${nextId}`;
|
|
651
647
|
const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
|
|
652
648
|
const inlinedTemplates = [
|
|
@@ -656,7 +652,7 @@ function buildDiscussPrompt(nextId, preamble, _basePath, pi, ctx, preparationCon
|
|
|
656
652
|
inlineTemplate("roadmap", "Roadmap"),
|
|
657
653
|
inlineTemplate("decisions", "Decisions"),
|
|
658
654
|
].join("\n\n---\n\n");
|
|
659
|
-
return loadPrompt("discuss", {
|
|
655
|
+
return prependLanguageDirective(basePath, loadPrompt("discuss", {
|
|
660
656
|
milestoneId: nextId,
|
|
661
657
|
preamble,
|
|
662
658
|
preparationContext: preparationContext ?? "",
|
|
@@ -666,13 +662,22 @@ function buildDiscussPrompt(nextId, preamble, _basePath, pi, ctx, preparationCon
|
|
|
666
662
|
inlinedTemplates,
|
|
667
663
|
commitInstruction: buildDocsCommitInstruction(`docs(${nextId}): context, requirements, and roadmap`),
|
|
668
664
|
multiMilestoneCommitInstruction: buildDocsCommitInstruction("docs: project plan — N milestones"),
|
|
669
|
-
});
|
|
665
|
+
}));
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Prepend the configured response-language directive to a dispatched discuss
|
|
669
|
+
* prompt so the discuss/QA conversation is held in the language set in
|
|
670
|
+
* PREFERENCES.md (#1210). No-op when no language is configured.
|
|
671
|
+
*/
|
|
672
|
+
function prependLanguageDirective(basePath, prompt) {
|
|
673
|
+
const directive = renderLanguageDirectiveForPrompt(loadEffectiveGSDPreferences(basePath)?.preferences);
|
|
674
|
+
return directive ? `${directive}\n\n${prompt}` : prompt;
|
|
670
675
|
}
|
|
671
676
|
/**
|
|
672
677
|
* Build the discuss prompt for headless milestone creation.
|
|
673
678
|
* Uses the discuss-headless prompt template with seed context injected.
|
|
674
679
|
*/
|
|
675
|
-
function buildHeadlessDiscussPrompt(nextId, seedContext,
|
|
680
|
+
function buildHeadlessDiscussPrompt(nextId, seedContext, basePath) {
|
|
676
681
|
const milestoneRel = `.gsd/milestones/${nextId}`;
|
|
677
682
|
const inlinedTemplates = [
|
|
678
683
|
inlineTemplate("project", "Project"),
|
|
@@ -681,7 +686,7 @@ function buildHeadlessDiscussPrompt(nextId, seedContext, _basePath) {
|
|
|
681
686
|
inlineTemplate("roadmap", "Roadmap"),
|
|
682
687
|
inlineTemplate("decisions", "Decisions"),
|
|
683
688
|
].join("\n\n---\n\n");
|
|
684
|
-
return loadPrompt("discuss-headless", {
|
|
689
|
+
return prependLanguageDirective(basePath, loadPrompt("discuss-headless", {
|
|
685
690
|
milestoneId: nextId,
|
|
686
691
|
seedContext,
|
|
687
692
|
contextPath: `${milestoneRel}/${nextId}-CONTEXT.md`,
|
|
@@ -689,7 +694,7 @@ function buildHeadlessDiscussPrompt(nextId, seedContext, _basePath) {
|
|
|
689
694
|
inlinedTemplates,
|
|
690
695
|
commitInstruction: buildDocsCommitInstruction(`docs(${nextId}): context, requirements, and roadmap`),
|
|
691
696
|
multiMilestoneCommitInstruction: buildDocsCommitInstruction("docs: project plan — N milestones"),
|
|
692
|
-
});
|
|
697
|
+
}));
|
|
693
698
|
}
|
|
694
699
|
/**
|
|
695
700
|
* Run preparation phase if enabled, then build the discuss prompt.
|
|
@@ -13,13 +13,12 @@ import { logWarning } from "./workflow-logger.js";
|
|
|
13
13
|
import { isClosedStatus } from "./status-guards.js";
|
|
14
14
|
import { dirname, join, relative } from "node:path";
|
|
15
15
|
import { getAllMilestones, getMilestone, getMilestoneScopedArtifacts, getSliceScopedArtifacts, getMilestoneSlices, getSliceTasks, getTasksBySliceIds, getTask, getSlice, insertArtifact, deleteArtifactByPath, getGateResults, isDbAvailable, } from "./gsd-db.js";
|
|
16
|
-
import { resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTasksDir, gsdProjectionRoot, gsdRoot,
|
|
16
|
+
import { resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTasksDir, targetMilestoneFile, targetSliceFile, gsdProjectionRoot, gsdRoot, buildTaskFileName, } from "./paths.js";
|
|
17
17
|
import { saveFile, clearParseCache, registerCacheClearCallback } from "./files.js";
|
|
18
18
|
import { parseRoadmap, parsePlan } from "./parsers-legacy.js";
|
|
19
19
|
import { invalidateStateCache } from "./state.js";
|
|
20
20
|
import { clearPathCache, milestonesDir, legacyMilestonesDir, isLegacyMilestonesLayout, resolveMilestonePath, relSliceFile, canonicalPhaseDirName } from "./paths.js";
|
|
21
21
|
import { readCompatMarker, writeCompatMarker, computeProjectionSha } from "./compat/compat-marker.js";
|
|
22
|
-
import { planFileName, milestoneIdToPhaseNum, sliceIdToPlanNum, } from "./layout-policy.js";
|
|
23
22
|
// ─── Compat marker invalidation ───────────────────────────────────────────
|
|
24
23
|
// Every successful projection write pushes its (basePath, projectionPath,
|
|
25
24
|
// entities) here; invalidateCaches() drains it and refreshes .gsd/.compat.json
|
|
@@ -134,19 +133,6 @@ function sanitizeInlineRoadmapText(value) {
|
|
|
134
133
|
.replace(/\s+/g, " ")
|
|
135
134
|
.trim();
|
|
136
135
|
}
|
|
137
|
-
function resolveRoadmapProjectionPath(basePath, milestoneId) {
|
|
138
|
-
const phaseNum = milestoneIdToPhaseNum(milestoneId);
|
|
139
|
-
const existing = resolveMilestonePath(basePath, milestoneId);
|
|
140
|
-
const legacyBase = legacyMilestonesDir(basePath);
|
|
141
|
-
const isLegacyLayout = existing
|
|
142
|
-
? existing.startsWith(legacyBase + "/") || existing.startsWith(legacyBase + "\\")
|
|
143
|
-
: isLegacyMilestonesLayout(basePath);
|
|
144
|
-
const phaseDir = existing ?? join(isLegacyLayout ? legacyBase : milestonesDir(basePath), isLegacyLayout ? milestoneId : canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title));
|
|
145
|
-
const roadmapFileName = isLegacyLayout
|
|
146
|
-
? `${milestoneId}-ROADMAP.md`
|
|
147
|
-
: `${String(phaseNum).padStart(2, "0")}-ROADMAP.md`;
|
|
148
|
-
return join(phaseDir, roadmapFileName);
|
|
149
|
-
}
|
|
150
136
|
function isMilestoneFlatPhaseLayout(basePath, milestoneId) {
|
|
151
137
|
const existing = resolveMilestonePath(basePath, milestoneId);
|
|
152
138
|
const legacyBase = legacyMilestonesDir(basePath);
|
|
@@ -492,7 +478,7 @@ export async function renderRoadmapFromDb(basePath, milestoneId) {
|
|
|
492
478
|
// clear "write the ROADMAP" failure) instead of a misleading stub.
|
|
493
479
|
if (slices.length === 0 && !milestone.vision.trim()) {
|
|
494
480
|
logWarning("projection", `renderRoadmapFromDb skipped unplanned milestone ${milestoneId} (zero slices, empty vision) — refusing to write a stub ROADMAP`);
|
|
495
|
-
const absPath =
|
|
481
|
+
const absPath = targetMilestoneFile(basePath, milestoneId, "ROADMAP", milestone.title);
|
|
496
482
|
if (existsSync(absPath)) {
|
|
497
483
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
498
484
|
unlinkSync(absPath);
|
|
@@ -506,7 +492,7 @@ export async function renderRoadmapFromDb(basePath, milestoneId) {
|
|
|
506
492
|
}
|
|
507
493
|
return { skipped: "unplanned-milestone" };
|
|
508
494
|
}
|
|
509
|
-
const absPath =
|
|
495
|
+
const absPath = targetMilestoneFile(basePath, milestoneId, "ROADMAP", milestone.title);
|
|
510
496
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
511
497
|
const content = renderRoadmapMarkdown(milestone, slices);
|
|
512
498
|
await writeAndStore(absPath, artifactPath, content, {
|
|
@@ -536,21 +522,15 @@ export async function renderMilestoneArtifactsFromDb(basePath, milestoneId) {
|
|
|
536
522
|
const artifacts = getMilestoneScopedArtifacts(milestoneId);
|
|
537
523
|
if (artifacts.length === 0)
|
|
538
524
|
return false;
|
|
539
|
-
const
|
|
540
|
-
join(milestonesDir(basePath), canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title));
|
|
541
|
-
mkdirSync(phaseDir, { recursive: true });
|
|
542
|
-
const legacyBase = legacyMilestonesDir(basePath);
|
|
543
|
-
const isLegacy = phaseDir.startsWith(legacyBase + "/") || phaseDir.startsWith(legacyBase + "\\");
|
|
525
|
+
const milestone = getMilestone(milestoneId);
|
|
544
526
|
let wrote = false;
|
|
545
527
|
for (const artifact of artifacts) {
|
|
546
528
|
if (artifact.artifact_type === "ROADMAP")
|
|
547
529
|
continue;
|
|
548
530
|
if (!artifact.full_content.trim())
|
|
549
531
|
continue;
|
|
550
|
-
const
|
|
551
|
-
|
|
552
|
-
: buildMilestoneFileName(milestoneId, artifact.artifact_type);
|
|
553
|
-
const absPath = join(phaseDir, fileName);
|
|
532
|
+
const absPath = targetMilestoneFile(basePath, milestoneId, artifact.artifact_type, milestone?.title);
|
|
533
|
+
mkdirSync(dirname(absPath), { recursive: true });
|
|
554
534
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
555
535
|
await writeAndStore(absPath, artifactPath, artifact.full_content, {
|
|
556
536
|
artifact_type: artifact.artifact_type,
|
|
@@ -664,20 +644,11 @@ export async function renderSliceSummary(basePath, milestoneId, sliceId) {
|
|
|
664
644
|
if (!slice) {
|
|
665
645
|
return false; // No slice data — skip silently
|
|
666
646
|
}
|
|
667
|
-
|
|
668
|
-
// finds existing dirs. In flat-phase the slice "path" is the phase dir.
|
|
669
|
-
let slicePath = resolveSlicePath(basePath, milestoneId, sliceId);
|
|
670
|
-
if (!slicePath) {
|
|
671
|
-
const mDir = milestonesDir(basePath);
|
|
672
|
-
const dirName = canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title);
|
|
673
|
-
slicePath = join(mDir, dirName);
|
|
674
|
-
mkdirSync(slicePath, { recursive: true });
|
|
675
|
-
}
|
|
647
|
+
const milestoneTitle = getMilestone(milestoneId)?.title;
|
|
676
648
|
let wrote = false;
|
|
677
|
-
// Write SUMMARY — flat-phase: NN-MM-SUMMARY.md inside phase dir
|
|
678
649
|
if (slice.full_summary_md) {
|
|
679
|
-
const
|
|
680
|
-
|
|
650
|
+
const summaryAbs = targetSliceFile(basePath, milestoneId, sliceId, "SUMMARY", milestoneTitle);
|
|
651
|
+
mkdirSync(dirname(summaryAbs), { recursive: true });
|
|
681
652
|
const summaryArtifact = toArtifactPath(summaryAbs, basePath);
|
|
682
653
|
await writeAndStore(summaryAbs, summaryArtifact, slice.full_summary_md, {
|
|
683
654
|
artifact_type: "SUMMARY",
|
|
@@ -686,10 +657,9 @@ export async function renderSliceSummary(basePath, milestoneId, sliceId) {
|
|
|
686
657
|
}, basePath);
|
|
687
658
|
wrote = true;
|
|
688
659
|
}
|
|
689
|
-
// Write UAT — flat-phase: NN-MM-UAT.md inside phase dir
|
|
690
660
|
if (slice.full_uat_md) {
|
|
691
|
-
const
|
|
692
|
-
|
|
661
|
+
const uatAbs = targetSliceFile(basePath, milestoneId, sliceId, "UAT", milestoneTitle);
|
|
662
|
+
mkdirSync(dirname(uatAbs), { recursive: true });
|
|
693
663
|
const uatArtifact = toArtifactPath(uatAbs, basePath);
|
|
694
664
|
await writeAndStore(uatAbs, uatArtifact, slice.full_uat_md, {
|
|
695
665
|
artifact_type: "UAT",
|
|
@@ -874,7 +844,7 @@ function detectStaleRendersImpl(basePath) {
|
|
|
874
844
|
// TODO(flat-phase): roadmap checkbox parsing may not match flat-phase
|
|
875
845
|
// roadmap format, causing false-positive drift loops. Skip during transition.
|
|
876
846
|
/*
|
|
877
|
-
const roadmapPath =
|
|
847
|
+
const roadmapPath = targetMilestoneFile(basePath, milestone.id, "ROADMAP", milestone.title);
|
|
878
848
|
if (existsSync(roadmapPath)) {
|
|
879
849
|
try {
|
|
880
850
|
const parsed = parseProjectionByIdentity(roadmapPath, parseRoadmap) as ReturnType<typeof parseRoadmap>;
|
|
@@ -961,34 +931,27 @@ function detectStaleRendersImpl(basePath) {
|
|
|
961
931
|
}
|
|
962
932
|
}
|
|
963
933
|
}
|
|
964
|
-
// Check missing slice summary/UAT files
|
|
934
|
+
// Check missing slice summary/UAT files. Use the same target helper as
|
|
935
|
+
// renderSliceSummary so detection and repair agree on flat-phase vs legacy
|
|
936
|
+
// output locations.
|
|
965
937
|
const sliceRow = getSlice(milestone.id, slice.id);
|
|
966
938
|
if (sliceRow && sliceRow.status === "complete") {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
const summaryName = planFileName(phaseNum, planNum, "SUMMARY");
|
|
975
|
-
const summaryAbsPath = join(slicePath, summaryName);
|
|
976
|
-
if (!existsSync(summaryAbsPath)) {
|
|
977
|
-
stale.push({
|
|
978
|
-
path: summaryAbsPath,
|
|
979
|
-
reason: `${slice.id} is complete with summary in DB but SUMMARY.md missing on disk`,
|
|
980
|
-
});
|
|
981
|
-
}
|
|
939
|
+
if (sliceRow.full_summary_md) {
|
|
940
|
+
const summaryAbsPath = targetSliceFile(basePath, milestone.id, slice.id, "SUMMARY", milestone.title);
|
|
941
|
+
if (!existsSync(summaryAbsPath)) {
|
|
942
|
+
stale.push({
|
|
943
|
+
path: summaryAbsPath,
|
|
944
|
+
reason: `${slice.id} is complete with summary in DB but SUMMARY.md missing on disk`,
|
|
945
|
+
});
|
|
982
946
|
}
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
}
|
|
947
|
+
}
|
|
948
|
+
if (sliceRow.full_uat_md) {
|
|
949
|
+
const uatAbsPath = targetSliceFile(basePath, milestone.id, slice.id, "UAT", milestone.title);
|
|
950
|
+
if (!existsSync(uatAbsPath)) {
|
|
951
|
+
stale.push({
|
|
952
|
+
path: uatAbsPath,
|
|
953
|
+
reason: `${slice.id} is complete with UAT in DB but UAT.md missing on disk`,
|
|
954
|
+
});
|
|
992
955
|
}
|
|
993
956
|
}
|
|
994
957
|
}
|
|
@@ -1013,12 +976,8 @@ export function roadmapRenderMarksSliceDone(roadmapContent, sliceId) {
|
|
|
1013
976
|
return parseRoadmap(roadmapContent).slices.some((slice) => slice.id === sliceId && slice.done);
|
|
1014
977
|
}
|
|
1015
978
|
export async function renderReplanFromDb(basePath, milestoneId, sliceId, replanData) {
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
?? join(milestonesDir(basePath), canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title));
|
|
1019
|
-
const phaseNum = milestoneIdToPhaseNum(milestoneId);
|
|
1020
|
-
const planNum = sliceIdToPlanNum(sliceId);
|
|
1021
|
-
const absPath = join(slicePath, planFileName(phaseNum, planNum, "REPLAN"));
|
|
979
|
+
const absPath = targetSliceFile(basePath, milestoneId, sliceId, "REPLAN", getMilestone(milestoneId)?.title);
|
|
980
|
+
mkdirSync(dirname(absPath), { recursive: true });
|
|
1022
981
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
1023
982
|
const lines = [];
|
|
1024
983
|
lines.push(`# ${sliceId} Replan`);
|
|
@@ -1045,12 +1004,8 @@ export async function renderReplanFromDb(basePath, milestoneId, sliceId, replanD
|
|
|
1045
1004
|
return { replanPath: absPath, content };
|
|
1046
1005
|
}
|
|
1047
1006
|
export async function renderAssessmentFromDb(basePath, milestoneId, sliceId, assessmentData) {
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
?? join(milestonesDir(basePath), canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title));
|
|
1051
|
-
const phaseNum = milestoneIdToPhaseNum(milestoneId);
|
|
1052
|
-
const planNum = sliceIdToPlanNum(sliceId);
|
|
1053
|
-
const absPath = join(slicePath, planFileName(phaseNum, planNum, "ASSESSMENT"));
|
|
1007
|
+
const absPath = targetSliceFile(basePath, milestoneId, sliceId, "ASSESSMENT", getMilestone(milestoneId)?.title);
|
|
1008
|
+
mkdirSync(dirname(absPath), { recursive: true });
|
|
1054
1009
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
1055
1010
|
const lines = [];
|
|
1056
1011
|
lines.push(`# ${sliceId} Assessment`);
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
//
|
|
5
5
|
// Exports: parseDecisionsTable, parseRequirementsSections, migrateFromMarkdown
|
|
6
6
|
import { readFileSync, readdirSync, existsSync, statSync } from 'node:fs';
|
|
7
|
-
import { join, basename } from 'node:path';
|
|
7
|
+
import { join, basename, dirname } from 'node:path';
|
|
8
8
|
import { upsertDecision, upsertRequirement, insertArtifact, insertMilestone, insertSlice, insertTask, transaction, updateMilestoneStatus, updateSliceStatus, _getAdapter, } from './gsd-db.js';
|
|
9
9
|
import { openWorkflowDatabasePath } from './db-workspace.js';
|
|
10
|
-
import { resolveGsdRootFile, resolveMilestoneFile, resolveSliceFile, resolveTasksDir, legacyMilestonesDir, gsdRoot, resolveTaskFiles, resolveMilestonePath, } from './paths.js';
|
|
10
|
+
import { resolveGsdRootFile, resolveMilestoneFile, resolveSliceFile, resolveSlicePath, resolveTasksDir, legacyMilestonesDir, gsdRoot, resolveTaskFiles, resolveMilestonePath, } from './paths.js';
|
|
11
11
|
import { findMilestoneIds } from './guided-flow.js';
|
|
12
12
|
import { milestoneIdToPhaseNum } from './layout-policy.js';
|
|
13
13
|
import { parseRoadmap, parsePlan } from './parsers-legacy.js';
|
|
14
|
-
import { parseContextDependsOn } from './files.js';
|
|
14
|
+
import { parseContextDependsOn, parseSummary } from './files.js';
|
|
15
15
|
import { logWarning } from './workflow-logger.js';
|
|
16
16
|
// ─── DECISIONS.md Parser ───────────────────────────────────────────────────
|
|
17
17
|
const VALID_MADE_BY = new Set(['human', 'agent', 'collaborative']);
|
|
@@ -662,21 +662,63 @@ export function migrateHierarchyToDb(basePath) {
|
|
|
662
662
|
for (const taskEntry of plan.tasks) {
|
|
663
663
|
// Per K002: use 'complete' not 'done'
|
|
664
664
|
let taskStatus = taskEntry.done ? 'complete' : 'pending';
|
|
665
|
-
//
|
|
666
|
-
//
|
|
667
|
-
//
|
|
668
|
-
//
|
|
669
|
-
//
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
665
|
+
// Resolve the per-task SUMMARY.md. Legacy layout keeps summaries under
|
|
666
|
+
// a tasks/ subdir; flat-phase writes TID-SUMMARY.md directly in the
|
|
667
|
+
// phase dir (execute-task's gsd_task_complete writes it there). A tasks/
|
|
668
|
+
// subdir may still exist in flat-phase for auxiliary artifacts — its
|
|
669
|
+
// mere existence must NOT redirect summary resolution into tasks/ (#1208).
|
|
670
|
+
const slicePath = resolveSlicePath(basePath, milestoneId, sliceEntry.id);
|
|
671
|
+
let taskSummaryFile = null;
|
|
672
|
+
let isLegacySlice = false;
|
|
673
|
+
// Legacy layout keeps per-task summaries under a tasks/ subdir. Its
|
|
674
|
+
// presence — not merely "is this a legacy slice" — is what makes a
|
|
675
|
+
// missing summary a downgrade signal. resolveTasksDir returns null when
|
|
676
|
+
// no such dir exists, so a legacy slice whose checkbox is the only
|
|
677
|
+
// completion signal (no tasks/ dir at all) is left complete on import.
|
|
678
|
+
let legacyTasksDir = null;
|
|
679
|
+
if (slicePath) {
|
|
680
|
+
isLegacySlice = basename(dirname(slicePath)) === 'slices';
|
|
681
|
+
legacyTasksDir = isLegacySlice
|
|
682
|
+
? resolveTasksDir(basePath, milestoneId, sliceEntry.id)
|
|
683
|
+
: null;
|
|
684
|
+
const summaryDir = legacyTasksDir ?? slicePath;
|
|
685
|
+
taskSummaryFile = join(summaryDir, `${taskEntry.id}-SUMMARY.md`);
|
|
686
|
+
}
|
|
687
|
+
const hasTaskSummary = taskSummaryFile !== null && existsSync(taskSummaryFile);
|
|
688
|
+
// Pre-migration consistency (legacy tasks/ layout only): if a task is
|
|
689
|
+
// marked done but its tasks/ dir has no per-task SUMMARY.md, import it
|
|
690
|
+
// as pending so it gets re-executed rather than silently entering the DB
|
|
691
|
+
// as complete. A legacy slice with no tasks/ dir (checkbox-only
|
|
692
|
+
// completion) and flat-phase layout are both left as-is here.
|
|
693
|
+
if (taskStatus === 'complete' && legacyTasksDir !== null && !hasTaskSummary) {
|
|
694
|
+
taskStatus = 'pending';
|
|
695
|
+
process.stderr.write(`gsd-migrate: ${milestoneId}/${sliceEntry.id}/${taskEntry.id} marked done but missing summary — importing as pending\n`);
|
|
696
|
+
}
|
|
697
|
+
// Lost-update guard (#1222): a per-task SUMMARY.md is the durable
|
|
698
|
+
// completion attestation written by gsd_task_complete. When the plan
|
|
699
|
+
// checkbox is stale-unchecked but the SUMMARY exists on disk, a
|
|
700
|
+
// re-import must NOT downgrade the completed task back to pending — that
|
|
701
|
+
// silent revert is the lost-update that hard-stopped auto-mode after the
|
|
702
|
+
// first execute-task. The surviving SUMMARY wins over a stale checkbox.
|
|
703
|
+
// reopen-task removes the SUMMARY, so this never re-completes an
|
|
704
|
+
// intentionally reopened task.
|
|
705
|
+
// Flat-phase summaries are phase-scoped (T01-SUMMARY.md); when a milestone
|
|
706
|
+
// has multiple slices, require the summary parent frontmatter to match so
|
|
707
|
+
// one slice's completion does not attest a sibling's same-named task.
|
|
708
|
+
let summaryAttestsCompletion = hasTaskSummary;
|
|
709
|
+
if (summaryAttestsCompletion && !isLegacySlice && roadmap.slices.length > 1 && taskSummaryFile) {
|
|
710
|
+
try {
|
|
711
|
+
const summaryContent = readFileSync(taskSummaryFile, 'utf-8');
|
|
712
|
+
summaryAttestsCompletion = parseSummary(summaryContent).frontmatter.parent === sliceEntry.id;
|
|
713
|
+
}
|
|
714
|
+
catch {
|
|
715
|
+
summaryAttestsCompletion = false;
|
|
678
716
|
}
|
|
679
717
|
}
|
|
718
|
+
if (taskStatus === 'pending' && summaryAttestsCompletion) {
|
|
719
|
+
taskStatus = 'complete';
|
|
720
|
+
process.stderr.write(`gsd-migrate: ${milestoneId}/${sliceEntry.id}/${taskEntry.id} unchecked in plan but SUMMARY.md present — importing as complete (#1222)\n`);
|
|
721
|
+
}
|
|
680
722
|
insertTask({
|
|
681
723
|
id: taskEntry.id,
|
|
682
724
|
sliceId: sliceEntry.id,
|
|
@@ -687,6 +729,12 @@ export function migrateHierarchyToDb(basePath) {
|
|
|
687
729
|
files: taskEntry.files ?? [],
|
|
688
730
|
verify: taskEntry.verify ?? '',
|
|
689
731
|
},
|
|
732
|
+
// #1222 (metadata half): re-import derives status from the plan/summary
|
|
733
|
+
// but has none of the execution prose gsd_task_complete wrote to the DB.
|
|
734
|
+
// Preserve the existing row's execution columns and completed_at so a
|
|
735
|
+
// re-import cannot blank a completed task's summary metadata or refresh
|
|
736
|
+
// its completion timestamp — the DB row is strictly richer than the plan.
|
|
737
|
+
preserveCompletionMetadata: true,
|
|
690
738
|
});
|
|
691
739
|
counts.tasks++;
|
|
692
740
|
}
|
|
@@ -699,14 +747,32 @@ export function migrateHierarchyToDb(basePath) {
|
|
|
699
747
|
if (!sliceEntry.done) {
|
|
700
748
|
const sliceSummaryPath = resolveSliceFile(basePath, milestoneId, sliceEntry.id, 'SUMMARY');
|
|
701
749
|
const hasSliceSummary = sliceSummaryPath !== null && existsSync(sliceSummaryPath);
|
|
750
|
+
const slicePathForTasks = resolveSlicePath(basePath, milestoneId, sliceEntry.id);
|
|
751
|
+
const isLegacySliceLayout = slicePathForTasks !== null
|
|
752
|
+
&& basename(dirname(slicePathForTasks)) === 'slices';
|
|
753
|
+
const taskSummaryDir = slicePathForTasks
|
|
754
|
+
? (isLegacySliceLayout
|
|
755
|
+
? (resolveTasksDir(basePath, milestoneId, sliceEntry.id) ?? slicePathForTasks)
|
|
756
|
+
: slicePathForTasks)
|
|
757
|
+
: null;
|
|
702
758
|
const allTasksDone = plan.tasks.length > 0 && plan.tasks.every(t => {
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
759
|
+
const taskSummaryFile = taskSummaryDir !== null
|
|
760
|
+
? join(taskSummaryDir, `${t.id}-SUMMARY.md`)
|
|
761
|
+
: null;
|
|
762
|
+
const hasTaskSummary = taskSummaryFile !== null && existsSync(taskSummaryFile);
|
|
763
|
+
let summaryAttestsCompletion = hasTaskSummary;
|
|
764
|
+
if (summaryAttestsCompletion && !isLegacySliceLayout && roadmap.slices.length > 1 && taskSummaryFile) {
|
|
765
|
+
try {
|
|
766
|
+
const summaryContent = readFileSync(taskSummaryFile, 'utf-8');
|
|
767
|
+
summaryAttestsCompletion = parseSummary(summaryContent).frontmatter.parent === sliceEntry.id;
|
|
768
|
+
}
|
|
769
|
+
catch {
|
|
770
|
+
summaryAttestsCompletion = false;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
// Match per-task import rules above: SUMMARY attestation wins over a stale
|
|
774
|
+
// checkbox (#1222); flat-phase checkboxes are authoritative without summary.
|
|
775
|
+
return summaryAttestsCompletion || (t.done && !isLegacySliceLayout);
|
|
710
776
|
});
|
|
711
777
|
if (allTasksDone && hasSliceSummary) {
|
|
712
778
|
if (_getAdapter()) {
|
|
@@ -172,7 +172,7 @@ export function snapshotUnitMetrics(ctx, unitType, unitId, startedAt, model, opt
|
|
|
172
172
|
ledger.units.push(unit);
|
|
173
173
|
}
|
|
174
174
|
saveLedger(basePath, ledger);
|
|
175
|
-
if (isUnifiedAuditEnabled()) {
|
|
175
|
+
if (isUnifiedAuditEnabled(basePath)) {
|
|
176
176
|
emitUokAuditEvent(basePath, buildAuditEnvelope({
|
|
177
177
|
traceId: opts?.traceId ?? `metrics:${unitType}:${unitId}`,
|
|
178
178
|
turnId: opts?.turnId,
|
|
@@ -324,7 +324,7 @@ export function snapshotUnitMetricsByScope(scope, ctx, unitType, unitId, started
|
|
|
324
324
|
scopedLedger.units.push(unit);
|
|
325
325
|
}
|
|
326
326
|
saveLedger(base, scopedLedger);
|
|
327
|
-
if (isUnifiedAuditEnabled()) {
|
|
327
|
+
if (isUnifiedAuditEnabled(base)) {
|
|
328
328
|
emitUokAuditEvent(base, buildAuditEnvelope({
|
|
329
329
|
traceId: opts?.traceId ?? `metrics:${unitType}:${unitId}`,
|
|
330
330
|
turnId: opts?.turnId,
|
|
@@ -56,14 +56,40 @@ function replaceSetPrefix(values, from, to) {
|
|
|
56
56
|
values.add(`${to}${value.slice(from.length)}`);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Rewrite one milestone identity across EVERY markdown identity set. The
|
|
61
|
+
* roadmapless subset is a view of `milestones`, so it must speak the same
|
|
62
|
+
* aligned vocabulary; otherwise the discussion-phase exclusion below keys off
|
|
63
|
+
* the stale bare id, fails its `dbScan.milestones.has(...)` membership check,
|
|
64
|
+
* and decrements the milestone count even though the aligned identity remains
|
|
65
|
+
* in the set, reporting false drift for a milestone that is actually in sync.
|
|
66
|
+
* Centralising the set list here keeps every alignment path from silently
|
|
67
|
+
* missing a set (the defect that regressed the suffixed roadmapless case).
|
|
68
|
+
*/
|
|
69
|
+
function realignMilestonePrefix(markdownScan, from, to) {
|
|
70
|
+
replaceSetPrefix(markdownScan.milestones, from, to);
|
|
71
|
+
replaceSetPrefix(markdownScan.slices, from, to);
|
|
72
|
+
replaceSetPrefix(markdownScan.tasks, from, to);
|
|
73
|
+
replaceSetPrefix(markdownScan.milestonesWithoutRoadmap, from, to);
|
|
74
|
+
}
|
|
59
75
|
function alignNumericMarkdownIdsWithDb(markdownScan, dbScan) {
|
|
60
76
|
for (const dbId of dbScan.milestones) {
|
|
61
77
|
const paddedId = paddedMilestoneId(dbId);
|
|
62
78
|
if (!paddedId || dbScan.milestones.has(paddedId) || !markdownScan.milestones.has(paddedId))
|
|
63
79
|
continue;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
80
|
+
realignMilestonePrefix(markdownScan, paddedId, dbId);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function bareMilestoneId(id) {
|
|
84
|
+
const match = id.match(/^(M\d{3})-[a-z0-9]{6}$/);
|
|
85
|
+
return match?.[1] ?? null;
|
|
86
|
+
}
|
|
87
|
+
function alignBareMarkdownIdsWithSuffixedDb(markdownScan, dbScan) {
|
|
88
|
+
for (const dbId of dbScan.milestones) {
|
|
89
|
+
const bareId = bareMilestoneId(dbId);
|
|
90
|
+
if (!bareId || dbScan.milestones.has(bareId) || !markdownScan.milestones.has(bareId))
|
|
91
|
+
continue;
|
|
92
|
+
realignMilestonePrefix(markdownScan, bareId, dbId);
|
|
67
93
|
}
|
|
68
94
|
}
|
|
69
95
|
/**
|
|
@@ -148,6 +174,7 @@ export async function checkMarkdownHierarchyAgainstDb(basePath) {
|
|
|
148
174
|
const dbScan = scanDbHierarchy();
|
|
149
175
|
const beforeDb = dbScan.counts;
|
|
150
176
|
alignNumericMarkdownIdsWithDb(markdownScan, dbScan);
|
|
177
|
+
alignBareMarkdownIdsWithSuffixedDb(markdownScan, dbScan);
|
|
151
178
|
// Discussion-phase scratch: a milestone dir with no ROADMAP and no DB row is
|
|
152
179
|
// a pre-registration discussion artifact (CONTEXT/CONTEXT-DRAFT only — the
|
|
153
180
|
// queued DB row is inserted only at discussion handoff). Treating it as
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
2
|
// File Purpose: Process-level transaction wrapper for milestone merge closeout.
|
|
3
|
+
import { mergeMilestoneToMain } from "./auto-worktree-merge.js";
|
|
3
4
|
export function runMilestoneMergeTransaction(deps, input) {
|
|
4
5
|
return deps.mergeMilestone(input.basePath, input.milestoneId, input.roadmapContent);
|
|
5
6
|
}
|
|
@@ -8,3 +9,13 @@ export function createMilestoneMergeTransaction(mergeMilestone) {
|
|
|
8
9
|
return runMilestoneMergeTransaction({ mergeMilestone }, { basePath, milestoneId, roadmapContent });
|
|
9
10
|
};
|
|
10
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Production merge transaction adapter.
|
|
14
|
+
*
|
|
15
|
+
* This is the only production construction point that knows the legacy
|
|
16
|
+
* `auto-worktree.ts` merge primitive. Lifecycle callers depend on the
|
|
17
|
+
* transaction runner interface, not the legacy implementation module.
|
|
18
|
+
*/
|
|
19
|
+
export function createDefaultMilestoneMergeTransaction(mergeMilestone = mergeMilestoneToMain) {
|
|
20
|
+
return createMilestoneMergeTransaction(mergeMilestone);
|
|
21
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
2
|
// File Purpose: Milestone closeout settlement state across DB proof, artifacts, merge, and cleanup.
|
|
3
|
-
import { isInAutoWorktree } from "./auto-worktree.js";
|
|
3
|
+
import { isInAutoWorktree } from "./auto-worktree-entry.js";
|
|
4
4
|
import { formatCloseoutProofBlock, proveMilestoneCloseout, } from "./milestone-closeout-proof.js";
|
|
5
5
|
import { resolveCloseoutArtifactProjection } from "./artifact-projection.js";
|
|
6
6
|
function isActiveUnmergedWorktree(input) {
|