@opengsd/gsd-pi 1.3.0-dev.eed73bea → 1.4.0-dev.5fc22c6f
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 +11 -11
- package/dist/cli.js +17 -4
- package/dist/headless-answers.js +1 -1
- package/dist/headless-ui.d.ts +1 -1
- package/dist/headless-ui.js +1 -1
- package/dist/headless.js +1 -1
- package/dist/onboarding.js +11 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +20 -25
- package/dist/resources/extensions/claude-code-cli/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +61 -50
- package/dist/resources/extensions/cursor-cli/index.js +16 -0
- package/dist/resources/extensions/cursor-cli/models.js +63 -0
- package/dist/resources/extensions/cursor-cli/package.json +11 -0
- package/dist/resources/extensions/cursor-cli/readiness.js +128 -0
- package/dist/resources/extensions/cursor-cli/stream-adapter.js +353 -0
- package/dist/resources/extensions/gsd/activity-log.js +4 -1
- package/dist/resources/extensions/gsd/artifact-verification.js +431 -0
- package/dist/resources/extensions/gsd/auto/session.js +11 -0
- package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +1 -1
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +28 -1
- package/dist/resources/extensions/gsd/auto-budget.js +5 -1
- package/dist/resources/extensions/gsd/auto-dispatch.js +32 -11
- package/dist/resources/extensions/gsd/auto-model-selection.js +36 -18
- package/dist/resources/extensions/gsd/auto-post-unit.js +1 -1
- package/dist/resources/extensions/gsd/auto-prompts.js +83 -25
- package/dist/resources/extensions/gsd/auto-recovery.js +9 -517
- package/dist/resources/extensions/gsd/auto-runtime-state.js +4 -5
- package/dist/resources/extensions/gsd/auto-start.js +4 -3
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +7 -3
- package/dist/resources/extensions/gsd/auto-verification.js +5 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +38 -11
- package/dist/resources/extensions/gsd/auto.js +32 -10
- package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +39 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +8 -4
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +147 -23
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +56 -36
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +29 -5
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +3 -1
- package/dist/resources/extensions/gsd/codebase-generator.js +157 -19
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +1 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +40 -4
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +154 -2
- package/dist/resources/extensions/gsd/commands-usage.js +1 -1
- package/dist/resources/extensions/gsd/commands-worktree.js +11 -2
- package/dist/resources/extensions/gsd/db/engine.js +4 -1
- package/dist/resources/extensions/gsd/db/queries.js +39 -0
- package/dist/resources/extensions/gsd/db-memory-fts-schema.js +34 -0
- package/dist/resources/extensions/gsd/db-workspace.js +55 -3
- package/dist/resources/extensions/gsd/delegation-policy.js +1 -1
- package/dist/resources/extensions/gsd/discussion-handoff.js +8 -3
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -4
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +227 -5
- package/dist/resources/extensions/gsd/doctor-providers.js +38 -10
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +3 -0
- package/dist/resources/extensions/gsd/doctor.js +93 -3
- package/dist/resources/extensions/gsd/exec-sandbox.js +14 -4
- package/dist/resources/extensions/gsd/flat-phase-migration.js +119 -23
- package/dist/resources/extensions/gsd/git-service.js +61 -8
- package/dist/resources/extensions/gsd/gitignore.js +4 -1
- package/dist/resources/extensions/gsd/guidance.js +1 -0
- package/dist/resources/extensions/gsd/guided-flow-queue.js +20 -13
- package/dist/resources/extensions/gsd/guided-flow.js +40 -2
- package/dist/resources/extensions/gsd/json-persistence.js +20 -0
- package/dist/resources/extensions/gsd/key-manager.js +1 -0
- package/dist/resources/extensions/gsd/knowledge-backfill.js +18 -11
- package/dist/resources/extensions/gsd/layout-policy.js +3 -1
- package/dist/resources/extensions/gsd/markdown-renderer.js +27 -15
- package/dist/resources/extensions/gsd/memory-backfill.js +28 -21
- package/dist/resources/extensions/gsd/metrics.js +4 -4
- package/dist/resources/extensions/gsd/migrate-external.js +22 -5
- package/dist/resources/extensions/gsd/migration-auto-check.js +22 -0
- package/dist/resources/extensions/gsd/milestone-ids.js +32 -2
- package/dist/resources/extensions/gsd/orphan-stash-audit.js +92 -16
- package/dist/resources/extensions/gsd/preferences-diagnostics.js +24 -1
- package/dist/resources/extensions/gsd/preferences-models.js +6 -4
- package/dist/resources/extensions/gsd/preferences-validation.js +25 -2
- package/dist/resources/extensions/gsd/preferences.js +29 -2
- package/dist/resources/extensions/gsd/prompts/code-review.md +6 -4
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +5 -3
- package/dist/resources/extensions/gsd/redact-secrets.js +37 -0
- package/dist/resources/extensions/gsd/repository-registry.js +6 -1
- package/dist/resources/extensions/gsd/root-write-leak-guard.js +7 -1
- package/dist/resources/extensions/gsd/safe-fs.js +23 -2
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +8 -1
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +16 -1
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +5 -2
- package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
- package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +2 -1
- package/dist/resources/extensions/gsd/state/derive/cache.js +28 -0
- package/dist/resources/extensions/gsd/state/derive/db-open.js +39 -0
- package/dist/resources/extensions/gsd/state/derive/from-db.js +452 -0
- package/dist/resources/extensions/gsd/state/derive/index.js +75 -0
- package/dist/resources/extensions/gsd/state/derive/interrupted-work.js +21 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +27 -33
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +48 -23
- package/dist/resources/extensions/gsd/state-reconciliation/registry.js +32 -28
- package/dist/resources/extensions/gsd/state.js +12 -611
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +4 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +3 -34
- package/dist/resources/extensions/gsd/tools/complete-task.js +8 -41
- package/dist/resources/extensions/gsd/tools/plan-slice.js +59 -44
- package/dist/resources/extensions/gsd/tools/plan-task.js +103 -12
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +40 -0
- package/dist/resources/extensions/gsd/undo.js +43 -6
- package/dist/resources/extensions/gsd/unit-context-manifest.js +5 -4
- package/dist/resources/extensions/gsd/unit-registry.js +11 -3
- package/dist/resources/extensions/gsd/unit-runtime.js +21 -0
- package/dist/resources/extensions/gsd/verification-gate.js +7 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +126 -13
- package/dist/resources/extensions/gsd/workflow-projections.js +19 -14
- package/dist/resources/extensions/gsd/workspace.js +26 -8
- package/dist/resources/extensions/gsd/worktree-manager.js +140 -5
- 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 +12 -12
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +9 -9
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +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/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
- 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/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-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/.next/static/chunks/{2659.b7b129ee6a769448.js → 2659.58e950899a9bb82f.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/2772.a7c1fcc69a4685ef.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{3616.3c60753b8ffcbd2e.js → 3616.61a2af74bb8833c8.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{4283.8e446784528ed9dc.js → 4283.d0d9e0a955e441cb.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{5826.a46ecdd1cfe8dabc.js → 5826.5421d66c72b9f34e.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{8785.481aa5869991b760.js → 8785.e29b3134cab1d153.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/8937.640dc9c2aaa1dfad.js +10 -0
- package/dist/web/standalone/.next/static/chunks/app/{page-6644fc6ee8ca1247.js → page-72a856634ad14c10.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/webpack-9c401904f87ded16.js +1 -0
- package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/wizard.d.ts +8 -0
- package/dist/wizard.js +8 -1
- package/integrations/hermes/__init__.py +31 -0
- package/integrations/hermes/tests/test_directory_loader.py +37 -0
- package/package.json +8 -8
- package/packages/cloud-mcp-gateway/dist/auth-store.d.ts +1 -0
- package/packages/cloud-mcp-gateway/dist/auth-store.d.ts.map +1 -1
- package/packages/cloud-mcp-gateway/dist/auth-store.js +21 -1
- package/packages/cloud-mcp-gateway/dist/auth-store.js.map +1 -1
- package/packages/cloud-mcp-gateway/dist/auth-store.test.js +34 -0
- package/packages/cloud-mcp-gateway/dist/auth-store.test.js.map +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/dist/cloud-runtime.d.ts +2 -0
- package/packages/daemon/dist/cloud-runtime.d.ts.map +1 -1
- package/packages/daemon/dist/cloud-runtime.js +25 -1
- package/packages/daemon/dist/cloud-runtime.js.map +1 -1
- package/packages/daemon/dist/cloud-runtime.test.js +51 -0
- package/packages/daemon/dist/cloud-runtime.test.js.map +1 -1
- package/packages/daemon/dist/message-batcher.d.ts +7 -0
- package/packages/daemon/dist/message-batcher.d.ts.map +1 -1
- package/packages/daemon/dist/message-batcher.js +13 -0
- package/packages/daemon/dist/message-batcher.js.map +1 -1
- package/packages/daemon/dist/message-batcher.test.js +48 -0
- package/packages/daemon/dist/message-batcher.test.js.map +1 -1
- package/packages/daemon/package.json +5 -5
- package/packages/gsd-agent-core/dist/agent-session.d.ts +1 -0
- package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/agent-session.js +3 -0
- package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.d.ts +13 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.js +15 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts +41 -0
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts.map +1 -0
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.js +62 -0
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.js.map +1 -0
- package/packages/gsd-agent-core/dist/index.d.ts +2 -0
- package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/index.js +2 -0
- package/packages/gsd-agent-core/dist/index.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-events.js +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-events.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +1 -0
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts +5 -0
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +60 -3
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
- package/packages/gsd-agent-core/dist/transcript-store.d.ts +58 -0
- package/packages/gsd-agent-core/dist/transcript-store.d.ts.map +1 -0
- package/packages/gsd-agent-core/dist/transcript-store.js +132 -0
- package/packages/gsd-agent-core/dist/transcript-store.js.map +1 -0
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +25 -11
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts +4 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js +7 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -24
- 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 +26 -841
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts +58 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js +312 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts +31 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js +130 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts +15 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +259 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts +13 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js +118 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +9 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts +54 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js +20 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +4 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +9 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts +56 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js +44 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js +77 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +24 -6
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +18 -0
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/workflow-tools.js +1 -1
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +3 -2
- 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/env-api-keys.d.ts.map +1 -1
- package/packages/pi-ai/dist/env-api-keys.js +3 -0
- package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +46 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +38 -0
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +2 -2
- 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/README.md +3 -2
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-context.js +94 -0
- package/packages/pi-coding-agent/dist/core/session-manager-context.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts +8 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.js +244 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts +12 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.js +84 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +135 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.js +2 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts +6 -154
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +22 -459
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts +75 -75
- package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme-schema.js +1 -1
- package/packages/pi-coding-agent/dist/theme/theme-schema.js.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.js +11 -7
- package/packages/pi-coding-agent/dist/theme/theme.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/dist/rpc-client.js +1 -1
- package/packages/rpc-client/dist/rpc-client.js.map +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/dist/theme/theme-schema.d.ts +75 -75
- package/pkg/dist/theme/theme-schema.d.ts.map +1 -1
- package/pkg/dist/theme/theme-schema.js +1 -1
- package/pkg/dist/theme/theme-schema.js.map +1 -1
- package/pkg/dist/theme/theme.d.ts.map +1 -1
- package/pkg/dist/theme/theme.js +11 -7
- package/pkg/dist/theme/theme.js.map +1 -1
- package/pkg/package.json +1 -1
- package/scripts/link-workspace-packages.cjs +14 -4
- package/src/resources/GSD-WORKFLOW.md +20 -25
- package/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +67 -49
- package/src/resources/extensions/claude-code-cli/tests/index.test.ts +14 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +159 -0
- package/src/resources/extensions/cursor-cli/index.ts +18 -0
- package/src/resources/extensions/cursor-cli/models.ts +65 -0
- package/src/resources/extensions/cursor-cli/package.json +11 -0
- package/src/resources/extensions/cursor-cli/readiness.ts +143 -0
- package/src/resources/extensions/cursor-cli/stream-adapter.ts +440 -0
- package/src/resources/extensions/cursor-cli/tests/index.test.ts +54 -0
- package/src/resources/extensions/cursor-cli/tests/readiness.test.ts +29 -0
- package/src/resources/extensions/cursor-cli/tests/stream-adapter.test.ts +166 -0
- package/src/resources/extensions/gsd/activity-log.ts +4 -1
- package/src/resources/extensions/gsd/artifact-verification.ts +468 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/session.ts +14 -0
- package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +3 -1
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +47 -1
- package/src/resources/extensions/gsd/auto-budget.ts +12 -1
- package/src/resources/extensions/gsd/auto-dispatch.ts +34 -12
- package/src/resources/extensions/gsd/auto-model-selection.ts +49 -18
- package/src/resources/extensions/gsd/auto-post-unit.ts +1 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +80 -25
- package/src/resources/extensions/gsd/auto-recovery.ts +13 -518
- package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -5
- package/src/resources/extensions/gsd/auto-start.ts +4 -3
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +7 -2
- package/src/resources/extensions/gsd/auto-verification.ts +5 -1
- package/src/resources/extensions/gsd/auto-worktree.ts +50 -11
- package/src/resources/extensions/gsd/auto.ts +36 -8
- package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +44 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +8 -4
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +171 -23
- package/src/resources/extensions/gsd/bootstrap/tests/write-gate-basepath.test.ts +49 -1
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +60 -37
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +39 -5
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +2 -1
- package/src/resources/extensions/gsd/codebase-generator.ts +179 -18
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +1 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +39 -3
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +136 -2
- package/src/resources/extensions/gsd/commands-usage.ts +1 -1
- package/src/resources/extensions/gsd/commands-worktree.ts +13 -2
- package/src/resources/extensions/gsd/db/engine.ts +8 -1
- package/src/resources/extensions/gsd/db/queries.ts +40 -0
- package/src/resources/extensions/gsd/db-memory-fts-schema.ts +45 -0
- package/src/resources/extensions/gsd/db-workspace.ts +61 -3
- package/src/resources/extensions/gsd/delegation-policy.ts +1 -1
- package/src/resources/extensions/gsd/discussion-handoff.ts +10 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -4
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +275 -5
- package/src/resources/extensions/gsd/doctor-providers.ts +39 -10
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +3 -0
- package/src/resources/extensions/gsd/doctor-types.ts +8 -1
- package/src/resources/extensions/gsd/doctor.ts +95 -3
- package/src/resources/extensions/gsd/exec-sandbox.ts +13 -4
- package/src/resources/extensions/gsd/flat-phase-migration.ts +142 -22
- package/src/resources/extensions/gsd/git-service.ts +70 -9
- package/src/resources/extensions/gsd/gitignore.ts +4 -1
- package/src/resources/extensions/gsd/guidance.ts +2 -0
- package/src/resources/extensions/gsd/guided-flow-queue.ts +20 -13
- package/src/resources/extensions/gsd/guided-flow.ts +45 -2
- package/src/resources/extensions/gsd/json-persistence.ts +20 -0
- package/src/resources/extensions/gsd/key-manager.ts +1 -0
- package/src/resources/extensions/gsd/knowledge-backfill.ts +16 -10
- package/src/resources/extensions/gsd/layout-policy.ts +2 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +27 -17
- package/src/resources/extensions/gsd/memory-backfill.ts +26 -20
- package/src/resources/extensions/gsd/metrics.ts +4 -4
- package/src/resources/extensions/gsd/migrate-external.ts +17 -4
- package/src/resources/extensions/gsd/migration-auto-check.ts +23 -0
- package/src/resources/extensions/gsd/milestone-ids.ts +31 -2
- package/src/resources/extensions/gsd/model-router.ts +4 -5
- package/src/resources/extensions/gsd/orphan-stash-audit.ts +108 -20
- package/src/resources/extensions/gsd/preferences-diagnostics.ts +24 -0
- package/src/resources/extensions/gsd/preferences-models.ts +6 -3
- package/src/resources/extensions/gsd/preferences-validation.ts +28 -2
- package/src/resources/extensions/gsd/preferences.ts +38 -4
- package/src/resources/extensions/gsd/prompts/code-review.md +6 -4
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +5 -3
- package/src/resources/extensions/gsd/redact-secrets.ts +40 -0
- package/src/resources/extensions/gsd/repository-registry.ts +7 -1
- package/src/resources/extensions/gsd/root-write-leak-guard.ts +13 -1
- package/src/resources/extensions/gsd/safe-fs.ts +22 -2
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +9 -1
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +16 -1
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +8 -2
- package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
- package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +2 -1
- package/src/resources/extensions/gsd/state/derive/cache.ts +46 -0
- package/src/resources/extensions/gsd/state/derive/db-open.ts +45 -0
- package/src/resources/extensions/gsd/state/derive/from-db.ts +561 -0
- package/src/resources/extensions/gsd/state/derive/index.ts +104 -0
- package/src/resources/extensions/gsd/state/derive/interrupted-work.ts +31 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +36 -30
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +50 -24
- package/src/resources/extensions/gsd/state-reconciliation/registry.ts +43 -28
- package/src/resources/extensions/gsd/state.ts +32 -732
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +98 -1
- package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +14 -5
- package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +178 -0
- package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +182 -4
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/auto-session-scope.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/auto-timeout-recovery-harness-abort.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/batch-task-query.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +365 -0
- package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +62 -1
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/db-memory-fts-schema.test.ts +58 -3
- package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +143 -0
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +138 -1
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +296 -2
- package/src/resources/extensions/gsd/tests/doctor-workspace.test.ts +207 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +74 -2
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +87 -19
- package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +11 -2
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/json-persistence-atomic.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +31 -1
- package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/metrics.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +57 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +91 -7
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +103 -4
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +307 -1
- package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/preferences.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +50 -14
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -6
- package/src/resources/extensions/gsd/tests/recovery-verify-logs.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/redact-secrets.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/register-hooks-flat-phase-migration.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +378 -0
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +41 -2
- package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +20 -1
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +15 -3
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +115 -0
- package/src/resources/extensions/gsd/tests/status-per-repo.test.ts +94 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +203 -0
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/undo.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +66 -18
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +53 -1
- package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +69 -4
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +96 -15
- package/src/resources/extensions/gsd/tests/workflow-mcp-preflight.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +214 -6
- package/src/resources/extensions/gsd/tests/workspace.test.ts +18 -4
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +31 -1
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +32 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
- package/src/resources/extensions/gsd/tools/complete-slice.ts +3 -30
- package/src/resources/extensions/gsd/tools/complete-task.ts +7 -39
- package/src/resources/extensions/gsd/tools/plan-slice.ts +60 -47
- package/src/resources/extensions/gsd/tools/plan-task.ts +135 -12
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +58 -0
- package/src/resources/extensions/gsd/undo.ts +47 -6
- package/src/resources/extensions/gsd/unit-context-manifest.ts +11 -5
- package/src/resources/extensions/gsd/unit-registry.ts +11 -3
- package/src/resources/extensions/gsd/unit-runtime.ts +42 -0
- package/src/resources/extensions/gsd/verification-gate.ts +8 -0
- package/src/resources/extensions/gsd/workflow-manifest.ts +141 -7
- package/src/resources/extensions/gsd/workflow-projections.ts +20 -14
- package/src/resources/extensions/gsd/workspace.ts +42 -8
- package/src/resources/extensions/gsd/worktree-manager.ts +183 -5
- package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +0 -1
- package/dist/web/standalone/.next/static/chunks/796.3976108148518f7d.js +0 -10
- package/dist/web/standalone/.next/static/chunks/webpack-7c1d97e39be2da11.js +0 -1
- /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → kIEFsCryyGy6RzifULbJl}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → kIEFsCryyGy6RzifULbJl}/_ssgManifest.js +0 -0
|
@@ -413,6 +413,46 @@ export function getSlicesByMilestoneIds(milestoneIds: readonly string[]): Map<st
|
|
|
413
413
|
return byMilestone;
|
|
414
414
|
}
|
|
415
415
|
|
|
416
|
+
/**
|
|
417
|
+
* Load tasks for many (milestone, slice) pairs in batched queries. Returns a Map
|
|
418
|
+
* keyed by `${milestone_id}\0${slice_id}`, preserving `ORDER BY sequence, id`
|
|
419
|
+
* within each bucket. Mirrors getSlicesByMilestoneIds to avoid an N+1 over tasks
|
|
420
|
+
* during full projection rebuilds.
|
|
421
|
+
*/
|
|
422
|
+
export function getTasksBySliceIds(
|
|
423
|
+
slices: ReadonlyArray<{ milestoneId: string; sliceId: string }>,
|
|
424
|
+
): Map<string, TaskRow[]> {
|
|
425
|
+
const bySlice = new Map<string, TaskRow[]>();
|
|
426
|
+
const db = getDbOrNull();
|
|
427
|
+
if (!db || slices.length === 0) return bySlice;
|
|
428
|
+
// SQLite caps bound params (~999); 2 per pair, so chunk well under the limit.
|
|
429
|
+
const CHUNK = 400;
|
|
430
|
+
for (let start = 0; start < slices.length; start += CHUNK) {
|
|
431
|
+
const chunk = slices.slice(start, start + CHUNK);
|
|
432
|
+
const clauses: string[] = [];
|
|
433
|
+
const params: Record<string, unknown> = {};
|
|
434
|
+
chunk.forEach((s, i) => {
|
|
435
|
+
clauses.push(`(milestone_id = :m${i} AND slice_id = :s${i})`);
|
|
436
|
+
params[`:m${i}`] = s.milestoneId;
|
|
437
|
+
params[`:s${i}`] = s.sliceId;
|
|
438
|
+
});
|
|
439
|
+
const rows = db
|
|
440
|
+
.prepare(`SELECT * FROM tasks WHERE ${clauses.join(" OR ")} ORDER BY milestone_id, slice_id, sequence, id`)
|
|
441
|
+
.all(params) as Record<string, unknown>[];
|
|
442
|
+
for (const row of rows) {
|
|
443
|
+
const task = rowToTask(row);
|
|
444
|
+
const key = `${task.milestone_id}\0${task.slice_id}`;
|
|
445
|
+
const bucket = bySlice.get(key);
|
|
446
|
+
if (bucket) {
|
|
447
|
+
bucket.push(task);
|
|
448
|
+
} else {
|
|
449
|
+
bySlice.set(key, [task]);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return bySlice;
|
|
454
|
+
}
|
|
455
|
+
|
|
416
456
|
/** Dispatch-eligibility shape consumed by decision-path callers (ADR-017). */
|
|
417
457
|
export interface MilestoneSliceSummary {
|
|
418
458
|
id: string;
|
|
@@ -2,11 +2,18 @@
|
|
|
2
2
|
// File Purpose: Memory FTS5 SQLite schema helpers for the GSD database facade.
|
|
3
3
|
|
|
4
4
|
import type { DbAdapter } from "./db-adapter.js";
|
|
5
|
+
import { createRuntimeKvTableV25 } from "./db-runtime-kv-schema.js";
|
|
6
|
+
|
|
7
|
+
export const MEMORIES_FTS_REBUILT_KEY = "memories_fts_rebuilt_at";
|
|
5
8
|
|
|
6
9
|
export interface MemoryFtsSchemaOptions {
|
|
7
10
|
onUnavailable?: (message: string) => void;
|
|
8
11
|
}
|
|
9
12
|
|
|
13
|
+
export interface MemoryFtsRebuildOptions {
|
|
14
|
+
onRebuildFailed?: (message: string) => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
10
17
|
function formatFtsUnavailableError(err: unknown): string {
|
|
11
18
|
const message = err instanceof Error ? err.message : String(err);
|
|
12
19
|
return message.replace(/\bmoduel\s*:\s*/gi, "module: ");
|
|
@@ -64,3 +71,41 @@ export function isMemoriesFtsAvailableSchema(db: DbAdapter): boolean {
|
|
|
64
71
|
return false;
|
|
65
72
|
}
|
|
66
73
|
}
|
|
74
|
+
|
|
75
|
+
export function rebuildMemoriesFtsSchemaOnce(
|
|
76
|
+
db: DbAdapter,
|
|
77
|
+
options: MemoryFtsRebuildOptions = {},
|
|
78
|
+
): void {
|
|
79
|
+
if (!isMemoriesFtsAvailableSchema(db)) return;
|
|
80
|
+
|
|
81
|
+
createRuntimeKvTableV25(db);
|
|
82
|
+
const marker = db.prepare(
|
|
83
|
+
"SELECT 1 as present FROM runtime_kv WHERE scope = 'global' AND scope_id = '' AND key = :key",
|
|
84
|
+
).get({ ":key": MEMORIES_FTS_REBUILT_KEY });
|
|
85
|
+
if (marker) return;
|
|
86
|
+
|
|
87
|
+
const now = new Date().toISOString();
|
|
88
|
+
try {
|
|
89
|
+
db.exec("BEGIN");
|
|
90
|
+
db.exec("INSERT INTO memories_fts(memories_fts) VALUES('rebuild')");
|
|
91
|
+
db.prepare(
|
|
92
|
+
`INSERT INTO runtime_kv (scope, scope_id, key, value_json, updated_at)
|
|
93
|
+
VALUES ('global', '', :key, :value_json, :updated_at)
|
|
94
|
+
ON CONFLICT (scope, scope_id, key) DO UPDATE SET
|
|
95
|
+
value_json = excluded.value_json,
|
|
96
|
+
updated_at = excluded.updated_at`,
|
|
97
|
+
).run({
|
|
98
|
+
":key": MEMORIES_FTS_REBUILT_KEY,
|
|
99
|
+
":value_json": JSON.stringify(now),
|
|
100
|
+
":updated_at": now,
|
|
101
|
+
});
|
|
102
|
+
db.exec("COMMIT");
|
|
103
|
+
} catch (err) {
|
|
104
|
+
try {
|
|
105
|
+
db.exec("ROLLBACK");
|
|
106
|
+
} catch {
|
|
107
|
+
// Best effort: leave startup alive and retry the rebuild on next open.
|
|
108
|
+
}
|
|
109
|
+
options.onRebuildFailed?.(`FTS5 rebuild failed: ${(err as Error).message}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// File Purpose: Workspace-facing Interface for opening and maintaining the workflow database.
|
|
3
3
|
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
|
-
import { dirname } from "node:path";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
6
|
|
|
7
7
|
import type { GsdWorkspace, MilestoneScope } from "./workspace.js";
|
|
8
8
|
import type { DbAdapter } from "./db-adapter.js";
|
|
@@ -24,8 +24,8 @@ import {
|
|
|
24
24
|
vacuumDatabase,
|
|
25
25
|
wasDbOpenAttempted,
|
|
26
26
|
} from "./gsd-db.js";
|
|
27
|
-
import { resolveGsdPathContract } from "./paths.js";
|
|
28
|
-
import { setLogBasePath } from "./workflow-logger.js";
|
|
27
|
+
import { resolveGsdPathContract, gsdRoot } from "./paths.js";
|
|
28
|
+
import { logWarning, setLogBasePath } from "./workflow-logger.js";
|
|
29
29
|
|
|
30
30
|
export interface WorkflowDatabaseLocation {
|
|
31
31
|
projectRoot: string;
|
|
@@ -56,6 +56,20 @@ export type WorkflowDatabaseOpenResult =
|
|
|
56
56
|
export type WorkflowDatabaseStatus = ReturnType<typeof getDbStatus>;
|
|
57
57
|
export type WorkflowDatabaseProvider = ReturnType<typeof getDbProvider>;
|
|
58
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Global SQLite handle invariants:
|
|
61
|
+
*
|
|
62
|
+
* - `openWorkflowDatabase` / `openDatabase` switch the process-global handle consumed by
|
|
63
|
+
* deriveState, dispatch, reconciliation repairs, and domain writers. Only one active
|
|
64
|
+
* project database should own the global handle at a time.
|
|
65
|
+
* - `openWorkflowDatabaseIsolated` opens a caller-owned connection that does not clobber
|
|
66
|
+
* the global handle. Use for read-only observers (parallel monitor) and other background
|
|
67
|
+
* probes that must not disturb the active workflow session.
|
|
68
|
+
* - Reconciliation repairs that write markdown/DB state must use `ensureWorkflowDbForBase`
|
|
69
|
+
* so repairs target the correct project; those paths intentionally re-open the global handle.
|
|
70
|
+
* - Pair ad-hoc project switches with `closeWorkflowDatabase()` or restore via
|
|
71
|
+
* `ensureWorkflowDbForBase(..., { refresh: true })` before returning to derive/dispatch.
|
|
72
|
+
*/
|
|
59
73
|
export function resolveWorkflowDatabaseLocation(basePath: string): WorkflowDatabaseLocation {
|
|
60
74
|
const contract = resolveGsdPathContract(basePath);
|
|
61
75
|
return {
|
|
@@ -172,6 +186,50 @@ export function refreshWorkflowDatabaseFromDisk(): boolean {
|
|
|
172
186
|
return refreshOpenDatabaseFromDisk();
|
|
173
187
|
}
|
|
174
188
|
|
|
189
|
+
export function expectedWorkflowDbPathForBase(basePath: string): string {
|
|
190
|
+
return join(gsdRoot(basePath), "gsd.db");
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export interface EnsureWorkflowDbOptions {
|
|
194
|
+
/** When true, refresh from disk before reopening if already open on the correct path. */
|
|
195
|
+
refresh?: boolean;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function ensureWorkflowDbAtPath(dbPath: string | null): boolean {
|
|
199
|
+
if (!dbPath || dbPath === ":memory:") return isDbAvailable();
|
|
200
|
+
if (isDbAvailable() && getWorkflowDatabasePath() === dbPath) return true;
|
|
201
|
+
if (!existsSync(dbPath)) return false;
|
|
202
|
+
try {
|
|
203
|
+
return openWorkflowDatabasePath(dbPath);
|
|
204
|
+
} catch (err) {
|
|
205
|
+
logWarning("reconcile", `ensureWorkflowDbAtPath could not reopen DB: ${(err as Error).message}`);
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function ensureWorkflowDbForBase(
|
|
211
|
+
basePath: string,
|
|
212
|
+
options: EnsureWorkflowDbOptions = {},
|
|
213
|
+
): boolean {
|
|
214
|
+
const dbPath = expectedWorkflowDbPathForBase(basePath);
|
|
215
|
+
if (!existsSync(dbPath)) return false;
|
|
216
|
+
|
|
217
|
+
try {
|
|
218
|
+
if (options.refresh) {
|
|
219
|
+
if (isDbAvailable() && getWorkflowDatabasePath() === dbPath && refreshWorkflowDatabaseFromDisk()) {
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
222
|
+
return openWorkflowDatabasePath(dbPath);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (isDbAvailable() && getWorkflowDatabasePath() === dbPath) return true;
|
|
226
|
+
return openWorkflowDatabasePath(dbPath);
|
|
227
|
+
} catch (err) {
|
|
228
|
+
logWarning("reconcile", `ensureWorkflowDbForBase could not reopen DB: ${(err as Error).message}`);
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
175
233
|
export function checkpointWorkflowDatabase(): void {
|
|
176
234
|
checkpointDatabase();
|
|
177
235
|
}
|
|
@@ -121,7 +121,7 @@ const POLICY: Record<string, DelegationPolicyEntry> = {
|
|
|
121
121
|
toolName: "gsd_plan_task",
|
|
122
122
|
verdict: "no",
|
|
123
123
|
rationale:
|
|
124
|
-
"
|
|
124
|
+
"Incremental task planning mutates the active slice plan and re-renders projections; keep it ordered in the foreground plan-slice unit.",
|
|
125
125
|
},
|
|
126
126
|
};
|
|
127
127
|
|
|
@@ -82,7 +82,13 @@ function ensureMilestoneRowForAcceptedHandoff(
|
|
|
82
82
|
entry: PendingAutoStartEntry,
|
|
83
83
|
contextFile: string | null,
|
|
84
84
|
): boolean {
|
|
85
|
-
if (!isDbAvailable())
|
|
85
|
+
if (!isDbAvailable()) {
|
|
86
|
+
logWarning(
|
|
87
|
+
"guided",
|
|
88
|
+
`R3b: milestone ${entry.milestoneId} DB-row recovery skipped because DB is unavailable`,
|
|
89
|
+
);
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
86
92
|
|
|
87
93
|
const { basePath, milestoneId } = entry;
|
|
88
94
|
const milestoneRow = getMilestone(milestoneId);
|
|
@@ -122,12 +128,14 @@ function ensureMilestoneRowForAcceptedHandoff(
|
|
|
122
128
|
`(attempt ${entry.r3bRecoveryCount + 1}/${MAX_DB_ROW_RECOVERIES})`,
|
|
123
129
|
);
|
|
124
130
|
|
|
131
|
+
let inserted = false;
|
|
125
132
|
try {
|
|
126
|
-
insertMilestone({ id: milestoneId, title: milestoneId, status: "queued" });
|
|
133
|
+
inserted = insertMilestone({ id: milestoneId, title: milestoneId, status: "queued" });
|
|
127
134
|
} catch (e) {
|
|
128
135
|
logWarning("guided", `R3b: insertMilestone failed: ${(e as Error).message}`);
|
|
129
136
|
}
|
|
130
137
|
|
|
138
|
+
if (inserted) return true;
|
|
131
139
|
if (getMilestone(milestoneId)) return true;
|
|
132
140
|
|
|
133
141
|
noteDbRowRecoveryMiss(entry);
|
|
@@ -163,7 +163,7 @@ Diagnostics record the file path, scope (global/project), severity (error/warnin
|
|
|
163
163
|
- **Deprecated:** `merge_to_main` — no longer valid; milestone-level merge is always used. Remove this setting.
|
|
164
164
|
|
|
165
165
|
- `workspace`: configures multi-repository parent workspaces. Keys:
|
|
166
|
-
- `mode`: `"project"` (default single-repo behavior) or `"parent"` (one `.gsd` controlling child repos).
|
|
166
|
+
- `mode`: `"project"` (default single-repo behavior) or `"parent"` (one `.gsd` controlling child repos). In `"parent"` mode at least one child repository must be declared under `repositories`, otherwise the setting is rejected at validation time.
|
|
167
167
|
- `repositories`: object map of repository IDs to config.
|
|
168
168
|
- Repository ID format: `^[A-Za-z0-9][A-Za-z0-9._-]*$`.
|
|
169
169
|
- Reserved ID: `project` is implicit and always maps to the project root; user-defined `workspace.repositories.project` is rejected.
|
|
@@ -171,6 +171,8 @@ Diagnostics record the file path, scope (global/project), severity (error/warnin
|
|
|
171
171
|
- `role`: optional short description of what the repo owns.
|
|
172
172
|
- `verification`: optional array of verification commands for that repo.
|
|
173
173
|
- `commit_policy`: optional `"auto"` or `"skip"` to include or skip commit actions per repo.
|
|
174
|
+
- Planning tools consume repository IDs through `targetRepositories`: `gsd_plan_slice.targetRepositories` sets a slice-wide default, and `gsd_plan_task.targetRepositories` records the repositories an individual task touches. Values must be declared IDs or the implicit `project`; omit these fields in single-repo projects.
|
|
175
|
+
- In parent mode with declared child repositories, `/gsd codebase generate` and automatic `.gsd/CODEBASE.md` refreshes enumerate `project` plus each child repository, render repo-labeled sections, and store repository IDs in map metadata.
|
|
174
176
|
|
|
175
177
|
## Workspace Example
|
|
176
178
|
|
|
@@ -198,6 +200,8 @@ workspace:
|
|
|
198
200
|
|
|
199
201
|
This config sets a parent workspace with two child repositories. The implicit `project` repository is always created for the project root and cannot be user-defined.
|
|
200
202
|
|
|
203
|
+
In `"parent"` mode, slice/task `targetRepositories` default to the declared child repositories (here `frontend` and `backend`) rather than the root `project` repo. In `"project"` mode (the default), `targetRepositories` defaults to `["project"]`.
|
|
204
|
+
|
|
201
205
|
- `unique_milestone_ids`: boolean — when `true`, generates milestone IDs in `M{seq}-{rand6}` format (e.g. `M001-eh88as`) instead of plain sequential `M001`. Prevents ID collisions in team workflows where multiple contributors create milestones concurrently. Both formats coexist — existing `M001`-style milestones remain valid. Default: `false`.
|
|
202
206
|
|
|
203
207
|
- `budget_ceiling`: number — maximum dollar amount to spend on auto-mode. When reached, behavior is controlled by `budget_enforcement`. Default: no limit.
|
|
@@ -273,10 +277,10 @@ This config sets a parent workspace with two child repositories. The implicit `p
|
|
|
273
277
|
- `audit_unified.enabled`: boolean — dual-write unified audit envelope events. Default: `true`.
|
|
274
278
|
- `plan_v2.enabled`: boolean — enable bounded clarify/research/draft/compile planning flow. Default: `true`.
|
|
275
279
|
|
|
276
|
-
- `context_management`: configures context hygiene for auto-mode sessions. Keys:
|
|
280
|
+
- `context_management`: configures context hygiene for auto-mode sessions. In step mode, the configurable threshold is a soft warning; automatic session re-rooting happens only at the fixed 90% hard context boundary. Keys:
|
|
277
281
|
- `observation_masking`: boolean — mask old tool results to reduce context bloat. Default: `true`.
|
|
278
282
|
- `observation_mask_turns`: number — keep this many recent turns verbatim (1-50). Default: `8`.
|
|
279
|
-
- `compaction_threshold_percent`: number —
|
|
283
|
+
- `compaction_threshold_percent`: number — show a soft context warning at this fraction of the context window (0.5-0.95). Lower values warn earlier so operators can compact manually before drift accumulates. Default: `0.60`.
|
|
280
284
|
- `tool_result_max_chars`: number — max chars per tool result in GSD sessions (200-10000). Default: `800`.
|
|
281
285
|
|
|
282
286
|
- `auto_visualize`: boolean — show a visualizer hint after each milestone completion in auto-mode. Default: `false`.
|
|
@@ -303,7 +307,9 @@ This config sets a parent workspace with two child repositories. The implicit `p
|
|
|
303
307
|
- `verification`: string[] (optional) — repository-specific verification commands used when global `verification_commands` is not set.
|
|
304
308
|
- `commit_policy`: `"auto"` | `"skip"` (optional) — per-repository closeout commit behavior.
|
|
305
309
|
- `project` is always an implicit repository target mapped to the project root for backward compatibility.
|
|
306
|
-
-
|
|
310
|
+
- `targetRepositories` on `gsd_plan_slice` sets the slice-wide default. `targetRepositories` on `gsd_plan_task` records or overrides the repository IDs for an individual task.
|
|
311
|
+
- Values must match declared repository IDs or the implicit `project`; omitted plan/task `targetRepositories` defaults to `["project"]`.
|
|
312
|
+
- `/gsd codebase` is workspace-aware in parent mode with declared child repositories: generated `.gsd/CODEBASE.md` uses workspace-relative paths, groups files under `## [repo-id]` headings, and refreshes when repository registry metadata changes.
|
|
307
313
|
|
|
308
314
|
- `verification_commands`: string[] — shell commands to run as verification after task execution (e.g., `["npm test", "npm run lint"]`). Commands run in order; if any fails, the task is marked as needing fixes.
|
|
309
315
|
|
|
@@ -1,19 +1,173 @@
|
|
|
1
|
-
import { existsSync, statSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
1
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { isAbsolute, join, relative } from "node:path";
|
|
3
3
|
|
|
4
4
|
import type { DoctorIssue } from "./doctor-types.js";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
getAllMilestones,
|
|
7
|
+
getMilestoneSlices,
|
|
8
|
+
getSliceTasks,
|
|
9
|
+
isDbAvailable,
|
|
10
|
+
isMemoriesFtsAvailable,
|
|
11
|
+
_getAdapter,
|
|
12
|
+
} from "./gsd-db.js";
|
|
13
|
+
import { MEMORIES_FTS_REBUILT_KEY } from "./db-memory-fts-schema.js";
|
|
6
14
|
import { isAfter, latestExplicitReopenAt } from "./milestone-reopen-events.js";
|
|
7
|
-
import { resolveGsdPathContract, resolveMilestoneFile } from "./paths.js";
|
|
15
|
+
import { gsdProjectionRoot, gsdRoot, resolveGsdPathContract, resolveMilestoneFile, resolveSliceFile } from "./paths.js";
|
|
8
16
|
import { deriveState } from "./state.js";
|
|
17
|
+
import { isClosedStatus } from "./status-guards.js";
|
|
9
18
|
import { workflowEventLogPath } from "./workflow-event-ledger.js";
|
|
10
19
|
import { readEvents } from "./workflow-events.js";
|
|
11
20
|
import { flushWorkflowProjections } from "./projection-flush.js";
|
|
21
|
+
import { parseRoadmapSlices } from "./roadmap-slices.js";
|
|
22
|
+
import { parsePlan } from "./parsers-legacy.js";
|
|
23
|
+
|
|
24
|
+
const USER_AUTHORED_ARTIFACT_TYPES = new Set(["CONTEXT", "RESEARCH"]);
|
|
25
|
+
|
|
26
|
+
function relativeFile(basePath: string, filePath: string): string {
|
|
27
|
+
return relative(basePath, filePath).split("\\").join("/");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function normalizedArtifactType(artifactType: string): string {
|
|
31
|
+
return artifactType.trim().toUpperCase();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function isUserAuthoredArtifactType(artifactType: string): boolean {
|
|
35
|
+
return USER_AUTHORED_ARTIFACT_TYPES.has(normalizedArtifactType(artifactType));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function userContentRecoveryCommand(artifactType: string): string {
|
|
39
|
+
return normalizedArtifactType(artifactType) === "CONTEXT" ? "/gsd discuss" : "/gsd auto";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function userContentMissingMessage(path: string, artifactType: string): string {
|
|
43
|
+
const type = normalizedArtifactType(artifactType) || "UNKNOWN";
|
|
44
|
+
return `Artifact \`${path}\` is a user-authored ${type} file recorded in the database but missing from disk. Re-run \`${userContentRecoveryCommand(type)}\` in this milestone to regenerate it.`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function reportCheckboxDbStatusDivergence(
|
|
48
|
+
issues: DoctorIssue[],
|
|
49
|
+
basePath: string,
|
|
50
|
+
filePath: string,
|
|
51
|
+
scope: "slice" | "task",
|
|
52
|
+
unitId: string,
|
|
53
|
+
status: string,
|
|
54
|
+
checkboxDone: boolean,
|
|
55
|
+
): void {
|
|
56
|
+
const dbDone = isClosedStatus(status);
|
|
57
|
+
if (checkboxDone === dbDone) return;
|
|
58
|
+
|
|
59
|
+
issues.push({
|
|
60
|
+
severity: "error",
|
|
61
|
+
code: "checkbox_db_status_divergence",
|
|
62
|
+
scope,
|
|
63
|
+
unitId,
|
|
64
|
+
message: `${scope === "slice" ? "Slice" : "Task"} ${unitId} is ${dbDone ? "closed" : "open"} in the database (status: ${status}) but the markdown checkbox is ${checkboxDone ? "checked" : "unchecked"}.`,
|
|
65
|
+
file: relativeFile(basePath, filePath),
|
|
66
|
+
fixable: false,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function checkProjectionCheckboxDbStatus(basePath: string, milestoneIds: string[], issues: DoctorIssue[]): void {
|
|
71
|
+
for (const milestoneId of milestoneIds) {
|
|
72
|
+
const roadmapPath = resolveMilestoneFile(basePath, milestoneId, "ROADMAP");
|
|
73
|
+
const slices = getMilestoneSlices(milestoneId);
|
|
74
|
+
|
|
75
|
+
if (roadmapPath && existsSync(roadmapPath)) {
|
|
76
|
+
try {
|
|
77
|
+
const roadmap = readFileSync(roadmapPath, "utf-8");
|
|
78
|
+
const sliceDoneById = new Map(parseRoadmapSlices(roadmap).map((entry) => [entry.id, entry.done]));
|
|
79
|
+
for (const slice of slices) {
|
|
80
|
+
const checkboxDone = sliceDoneById.get(slice.id);
|
|
81
|
+
if (checkboxDone === undefined) continue;
|
|
82
|
+
reportCheckboxDbStatusDivergence(
|
|
83
|
+
issues,
|
|
84
|
+
basePath,
|
|
85
|
+
roadmapPath,
|
|
86
|
+
"slice",
|
|
87
|
+
`${milestoneId}/${slice.id}`,
|
|
88
|
+
slice.status,
|
|
89
|
+
checkboxDone,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
} catch {
|
|
93
|
+
// Non-fatal — checkbox drift diagnostics must never block doctor.
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
for (const slice of slices) {
|
|
98
|
+
const planPath = resolveSliceFile(basePath, milestoneId, slice.id, "PLAN");
|
|
99
|
+
if (!planPath || !existsSync(planPath)) continue;
|
|
100
|
+
try {
|
|
101
|
+
const plan = readFileSync(planPath, "utf-8");
|
|
102
|
+
// parsePlan reads the authoritative task checkboxes (the flat-phase
|
|
103
|
+
// <tasks> block / ## Tasks section), so a stray task-style checkbox
|
|
104
|
+
// line elsewhere in PLAN.md (e.g. a Must-Haves or Verification bullet
|
|
105
|
+
// above <tasks>) can no longer hide real drift or fake a divergence.
|
|
106
|
+
const taskDoneById = new Map(parsePlan(plan).tasks.map((entry) => [entry.id, entry.done]));
|
|
107
|
+
for (const task of getSliceTasks(milestoneId, slice.id)) {
|
|
108
|
+
const checkboxDone = taskDoneById.get(task.id);
|
|
109
|
+
if (checkboxDone === undefined) continue;
|
|
110
|
+
reportCheckboxDbStatusDivergence(
|
|
111
|
+
issues,
|
|
112
|
+
basePath,
|
|
113
|
+
planPath,
|
|
114
|
+
"task",
|
|
115
|
+
`${milestoneId}/${slice.id}/${task.id}`,
|
|
116
|
+
task.status,
|
|
117
|
+
checkboxDone,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
} catch {
|
|
121
|
+
// Non-fatal — checkbox drift diagnostics must never block doctor.
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function isClearedByMilestoneShellProjectionFlush(
|
|
128
|
+
basePath: string,
|
|
129
|
+
issue: DoctorIssue,
|
|
130
|
+
reRenderedMilestoneIds: Set<string>,
|
|
131
|
+
): boolean {
|
|
132
|
+
if (issue.code !== "checkbox_db_status_divergence") return false;
|
|
133
|
+
if (issue.scope !== "slice") return false;
|
|
134
|
+
|
|
135
|
+
const milestoneId = issue.unitId.split("/")[0] ?? "";
|
|
136
|
+
if (!reRenderedMilestoneIds.has(milestoneId)) return false;
|
|
137
|
+
|
|
138
|
+
const roadmapPath = resolveMilestoneFile(basePath, milestoneId, "ROADMAP");
|
|
139
|
+
if (!roadmapPath || !issue.file) return false;
|
|
140
|
+
|
|
141
|
+
return issue.file === relativeFile(basePath, roadmapPath);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function artifactExistsOnDisk(basePath: string, artifactPath: string): boolean {
|
|
145
|
+
if (isAbsolute(artifactPath)) return existsSync(artifactPath);
|
|
146
|
+
return [
|
|
147
|
+
join(gsdProjectionRoot(basePath), artifactPath),
|
|
148
|
+
join(gsdRoot(basePath), artifactPath),
|
|
149
|
+
].some((candidate) => existsSync(candidate));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function artifactUnitId(row: { milestone_id: string | null; slice_id: string | null; task_id: string | null }): string {
|
|
153
|
+
if (!row.milestone_id) return "project";
|
|
154
|
+
if (row.slice_id && row.task_id) return `${row.milestone_id}/${row.slice_id}/${row.task_id}`;
|
|
155
|
+
if (row.slice_id) return `${row.milestone_id}/${row.slice_id}`;
|
|
156
|
+
return row.milestone_id;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function artifactScope(row: { milestone_id: string | null; slice_id: string | null; task_id: string | null }): DoctorIssue["scope"] {
|
|
160
|
+
if (row.task_id) return "task";
|
|
161
|
+
if (row.slice_id) return "slice";
|
|
162
|
+
if (row.milestone_id) return "milestone";
|
|
163
|
+
return "project";
|
|
164
|
+
}
|
|
12
165
|
|
|
13
166
|
export async function checkEngineHealth(
|
|
14
167
|
basePath: string,
|
|
15
168
|
issues: DoctorIssue[],
|
|
16
169
|
fixesApplied: string[],
|
|
170
|
+
options?: { repair?: boolean },
|
|
17
171
|
): Promise<void> {
|
|
18
172
|
const dbPath = resolveGsdPathContract(basePath).projectDb;
|
|
19
173
|
|
|
@@ -34,6 +188,32 @@ export async function checkEngineHealth(
|
|
|
34
188
|
if (isDbAvailable()) {
|
|
35
189
|
const adapter = _getAdapter()!;
|
|
36
190
|
|
|
191
|
+
try {
|
|
192
|
+
if (isMemoriesFtsAvailable(adapter)) {
|
|
193
|
+
const runtimeKv = adapter
|
|
194
|
+
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='runtime_kv'")
|
|
195
|
+
.get();
|
|
196
|
+
const marker = runtimeKv
|
|
197
|
+
? adapter.prepare(
|
|
198
|
+
"SELECT 1 as present FROM runtime_kv WHERE scope = 'global' AND scope_id = '' AND key = :key",
|
|
199
|
+
).get({ ":key": MEMORIES_FTS_REBUILT_KEY })
|
|
200
|
+
: undefined;
|
|
201
|
+
if (!marker) {
|
|
202
|
+
issues.push({
|
|
203
|
+
severity: "warning",
|
|
204
|
+
code: "memories_fts_rebuild_missing",
|
|
205
|
+
scope: "project",
|
|
206
|
+
unitId: "project",
|
|
207
|
+
message: `Memory full-text index exists but runtime_kv has no ${MEMORIES_FTS_REBUILT_KEY} marker. The index may be stale or incomplete, so memory search can silently degrade to the LIKE fallback.`,
|
|
208
|
+
file: ".gsd/gsd.db",
|
|
209
|
+
fixable: false,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
} catch {
|
|
214
|
+
// Non-fatal — memory FTS health check failed
|
|
215
|
+
}
|
|
216
|
+
|
|
37
217
|
// a. Orphaned tasks (task.slice_id points to non-existent slice)
|
|
38
218
|
try {
|
|
39
219
|
const orphanedTasks = adapter
|
|
@@ -196,7 +376,63 @@ export async function checkEngineHealth(
|
|
|
196
376
|
// Non-fatal — completed-milestone reopen check failed
|
|
197
377
|
}
|
|
198
378
|
|
|
199
|
-
// f.
|
|
379
|
+
// f. Artifact rows reference files that no longer exist on disk.
|
|
380
|
+
const missingUserContentArtifacts: Array<{ path: string; artifactType: string }> = [];
|
|
381
|
+
try {
|
|
382
|
+
const artifactRows = adapter
|
|
383
|
+
.prepare(
|
|
384
|
+
`SELECT path, artifact_type, milestone_id, slice_id, task_id
|
|
385
|
+
FROM artifacts
|
|
386
|
+
WHERE path != ''
|
|
387
|
+
ORDER BY path`,
|
|
388
|
+
)
|
|
389
|
+
.all() as Array<{
|
|
390
|
+
path: string;
|
|
391
|
+
artifact_type: string;
|
|
392
|
+
milestone_id: string | null;
|
|
393
|
+
slice_id: string | null;
|
|
394
|
+
task_id: string | null;
|
|
395
|
+
}>;
|
|
396
|
+
|
|
397
|
+
for (const row of artifactRows) {
|
|
398
|
+
if (artifactExistsOnDisk(basePath, row.path)) continue;
|
|
399
|
+
const unitId = artifactUnitId(row);
|
|
400
|
+
if (isUserAuthoredArtifactType(row.artifact_type)) {
|
|
401
|
+
const artifactType = normalizedArtifactType(row.artifact_type);
|
|
402
|
+
missingUserContentArtifacts.push({ path: row.path, artifactType });
|
|
403
|
+
issues.push({
|
|
404
|
+
severity: "warning",
|
|
405
|
+
code: "artifact_user_content_missing",
|
|
406
|
+
scope: artifactScope(row),
|
|
407
|
+
unitId,
|
|
408
|
+
message: userContentMissingMessage(row.path, artifactType),
|
|
409
|
+
file: row.path,
|
|
410
|
+
fixable: false,
|
|
411
|
+
});
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
issues.push({
|
|
415
|
+
severity: "error",
|
|
416
|
+
code: "artifact_file_missing",
|
|
417
|
+
scope: artifactScope(row),
|
|
418
|
+
unitId,
|
|
419
|
+
message: `Artifact ${row.path} is recorded in the database as ${row.artifact_type || "UNKNOWN"} but no matching file exists on disk`,
|
|
420
|
+
file: row.path,
|
|
421
|
+
fixable: false,
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
} catch {
|
|
425
|
+
// Non-fatal — artifact file existence check failed
|
|
426
|
+
}
|
|
427
|
+
if (options?.repair) {
|
|
428
|
+
for (const artifact of missingUserContentArtifacts) {
|
|
429
|
+
fixesApplied.push(
|
|
430
|
+
`skipped user-authored ${artifact.artifactType} artifact ${artifact.path} (content cannot be regenerated from the database)`,
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// g. Completion artifacts disagree with open DB hierarchy rows.
|
|
200
436
|
try {
|
|
201
437
|
const rows = adapter
|
|
202
438
|
.prepare(
|
|
@@ -225,6 +461,7 @@ export async function checkEngineHealth(
|
|
|
225
461
|
|
|
226
462
|
const seen = new Set<string>();
|
|
227
463
|
for (const row of rows) {
|
|
464
|
+
if (!artifactExistsOnDisk(basePath, row.path)) continue;
|
|
228
465
|
const reopenAt = latestExplicitReopenAt(basePath, row.milestone_id);
|
|
229
466
|
if (!isAfter(row.imported_at, reopenAt)) continue;
|
|
230
467
|
const isSliceSummary = row.slice_id && !row.task_id && row.slice_status && !["complete", "done", "skipped", "closed"].includes(row.slice_status);
|
|
@@ -256,9 +493,24 @@ export async function checkEngineHealth(
|
|
|
256
493
|
// Non-fatal — DB constraint checks failed entirely
|
|
257
494
|
}
|
|
258
495
|
|
|
496
|
+
// Checkbox-vs-DB divergence detection runs before projection drift auto-fix
|
|
497
|
+
// so stale re-renders cannot overwrite manually edited markdown first. Runs
|
|
498
|
+
// inside its own try/catch: getAllMilestones / getMilestoneSlices /
|
|
499
|
+
// getSliceTasks issue prepared queries that can throw on a corrupt or locked
|
|
500
|
+
// DB, and like every other DB-touching check here this diagnostic must never
|
|
501
|
+
// block doctor.
|
|
502
|
+
try {
|
|
503
|
+
if (isDbAvailable()) {
|
|
504
|
+
checkProjectionCheckboxDbStatus(basePath, getAllMilestones().map((milestone) => milestone.id), issues);
|
|
505
|
+
}
|
|
506
|
+
} catch {
|
|
507
|
+
// Non-fatal: checkbox-vs-DB divergence check must never block doctor
|
|
508
|
+
}
|
|
509
|
+
|
|
259
510
|
// ── Projection drift detection ──────────────────────────────────────────
|
|
260
511
|
// If the DB is available, check whether markdown projections are stale
|
|
261
512
|
// relative to the event log and re-render them.
|
|
513
|
+
const reRenderedMilestoneIds: string[] = [];
|
|
262
514
|
try {
|
|
263
515
|
if (isDbAvailable()) {
|
|
264
516
|
const eventLogPath = workflowEventLogPath(basePath);
|
|
@@ -273,6 +525,7 @@ export async function checkEngineHealth(
|
|
|
273
525
|
try {
|
|
274
526
|
await flushWorkflowProjections(basePath, { milestoneId: milestone.id });
|
|
275
527
|
fixesApplied.push(`re-rendered missing projections for ${milestone.id}`);
|
|
528
|
+
reRenderedMilestoneIds.push(milestone.id);
|
|
276
529
|
} catch {
|
|
277
530
|
// Non-fatal — projection re-render failed
|
|
278
531
|
}
|
|
@@ -283,6 +536,7 @@ export async function checkEngineHealth(
|
|
|
283
536
|
try {
|
|
284
537
|
await flushWorkflowProjections(basePath, { milestoneId: milestone.id });
|
|
285
538
|
fixesApplied.push(`re-rendered stale projections for ${milestone.id}`);
|
|
539
|
+
reRenderedMilestoneIds.push(milestone.id);
|
|
286
540
|
} catch {
|
|
287
541
|
// Non-fatal — projection re-render failed
|
|
288
542
|
}
|
|
@@ -293,4 +547,20 @@ export async function checkEngineHealth(
|
|
|
293
547
|
} catch {
|
|
294
548
|
// Non-fatal — projection drift check must never block doctor
|
|
295
549
|
}
|
|
550
|
+
|
|
551
|
+
if (reRenderedMilestoneIds.length > 0) {
|
|
552
|
+
const reRendered = new Set(reRenderedMilestoneIds);
|
|
553
|
+
for (let i = issues.length - 1; i >= 0; i--) {
|
|
554
|
+
const issue = issues[i]!;
|
|
555
|
+
// flushWorkflowProjections re-renders milestone shell projections (not
|
|
556
|
+
// slice PLAN.md files), so only clear stale ROADMAP checkbox diagnostics.
|
|
557
|
+
if (isClearedByMilestoneShellProjectionFlush(basePath, issue, reRendered)) {
|
|
558
|
+
issues.splice(i, 1);
|
|
559
|
+
continue;
|
|
560
|
+
}
|
|
561
|
+
if (issue.code === "artifact_file_missing" && issue.file && artifactExistsOnDisk(basePath, issue.file)) {
|
|
562
|
+
issues.splice(i, 1);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
296
566
|
}
|