@opengsd/gsd-pi 1.5.0-dev.553dc518 → 1.5.0-dev.c4c8885f
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/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/orchestrator.js +16 -10
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +14 -5
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +7 -2
- 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 +54 -31
- 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.js +97 -31
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +67 -6
- package/dist/resources/extensions/gsd/codebase-generator.js +7 -1
- 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/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/flat-phase-migration.js +18 -0
- package/dist/resources/extensions/gsd/gsd-db.js +12 -11
- package/dist/resources/extensions/gsd/guided-flow.js +16 -7
- package/dist/resources/extensions/gsd/journal.js +1 -1
- package/dist/resources/extensions/gsd/markdown-renderer.js +34 -91
- 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/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-validation.js +66 -10
- package/dist/resources/extensions/gsd/preferences.js +20 -0
- 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/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/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/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/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.js +5 -14
- 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 +10 -10
- 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 +10 -10
- 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/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 +1 -1
- package/integrations/hermes/pyproject.toml +1 -1
- package/package.json +1 -1
- 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/package.json +5 -5
- 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/package.json +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/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/orchestrator.ts +17 -11
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +14 -4
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +9 -2
- 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 +58 -29
- 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.ts +103 -30
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +66 -6
- package/src/resources/extensions/gsd/codebase-generator.ts +7 -1
- 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/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/flat-phase-migration.ts +20 -0
- package/src/resources/extensions/gsd/gsd-db.ts +20 -11
- package/src/resources/extensions/gsd/guided-flow.ts +19 -7
- package/src/resources/extensions/gsd/journal.ts +1 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +52 -103
- 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/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 +24 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +77 -9
- package/src/resources/extensions/gsd/preferences.ts +20 -0
- 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/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-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-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/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/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/flat-phase-migration.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +22 -1
- package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +72 -32
- package/src/resources/extensions/gsd/tests/import-completion-lost-update.test.ts +196 -0
- package/src/resources/extensions/gsd/tests/integration/paths.test.ts +88 -1
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -15
- 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/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.test.ts +19 -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/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/start-auto-detached.test.ts +32 -0
- 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/tool-call-loop-guard.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/uat-dispatch.test.ts +211 -0
- 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/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/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/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.ts +5 -21
- 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/{ZpFDazP-38PXBPiI_LdZf → NPMNi2HV8BuK3baQsEUhk}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{ZpFDazP-38PXBPiI_LdZf → NPMNi2HV8BuK3baQsEUhk}/_ssgManifest.js +0 -0
|
@@ -50,7 +50,7 @@ import { readSessionLockData, isSessionLockProcessAlive } from "./session-lock.j
|
|
|
50
50
|
import { nativeAddAll, nativeCommit, nativeHasCommittedHead, nativeIsRepo, nativeInit } from "./native-git-bridge.js";
|
|
51
51
|
import { isInheritedRepo } from "./repo-identity.js";
|
|
52
52
|
import { ensureGitignore, ensurePreferences, untrackRuntimeFiles } from "./gitignore.js";
|
|
53
|
-
import { getIsolationMode, loadEffectiveGSDPreferences } from "./preferences.js";
|
|
53
|
+
import { getIsolationMode, loadEffectiveGSDPreferences, renderLanguageDirectiveForPrompt } from "./preferences.js";
|
|
54
54
|
import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
|
|
55
55
|
import { resolveUokFlags } from "./uok/flags.js";
|
|
56
56
|
import { ensurePlanV2Graph, isMissingFinalizedContextResult } from "./uok/plan-v2.js";
|
|
@@ -921,7 +921,7 @@ function resolveAvailableModel<T extends { id: string; provider: string }>(
|
|
|
921
921
|
* Build the discuss-and-plan prompt for a new milestone.
|
|
922
922
|
* Used by all three "new milestone" paths (first ever, no active, all complete).
|
|
923
923
|
*/
|
|
924
|
-
function buildDiscussPrompt(nextId: string, preamble: string,
|
|
924
|
+
function buildDiscussPrompt(nextId: string, preamble: string, basePath: string, pi: ExtensionAPI, ctx: ExtensionCommandContext, preparationContext?: string): string {
|
|
925
925
|
const milestoneRel = `.gsd/milestones/${nextId}`;
|
|
926
926
|
const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
|
|
927
927
|
const inlinedTemplates = [
|
|
@@ -931,7 +931,7 @@ function buildDiscussPrompt(nextId: string, preamble: string, _basePath: string,
|
|
|
931
931
|
inlineTemplate("roadmap", "Roadmap"),
|
|
932
932
|
inlineTemplate("decisions", "Decisions"),
|
|
933
933
|
].join("\n\n---\n\n");
|
|
934
|
-
return loadPrompt("discuss", {
|
|
934
|
+
return prependLanguageDirective(basePath, loadPrompt("discuss", {
|
|
935
935
|
milestoneId: nextId,
|
|
936
936
|
preamble,
|
|
937
937
|
preparationContext: preparationContext ?? "",
|
|
@@ -941,14 +941,26 @@ function buildDiscussPrompt(nextId: string, preamble: string, _basePath: string,
|
|
|
941
941
|
inlinedTemplates,
|
|
942
942
|
commitInstruction: buildDocsCommitInstruction(`docs(${nextId}): context, requirements, and roadmap`),
|
|
943
943
|
multiMilestoneCommitInstruction: buildDocsCommitInstruction("docs: project plan — N milestones"),
|
|
944
|
-
});
|
|
944
|
+
}));
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* Prepend the configured response-language directive to a dispatched discuss
|
|
949
|
+
* prompt so the discuss/QA conversation is held in the language set in
|
|
950
|
+
* PREFERENCES.md (#1210). No-op when no language is configured.
|
|
951
|
+
*/
|
|
952
|
+
function prependLanguageDirective(basePath: string, prompt: string): string {
|
|
953
|
+
const directive = renderLanguageDirectiveForPrompt(
|
|
954
|
+
loadEffectiveGSDPreferences(basePath)?.preferences,
|
|
955
|
+
);
|
|
956
|
+
return directive ? `${directive}\n\n${prompt}` : prompt;
|
|
945
957
|
}
|
|
946
958
|
|
|
947
959
|
/**
|
|
948
960
|
* Build the discuss prompt for headless milestone creation.
|
|
949
961
|
* Uses the discuss-headless prompt template with seed context injected.
|
|
950
962
|
*/
|
|
951
|
-
function buildHeadlessDiscussPrompt(nextId: string, seedContext: string,
|
|
963
|
+
function buildHeadlessDiscussPrompt(nextId: string, seedContext: string, basePath: string): string {
|
|
952
964
|
const milestoneRel = `.gsd/milestones/${nextId}`;
|
|
953
965
|
const inlinedTemplates = [
|
|
954
966
|
inlineTemplate("project", "Project"),
|
|
@@ -957,7 +969,7 @@ function buildHeadlessDiscussPrompt(nextId: string, seedContext: string, _basePa
|
|
|
957
969
|
inlineTemplate("roadmap", "Roadmap"),
|
|
958
970
|
inlineTemplate("decisions", "Decisions"),
|
|
959
971
|
].join("\n\n---\n\n");
|
|
960
|
-
return loadPrompt("discuss-headless", {
|
|
972
|
+
return prependLanguageDirective(basePath, loadPrompt("discuss-headless", {
|
|
961
973
|
milestoneId: nextId,
|
|
962
974
|
seedContext,
|
|
963
975
|
contextPath: `${milestoneRel}/${nextId}-CONTEXT.md`,
|
|
@@ -965,7 +977,7 @@ function buildHeadlessDiscussPrompt(nextId: string, seedContext: string, _basePa
|
|
|
965
977
|
inlinedTemplates,
|
|
966
978
|
commitInstruction: buildDocsCommitInstruction(`docs(${nextId}): context, requirements, and roadmap`),
|
|
967
979
|
multiMilestoneCommitInstruction: buildDocsCommitInstruction("docs: project plan — N milestones"),
|
|
968
|
-
});
|
|
980
|
+
}));
|
|
969
981
|
}
|
|
970
982
|
|
|
971
983
|
/**
|
|
@@ -142,7 +142,7 @@ export function emitJournalEvent(basePath: string, entry: JournalEntry): void {
|
|
|
142
142
|
// Silent failure — journal must never break auto-mode
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
if (!isUnifiedAuditEnabled()) return;
|
|
145
|
+
if (!isUnifiedAuditEnabled(basePath)) return;
|
|
146
146
|
try {
|
|
147
147
|
const causedBy = entry.causedBy
|
|
148
148
|
? `${entry.causedBy.flowId}:${entry.causedBy.seq}`
|
|
@@ -38,9 +38,10 @@ import {
|
|
|
38
38
|
resolveSlicePath,
|
|
39
39
|
resolveTaskFile,
|
|
40
40
|
resolveTasksDir,
|
|
41
|
+
targetMilestoneFile,
|
|
42
|
+
targetSliceFile,
|
|
41
43
|
gsdProjectionRoot,
|
|
42
44
|
gsdRoot,
|
|
43
|
-
buildMilestoneFileName,
|
|
44
45
|
buildTaskFileName,
|
|
45
46
|
buildSliceFileName,
|
|
46
47
|
} from "./paths.js";
|
|
@@ -52,9 +53,6 @@ import { readCompatMarker, writeCompatMarker, computeProjectionSha } from "./com
|
|
|
52
53
|
import type { RiskLevel } from "./types.js";
|
|
53
54
|
import {
|
|
54
55
|
phaseDirName,
|
|
55
|
-
planFileName,
|
|
56
|
-
milestoneIdToPhaseNum,
|
|
57
|
-
sliceIdToPlanNum,
|
|
58
56
|
derivePhaseSlug,
|
|
59
57
|
} from "./layout-policy.js";
|
|
60
58
|
|
|
@@ -176,23 +174,6 @@ function sanitizeInlineRoadmapText(value: string | null | undefined): string {
|
|
|
176
174
|
.trim();
|
|
177
175
|
}
|
|
178
176
|
|
|
179
|
-
function resolveRoadmapProjectionPath(basePath: string, milestoneId: string): string {
|
|
180
|
-
const phaseNum = milestoneIdToPhaseNum(milestoneId);
|
|
181
|
-
const existing = resolveMilestonePath(basePath, milestoneId);
|
|
182
|
-
const legacyBase = legacyMilestonesDir(basePath);
|
|
183
|
-
const isLegacyLayout = existing
|
|
184
|
-
? existing.startsWith(legacyBase + "/") || existing.startsWith(legacyBase + "\\")
|
|
185
|
-
: isLegacyMilestonesLayout(basePath);
|
|
186
|
-
const phaseDir = existing ?? join(
|
|
187
|
-
isLegacyLayout ? legacyBase : milestonesDir(basePath),
|
|
188
|
-
isLegacyLayout ? milestoneId : canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title),
|
|
189
|
-
);
|
|
190
|
-
const roadmapFileName = isLegacyLayout
|
|
191
|
-
? `${milestoneId}-ROADMAP.md`
|
|
192
|
-
: `${String(phaseNum).padStart(2, "0")}-ROADMAP.md`;
|
|
193
|
-
return join(phaseDir, roadmapFileName);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
177
|
function isMilestoneFlatPhaseLayout(basePath: string, milestoneId: string): boolean {
|
|
197
178
|
const existing = resolveMilestonePath(basePath, milestoneId);
|
|
198
179
|
const legacyBase = legacyMilestonesDir(basePath);
|
|
@@ -600,7 +581,7 @@ export async function renderRoadmapFromDb(
|
|
|
600
581
|
"projection",
|
|
601
582
|
`renderRoadmapFromDb skipped unplanned milestone ${milestoneId} (zero slices, empty vision) — refusing to write a stub ROADMAP`,
|
|
602
583
|
);
|
|
603
|
-
const absPath =
|
|
584
|
+
const absPath = targetMilestoneFile(basePath, milestoneId, "ROADMAP", milestone.title);
|
|
604
585
|
if (existsSync(absPath)) {
|
|
605
586
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
606
587
|
unlinkSync(absPath);
|
|
@@ -614,7 +595,7 @@ export async function renderRoadmapFromDb(
|
|
|
614
595
|
return { skipped: "unplanned-milestone" };
|
|
615
596
|
}
|
|
616
597
|
|
|
617
|
-
const absPath =
|
|
598
|
+
const absPath = targetMilestoneFile(basePath, milestoneId, "ROADMAP", milestone.title);
|
|
618
599
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
619
600
|
const content = renderRoadmapMarkdown(milestone, slices);
|
|
620
601
|
|
|
@@ -655,25 +636,20 @@ export async function renderMilestoneArtifactsFromDb(
|
|
|
655
636
|
const artifacts = getMilestoneScopedArtifacts(milestoneId);
|
|
656
637
|
if (artifacts.length === 0) return false;
|
|
657
638
|
|
|
658
|
-
const
|
|
659
|
-
join(
|
|
660
|
-
milestonesDir(basePath),
|
|
661
|
-
canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title),
|
|
662
|
-
);
|
|
663
|
-
mkdirSync(phaseDir, { recursive: true });
|
|
664
|
-
|
|
665
|
-
const legacyBase = legacyMilestonesDir(basePath);
|
|
666
|
-
const isLegacy = phaseDir.startsWith(legacyBase + "/") || phaseDir.startsWith(legacyBase + "\\");
|
|
639
|
+
const milestone = getMilestone(milestoneId);
|
|
667
640
|
|
|
668
641
|
let wrote = false;
|
|
669
642
|
for (const artifact of artifacts) {
|
|
670
643
|
if (artifact.artifact_type === "ROADMAP") continue;
|
|
671
644
|
if (!artifact.full_content.trim()) continue;
|
|
672
645
|
|
|
673
|
-
const
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
646
|
+
const absPath = targetMilestoneFile(
|
|
647
|
+
basePath,
|
|
648
|
+
milestoneId,
|
|
649
|
+
artifact.artifact_type,
|
|
650
|
+
milestone?.title,
|
|
651
|
+
);
|
|
652
|
+
mkdirSync(dirname(absPath), { recursive: true });
|
|
677
653
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
678
654
|
await writeAndStore(absPath, artifactPath, artifact.full_content, {
|
|
679
655
|
artifact_type: artifact.artifact_type,
|
|
@@ -824,22 +800,12 @@ export async function renderSliceSummary(
|
|
|
824
800
|
return false; // No slice data — skip silently
|
|
825
801
|
}
|
|
826
802
|
|
|
827
|
-
|
|
828
|
-
// finds existing dirs. In flat-phase the slice "path" is the phase dir.
|
|
829
|
-
let slicePath = resolveSlicePath(basePath, milestoneId, sliceId);
|
|
830
|
-
if (!slicePath) {
|
|
831
|
-
const mDir = milestonesDir(basePath);
|
|
832
|
-
const dirName = canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title);
|
|
833
|
-
slicePath = join(mDir, dirName);
|
|
834
|
-
mkdirSync(slicePath, { recursive: true });
|
|
835
|
-
}
|
|
836
|
-
|
|
803
|
+
const milestoneTitle = getMilestone(milestoneId)?.title;
|
|
837
804
|
let wrote = false;
|
|
838
805
|
|
|
839
|
-
// Write SUMMARY — flat-phase: NN-MM-SUMMARY.md inside phase dir
|
|
840
806
|
if (slice.full_summary_md) {
|
|
841
|
-
const
|
|
842
|
-
|
|
807
|
+
const summaryAbs = targetSliceFile(basePath, milestoneId, sliceId, "SUMMARY", milestoneTitle);
|
|
808
|
+
mkdirSync(dirname(summaryAbs), { recursive: true });
|
|
843
809
|
const summaryArtifact = toArtifactPath(summaryAbs, basePath);
|
|
844
810
|
|
|
845
811
|
await writeAndStore(summaryAbs, summaryArtifact, slice.full_summary_md, {
|
|
@@ -850,10 +816,9 @@ export async function renderSliceSummary(
|
|
|
850
816
|
wrote = true;
|
|
851
817
|
}
|
|
852
818
|
|
|
853
|
-
// Write UAT — flat-phase: NN-MM-UAT.md inside phase dir
|
|
854
819
|
if (slice.full_uat_md) {
|
|
855
|
-
const
|
|
856
|
-
|
|
820
|
+
const uatAbs = targetSliceFile(basePath, milestoneId, sliceId, "UAT", milestoneTitle);
|
|
821
|
+
mkdirSync(dirname(uatAbs), { recursive: true });
|
|
857
822
|
const uatArtifact = toArtifactPath(uatAbs, basePath);
|
|
858
823
|
|
|
859
824
|
await writeAndStore(uatAbs, uatArtifact, slice.full_uat_md, {
|
|
@@ -1080,7 +1045,7 @@ function detectStaleRendersImpl(basePath: string): StaleEntry[] {
|
|
|
1080
1045
|
// TODO(flat-phase): roadmap checkbox parsing may not match flat-phase
|
|
1081
1046
|
// roadmap format, causing false-positive drift loops. Skip during transition.
|
|
1082
1047
|
/*
|
|
1083
|
-
const roadmapPath =
|
|
1048
|
+
const roadmapPath = targetMilestoneFile(basePath, milestone.id, "ROADMAP", milestone.title);
|
|
1084
1049
|
if (existsSync(roadmapPath)) {
|
|
1085
1050
|
try {
|
|
1086
1051
|
const parsed = parseProjectionByIdentity(roadmapPath, parseRoadmap) as ReturnType<typeof parseRoadmap>;
|
|
@@ -1172,36 +1137,28 @@ function detectStaleRendersImpl(basePath: string): StaleEntry[] {
|
|
|
1172
1137
|
}
|
|
1173
1138
|
}
|
|
1174
1139
|
|
|
1175
|
-
// Check missing slice summary/UAT files
|
|
1140
|
+
// Check missing slice summary/UAT files. Use the same target helper as
|
|
1141
|
+
// renderSliceSummary so detection and repair agree on flat-phase vs legacy
|
|
1142
|
+
// output locations.
|
|
1176
1143
|
const sliceRow = getSlice(milestone.id, slice.id);
|
|
1177
1144
|
if (sliceRow && sliceRow.status === "complete") {
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
if (sliceRow.full_summary_md) {
|
|
1186
|
-
const summaryName = planFileName(phaseNum, planNum, "SUMMARY");
|
|
1187
|
-
const summaryAbsPath = join(slicePath, summaryName);
|
|
1188
|
-
if (!existsSync(summaryAbsPath)) {
|
|
1189
|
-
stale.push({
|
|
1190
|
-
path: summaryAbsPath,
|
|
1191
|
-
reason: `${slice.id} is complete with summary in DB but SUMMARY.md missing on disk`,
|
|
1192
|
-
});
|
|
1193
|
-
}
|
|
1145
|
+
if (sliceRow.full_summary_md) {
|
|
1146
|
+
const summaryAbsPath = targetSliceFile(basePath, milestone.id, slice.id, "SUMMARY", milestone.title);
|
|
1147
|
+
if (!existsSync(summaryAbsPath)) {
|
|
1148
|
+
stale.push({
|
|
1149
|
+
path: summaryAbsPath,
|
|
1150
|
+
reason: `${slice.id} is complete with summary in DB but SUMMARY.md missing on disk`,
|
|
1151
|
+
});
|
|
1194
1152
|
}
|
|
1153
|
+
}
|
|
1195
1154
|
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
});
|
|
1204
|
-
}
|
|
1155
|
+
if (sliceRow.full_uat_md) {
|
|
1156
|
+
const uatAbsPath = targetSliceFile(basePath, milestone.id, slice.id, "UAT", milestone.title);
|
|
1157
|
+
if (!existsSync(uatAbsPath)) {
|
|
1158
|
+
stale.push({
|
|
1159
|
+
path: uatAbsPath,
|
|
1160
|
+
reason: `${slice.id} is complete with UAT in DB but UAT.md missing on disk`,
|
|
1161
|
+
});
|
|
1205
1162
|
}
|
|
1206
1163
|
}
|
|
1207
1164
|
}
|
|
@@ -1257,12 +1214,14 @@ export async function renderReplanFromDb(
|
|
|
1257
1214
|
sliceId: string,
|
|
1258
1215
|
replanData: ReplanData,
|
|
1259
1216
|
): Promise<{ replanPath: string; content: string }> {
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1217
|
+
const absPath = targetSliceFile(
|
|
1218
|
+
basePath,
|
|
1219
|
+
milestoneId,
|
|
1220
|
+
sliceId,
|
|
1221
|
+
"REPLAN",
|
|
1222
|
+
getMilestone(milestoneId)?.title,
|
|
1223
|
+
);
|
|
1224
|
+
mkdirSync(dirname(absPath), { recursive: true });
|
|
1266
1225
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
1267
1226
|
|
|
1268
1227
|
const lines: string[] = [];
|
|
@@ -1299,24 +1258,14 @@ export async function renderAssessmentFromDb(
|
|
|
1299
1258
|
sliceId: string,
|
|
1300
1259
|
assessmentData: AssessmentData,
|
|
1301
1260
|
): Promise<{ assessmentPath: string; content: string }> {
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
const isLegacyLayout = mDir
|
|
1311
|
-
? mDir.startsWith(legacyBase + "/") || mDir.startsWith(legacyBase + "\\")
|
|
1312
|
-
: false;
|
|
1313
|
-
const fallbackDir = join(milestonesDir(basePath), canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title));
|
|
1314
|
-
const slicePath = isLegacyLayout
|
|
1315
|
-
? (resolveSlicePath(basePath, milestoneId, sliceId) ?? fallbackDir)
|
|
1316
|
-
: (mDir ?? fallbackDir);
|
|
1317
|
-
const phaseNum = milestoneIdToPhaseNum(milestoneId);
|
|
1318
|
-
const planNum = sliceIdToPlanNum(sliceId);
|
|
1319
|
-
const absPath = join(slicePath, planFileName(phaseNum, planNum, "ASSESSMENT"));
|
|
1261
|
+
const absPath = targetSliceFile(
|
|
1262
|
+
basePath,
|
|
1263
|
+
milestoneId,
|
|
1264
|
+
sliceId,
|
|
1265
|
+
"ASSESSMENT",
|
|
1266
|
+
getMilestone(milestoneId)?.title,
|
|
1267
|
+
);
|
|
1268
|
+
mkdirSync(dirname(absPath), { recursive: true });
|
|
1320
1269
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
1321
1270
|
|
|
1322
1271
|
const lines: string[] = [];
|
|
@@ -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
|