@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
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
|
|
13
13
|
import { execFileSync } from "node:child_process";
|
|
14
14
|
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
15
|
+
import type { Dirent } from "node:fs";
|
|
15
16
|
import { isAbsolute, join, normalize, relative, resolve, sep } from "node:path";
|
|
16
17
|
import { gsdRoot } from "./paths.js";
|
|
17
18
|
import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
|
|
18
19
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
19
20
|
import { logWarning } from "./workflow-logger.js";
|
|
20
|
-
import { createRepositoryRegistryFromPreferences } from "./repository-registry.js";
|
|
21
|
+
import { createRepositoryRegistryFromPreferences, defaultRepositoryTargets } from "./repository-registry.js";
|
|
21
22
|
import { isGsdGitignored } from "./gitignore.js";
|
|
22
23
|
|
|
23
24
|
|
|
@@ -360,6 +361,7 @@ export interface PreMergeCheckResult {
|
|
|
360
361
|
*/
|
|
361
362
|
export const RUNTIME_EXCLUSION_PATHS: readonly string[] = [
|
|
362
363
|
".gsd-worktrees/",
|
|
364
|
+
".gsd-backups/**",
|
|
363
365
|
".gsd/activity/",
|
|
364
366
|
".gsd/audit/",
|
|
365
367
|
".gsd/forensics/",
|
|
@@ -1264,19 +1266,80 @@ export function handleTurnGitActionError(action: TurnGitActionMode, err: unknown
|
|
|
1264
1266
|
};
|
|
1265
1267
|
}
|
|
1266
1268
|
|
|
1269
|
+
export function isRepositoryDirty(repoRoot: string): boolean {
|
|
1270
|
+
try {
|
|
1271
|
+
return runGit(repoRoot, ["status", "--porcelain"]).length > 0;
|
|
1272
|
+
} catch {
|
|
1273
|
+
// Fallback preserves legacy behavior if explicit status probing fails.
|
|
1274
|
+
return nativeHasChanges(repoRoot);
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1267
1278
|
function collectRepositoryDirtyStatus(basePath: string): Record<string, boolean> {
|
|
1268
1279
|
const preferences = loadEffectiveGSDPreferences(basePath)?.preferences;
|
|
1269
1280
|
const registry = createRepositoryRegistryFromPreferences(basePath, preferences);
|
|
1270
1281
|
const dirtyByRepository: Record<string, boolean> = {};
|
|
1282
|
+
const registeredRoots = new Set(registry.repositories.map((repo) => resolve(repo.root)));
|
|
1271
1283
|
for (const repo of registry.repositories) {
|
|
1284
|
+
dirtyByRepository[repo.id] = isRepositoryDirty(repo.root);
|
|
1285
|
+
}
|
|
1286
|
+
for (const repoRoot of findUndeclaredNestedGitRepositories(registry.projectRoot, registeredRoots)) {
|
|
1287
|
+
const dirty = isRepositoryDirty(repoRoot);
|
|
1288
|
+
if (!dirty) continue;
|
|
1289
|
+
|
|
1290
|
+
const relPath = relative(registry.projectRoot, repoRoot).split(sep).join("/") || repoRoot;
|
|
1291
|
+
const label = `${relPath} (undeclared)`;
|
|
1292
|
+
dirtyByRepository[label] = true;
|
|
1293
|
+
logWarning(
|
|
1294
|
+
"engine",
|
|
1295
|
+
`undeclared dirty nested git repo ${relPath}; declare it under workspace.repositories or commit manually`,
|
|
1296
|
+
{ file: "git-service.ts" },
|
|
1297
|
+
);
|
|
1298
|
+
}
|
|
1299
|
+
return dirtyByRepository;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
const UNDECLARED_NESTED_REPO_SCAN_MAX_DEPTH = 4;
|
|
1303
|
+
const UNDECLARED_NESTED_REPO_SKIP_DIRS = new Set([
|
|
1304
|
+
".git",
|
|
1305
|
+
".gsd",
|
|
1306
|
+
".gsd-worktrees",
|
|
1307
|
+
"node_modules",
|
|
1308
|
+
"dist",
|
|
1309
|
+
"dist-test",
|
|
1310
|
+
]);
|
|
1311
|
+
|
|
1312
|
+
function findUndeclaredNestedGitRepositories(projectRoot: string, registeredRoots: ReadonlySet<string>): string[] {
|
|
1313
|
+
const found: string[] = [];
|
|
1314
|
+
|
|
1315
|
+
function visit(dir: string, depth: number): void {
|
|
1316
|
+
if (depth >= UNDECLARED_NESTED_REPO_SCAN_MAX_DEPTH) return;
|
|
1317
|
+
|
|
1318
|
+
let entries: Dirent[];
|
|
1272
1319
|
try {
|
|
1273
|
-
|
|
1320
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
1274
1321
|
} catch {
|
|
1275
|
-
|
|
1276
|
-
|
|
1322
|
+
return;
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
for (const entry of entries) {
|
|
1326
|
+
if (!entry.isDirectory()) continue;
|
|
1327
|
+
if (UNDECLARED_NESTED_REPO_SKIP_DIRS.has(entry.name)) continue;
|
|
1328
|
+
|
|
1329
|
+
const child = join(dir, entry.name);
|
|
1330
|
+
const childRoot = resolve(child);
|
|
1331
|
+
const hasGitDir = existsSync(join(child, ".git"));
|
|
1332
|
+
const isRegistered = registeredRoots.has(childRoot);
|
|
1333
|
+
if (hasGitDir && !isRegistered) {
|
|
1334
|
+
found.push(childRoot);
|
|
1335
|
+
continue;
|
|
1336
|
+
}
|
|
1337
|
+
visit(child, depth + 1);
|
|
1277
1338
|
}
|
|
1278
1339
|
}
|
|
1279
|
-
|
|
1340
|
+
|
|
1341
|
+
visit(projectRoot, 0);
|
|
1342
|
+
return found;
|
|
1280
1343
|
}
|
|
1281
1344
|
|
|
1282
1345
|
function runPerRepositoryCommitAction(args: {
|
|
@@ -1293,7 +1356,7 @@ function runPerRepositoryCommitAction(args: {
|
|
|
1293
1356
|
} {
|
|
1294
1357
|
const preferences = loadEffectiveGSDPreferences(args.basePath)?.preferences;
|
|
1295
1358
|
const registry = createRepositoryRegistryFromPreferences(args.basePath, preferences);
|
|
1296
|
-
const repoIds = args.targetRepositories?.length ? args.targetRepositories :
|
|
1359
|
+
const repoIds = args.targetRepositories?.length ? args.targetRepositories : defaultRepositoryTargets(registry);
|
|
1297
1360
|
const gitPrefs = preferences?.git ?? {};
|
|
1298
1361
|
const commitMessages: Record<string, string> = {};
|
|
1299
1362
|
const commitErrors: Record<string, string> = {};
|
|
@@ -1381,9 +1444,7 @@ export function runTurnGitAction(args: {
|
|
|
1381
1444
|
};
|
|
1382
1445
|
}
|
|
1383
1446
|
|
|
1384
|
-
const primaryMessage =
|
|
1385
|
-
repoCommitResult.commitMessages[args.targetRepositories?.[0] ?? "project"]
|
|
1386
|
-
?? Object.values(repoCommitResult.commitMessages)[0];
|
|
1447
|
+
const primaryMessage = Object.values(repoCommitResult.commitMessages)[0];
|
|
1387
1448
|
return {
|
|
1388
1449
|
action: args.action,
|
|
1389
1450
|
status: "ok",
|
|
@@ -24,8 +24,9 @@ import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
|
|
|
24
24
|
* With external state (symlink), these are a no-op in most cases,
|
|
25
25
|
* but retained for backwards compatibility during migration.
|
|
26
26
|
*/
|
|
27
|
-
const GSD_RUNTIME_PATTERNS = [
|
|
27
|
+
export const GSD_RUNTIME_PATTERNS = [
|
|
28
28
|
".gsd-worktrees/",
|
|
29
|
+
".gsd-backups/",
|
|
29
30
|
".gsd/activity/",
|
|
30
31
|
".gsd/audit/",
|
|
31
32
|
".gsd/forensics/",
|
|
@@ -51,6 +52,8 @@ const BASELINE_PATTERNS = [
|
|
|
51
52
|
".gsd",
|
|
52
53
|
// Worktree container sibling — NOT covered by the ".gsd" pattern above.
|
|
53
54
|
".gsd-worktrees/",
|
|
55
|
+
// Flat-phase migration snapshots — NOT covered by the ".gsd" pattern above.
|
|
56
|
+
".gsd-backups/",
|
|
54
57
|
".gsd-id",
|
|
55
58
|
".mcp.json",
|
|
56
59
|
".bg-shell/",
|
|
@@ -209,6 +209,8 @@ const DOCTOR_FIX_HINTS: Partial<Record<DoctorIssueCode, string>> = {
|
|
|
209
209
|
state_file_stale: "Run `/gsd doctor fix` to rebuild the projection from the database.",
|
|
210
210
|
state_file_missing: "Run `/gsd doctor fix` to rebuild the projection from the database.",
|
|
211
211
|
projection_drift: "Run `/gsd doctor fix` to rebuild markdown projections from the database (DB is the source of truth).",
|
|
212
|
+
artifact_user_content_missing:
|
|
213
|
+
"Doctor cannot recreate user-authored content from the database. Re-run `/gsd discuss` for CONTEXT artifacts or `/gsd auto` for RESEARCH artifacts in that milestone.",
|
|
212
214
|
uat_retry_exhausted: "Review the failing UAT criteria via `/gsd status`, fix the issue, then re-run `/gsd auto`.",
|
|
213
215
|
};
|
|
214
216
|
|
|
@@ -360,24 +360,31 @@ function capExistingMilestonesContext(
|
|
|
360
360
|
if (fullContext.length <= cap) return fullContext;
|
|
361
361
|
|
|
362
362
|
const notice = `[Existing milestones context truncated to ${cap} chars. Read source paths in this prompt or the corresponding .gsd artifacts for full details.]`;
|
|
363
|
-
const
|
|
364
|
-
const selected: string[] = [];
|
|
363
|
+
const noticeSuffix = `${QUEUE_CONTEXT_SECTION_SEPARATOR}${notice}`;
|
|
365
364
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
365
|
+
const selected: string[] = [];
|
|
366
|
+
for (const section of sections) {
|
|
367
|
+
const candidate = [...selected, section].join(QUEUE_CONTEXT_SECTION_SEPARATOR) + noticeSuffix;
|
|
368
|
+
if (candidate.length <= cap) {
|
|
369
|
+
selected.push(section);
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
break;
|
|
373
|
+
}
|
|
373
374
|
|
|
374
|
-
|
|
375
|
+
if (selected.length === sections.length) {
|
|
376
|
+
return selected.join(QUEUE_CONTEXT_SECTION_SEPARATOR) + noticeSuffix;
|
|
375
377
|
}
|
|
376
378
|
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
+
const compactTail = sections.slice(selected.length).map(compactSectionForQueueBudget);
|
|
380
|
+
const hybrid = [...selected, ...compactTail].join(QUEUE_CONTEXT_SECTION_SEPARATOR) + noticeSuffix;
|
|
381
|
+
if (hybrid.length <= cap) return hybrid;
|
|
382
|
+
|
|
383
|
+
const compact = sections.map(compactSectionForQueueBudget);
|
|
384
|
+
const compactContext = compact.join(QUEUE_CONTEXT_SECTION_SEPARATOR) + noticeSuffix;
|
|
385
|
+
if (compactContext.length <= cap) return compactContext;
|
|
379
386
|
|
|
380
|
-
return `${
|
|
387
|
+
return `${compactContext.slice(0, Math.max(0, cap - notice.length - 2)).trimEnd()}\n\n${notice}`;
|
|
381
388
|
}
|
|
382
389
|
|
|
383
390
|
function compactSectionForQueueBudget(section: string): string {
|
|
@@ -42,7 +42,7 @@ import { gsdHome } from "./gsd-home.js";
|
|
|
42
42
|
import {
|
|
43
43
|
gsdRoot, milestonesDir, legacyMilestonesDir, resolveMilestoneFile,
|
|
44
44
|
resolveSliceFile, resolveSlicePath, resolveGsdRootFile, relGsdRootFile,
|
|
45
|
-
relMilestoneFile, relSliceFile,
|
|
45
|
+
relMilestoneFile, relSliceFile, clearPathCache,
|
|
46
46
|
} from "./paths.js";
|
|
47
47
|
import { join } from "node:path";
|
|
48
48
|
import { readFileSync, existsSync, mkdirSync, readdirSync, rmSync } from "node:fs";
|
|
@@ -101,6 +101,7 @@ import {
|
|
|
101
101
|
formatPriorContextBrief,
|
|
102
102
|
} from "./preparation.js";
|
|
103
103
|
import { verifyExpectedArtifact } from "./auto-recovery.js";
|
|
104
|
+
import { countPlanMilestoneRoadmapSlices } from "./artifact-verification.js";
|
|
104
105
|
import type { MilestoneScope } from "./workspace.js";
|
|
105
106
|
import { clearPendingGate, extractDepthVerificationMilestoneId, getPendingGate } from "./bootstrap/write-gate.js";
|
|
106
107
|
import {
|
|
@@ -164,7 +165,7 @@ export const _scheduleAutoStartAfterIdleForTest = scheduleAutoStartAfterIdle;
|
|
|
164
165
|
// These thin wrappers accept a MilestoneScope so callers that already hold a
|
|
165
166
|
// pinned scope never have to re-derive (basePath, milestoneId) separately.
|
|
166
167
|
// The underlying implementations in auto-recovery.ts / auto-artifact-paths.ts /
|
|
167
|
-
// state.ts
|
|
168
|
+
// state.ts remain the default for non-scope-specific units.
|
|
168
169
|
|
|
169
170
|
/**
|
|
170
171
|
* Scope-based overload of verifyExpectedArtifact.
|
|
@@ -176,9 +177,47 @@ export function verifyExpectedArtifactForScope(
|
|
|
176
177
|
unitType: string,
|
|
177
178
|
unitId: string,
|
|
178
179
|
): boolean {
|
|
180
|
+
if (
|
|
181
|
+
unitId === scope.milestoneId &&
|
|
182
|
+
(unitType === "discuss-milestone" || unitType === "plan-milestone")
|
|
183
|
+
) {
|
|
184
|
+
// Layout-aware scope paths use resolveMilestoneFile; clear stale dir listings
|
|
185
|
+
// primed before discuss/plan wrote CONTEXT.md or ROADMAP.md (see checkAutoStartAfterDiscuss).
|
|
186
|
+
clearPathCache();
|
|
187
|
+
}
|
|
188
|
+
if (
|
|
189
|
+
unitId === scope.milestoneId &&
|
|
190
|
+
unitType === "discuss-milestone"
|
|
191
|
+
) {
|
|
192
|
+
const path = resolveExpectedArtifactPathForScope(scope, unitType, unitId);
|
|
193
|
+
return path ? existsSync(path) : false;
|
|
194
|
+
}
|
|
195
|
+
if (unitId === scope.milestoneId && unitType === "plan-milestone") {
|
|
196
|
+
const path = resolveExpectedArtifactPathForScope(scope, unitType, unitId);
|
|
197
|
+
return verifyScopedPlanMilestoneArtifact(path, unitType, unitId);
|
|
198
|
+
}
|
|
179
199
|
return verifyExpectedArtifact(unitType, unitId, scope.workspace.projectRoot);
|
|
180
200
|
}
|
|
181
201
|
|
|
202
|
+
function verifyScopedPlanMilestoneArtifact(
|
|
203
|
+
path: string | null,
|
|
204
|
+
unitType: string,
|
|
205
|
+
unitId: string,
|
|
206
|
+
): boolean {
|
|
207
|
+
if (!path || !existsSync(path)) return false;
|
|
208
|
+
try {
|
|
209
|
+
const roadmapContent = readFileSync(path, "utf-8");
|
|
210
|
+
if (countPlanMilestoneRoadmapSlices(roadmapContent) === 0) {
|
|
211
|
+
logWarning("recovery", `verify-fail ${unitType} ${unitId}: roadmap has zero slices at ${path}`);
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
return true;
|
|
215
|
+
} catch (err) {
|
|
216
|
+
logWarning("recovery", `plan-milestone roadmap verification failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
182
221
|
/**
|
|
183
222
|
* Scope-based overload of resolveExpectedArtifactPath.
|
|
184
223
|
* Returns the canonical absolute path (or null) using the scope's projectRoot.
|
|
@@ -188,6 +227,10 @@ export function resolveExpectedArtifactPathForScope(
|
|
|
188
227
|
unitType: string,
|
|
189
228
|
unitId: string,
|
|
190
229
|
): string | null {
|
|
230
|
+
if (unitId === scope.milestoneId) {
|
|
231
|
+
if (unitType === "discuss-milestone") return scope.contextFile();
|
|
232
|
+
if (unitType === "plan-milestone") return scope.roadmapFile();
|
|
233
|
+
}
|
|
191
234
|
return resolveExpectedArtifactPath(unitType, unitId, scope.workspace.projectRoot);
|
|
192
235
|
}
|
|
193
236
|
|
|
@@ -62,6 +62,26 @@ export function saveJsonFile<T>(filePath: string, data: T): void {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Save a JSON file atomically using compact serialization.
|
|
67
|
+
*
|
|
68
|
+
* Intended for machine-only ledgers where pretty-printing has no consumer.
|
|
69
|
+
* Keeps the same write-tmp-rename safety and non-fatal error behavior as
|
|
70
|
+
* saveJsonFile.
|
|
71
|
+
*/
|
|
72
|
+
export function saveJsonFileCompact<T>(filePath: string, data: T): void {
|
|
73
|
+
try {
|
|
74
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
75
|
+
// Use randomized tmp suffix to prevent concurrent-write data loss
|
|
76
|
+
const tmp = `${filePath}.tmp.${randomBytes(4).toString("hex")}`;
|
|
77
|
+
writeFileSync(tmp, JSON.stringify(data) + "\n", "utf-8");
|
|
78
|
+
renameSync(tmp, filePath);
|
|
79
|
+
// No cleanup needed — renameSync atomically removes tmp on success
|
|
80
|
+
} catch {
|
|
81
|
+
// Non-fatal — don't let persistence failures break operation
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
65
85
|
/**
|
|
66
86
|
* Write a JSON file atomically (write to .tmp, then rename).
|
|
67
87
|
* Creates parent directories as needed. Non-fatal on error.
|
|
@@ -43,6 +43,7 @@ export const PROVIDER_REGISTRY: ProviderInfo[] = [
|
|
|
43
43
|
// must be in the canonical registry so all consumers see the same catalog.
|
|
44
44
|
// See: https://github.com/open-gsd/gsd-pi/issues/4541
|
|
45
45
|
{ id: "claude-code", label: "Claude Code CLI", category: "llm", authMode: "externalCli" },
|
|
46
|
+
{ id: "cursor-agent", label: "Cursor Agent", category: "llm", envVar: "CURSOR_API_KEY", authMode: "externalCli" },
|
|
46
47
|
{ id: "openai", label: "OpenAI", category: "llm", envVar: "OPENAI_API_KEY", prefixes: ["sk-"], dashboardUrl: "platform.openai.com/api-keys" },
|
|
47
48
|
{ id: "github-copilot", label: "GitHub Copilot", category: "llm", envVar: "GITHUB_TOKEN", authMode: "browserOAuth" },
|
|
48
49
|
{ id: "openai-codex", label: "ChatGPT Plus/Pro (Codex)",category: "llm", authMode: "browserOAuth" },
|
|
@@ -35,8 +35,8 @@ interface SynthesizedRow {
|
|
|
35
35
|
* - Idempotent (per-row): each migrated memory carries
|
|
36
36
|
* `structured_fields.sourceKnowledgeId = "<P|L>NNN"`. Rows whose ID is
|
|
37
37
|
* already present in the memory store are skipped.
|
|
38
|
-
* - Best-effort: never throws.
|
|
39
|
-
* backfill cannot block
|
|
38
|
+
* - Best-effort: never throws. Failed memory inserts are logged and skipped;
|
|
39
|
+
* setup/read failures log and return 0 so backfill cannot block startup.
|
|
40
40
|
* - Rules (K###) are intentionally skipped — they remain manually maintained
|
|
41
41
|
* in `KNOWLEDGE.md` per ADR-013.
|
|
42
42
|
*
|
|
@@ -69,14 +69,20 @@ export function backfillKnowledgeToMemories(basePath: string): number {
|
|
|
69
69
|
const matchPattern = `%"sourceKnowledgeId":"${synth.id}"%`;
|
|
70
70
|
if (checkExisting.get({ ":pattern": matchPattern })) continue;
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
try {
|
|
73
|
+
const id = createMemory({
|
|
74
|
+
category: synth.category,
|
|
75
|
+
content: synth.content,
|
|
76
|
+
scope: synth.scope,
|
|
77
|
+
confidence: 0.85,
|
|
78
|
+
structuredFields: synth.structuredFields,
|
|
79
|
+
});
|
|
80
|
+
if (id) written += 1;
|
|
81
|
+
} catch (rowErr) {
|
|
82
|
+
const message = rowErr instanceof Error ? rowErr.message : String(rowErr);
|
|
83
|
+
logWarning("knowledge-backfill", `KNOWLEDGE.md -> memories backfill skipped ${synth.id}: ${message}`);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
80
86
|
}
|
|
81
87
|
|
|
82
88
|
return written;
|
|
@@ -47,8 +47,9 @@ export function dbPath(basePath: string): string {
|
|
|
47
47
|
* Used by the renderer to derive the phase number from the DB's milestone_id.
|
|
48
48
|
*/
|
|
49
49
|
export function milestoneIdToPhaseNum(milestoneId: string): number {
|
|
50
|
-
// No $ anchor: accepts bare (M012)
|
|
50
|
+
// No $ anchor: accepts bare (M012), team-suffixed (M012-abc123), and legacy numeric IDs.
|
|
51
51
|
const m = milestoneId.match(/^M0*(\d+)/i);
|
|
52
|
+
if (!m && /^\d+$/.test(milestoneId)) return Number.parseInt(milestoneId, 10);
|
|
52
53
|
return m ? Number.parseInt(m[1]!, 10) : 1;
|
|
53
54
|
}
|
|
54
55
|
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
getSliceScopedArtifacts,
|
|
21
21
|
getMilestoneSlices,
|
|
22
22
|
getSliceTasks,
|
|
23
|
+
getTasksBySliceIds,
|
|
23
24
|
getTask,
|
|
24
25
|
getSlice,
|
|
25
26
|
insertArtifact,
|
|
@@ -136,6 +137,12 @@ function meaningfulSection(value: string | null | undefined): string {
|
|
|
136
137
|
return trimmed;
|
|
137
138
|
}
|
|
138
139
|
|
|
140
|
+
function renderGateFindings(gate: GateRow): string {
|
|
141
|
+
const findings = gate.findings.trim() || `- **Verdict:** ${gate.verdict}\n- **Rationale:** ${gate.rationale}`;
|
|
142
|
+
if (gate.verdict !== "flag") return findings;
|
|
143
|
+
return `> **Warning:** Verdict: flag - concerns recorded below\n\n${findings}`;
|
|
144
|
+
}
|
|
145
|
+
|
|
139
146
|
function pushIndented(lines: string[], value: string, indent = " "): void {
|
|
140
147
|
for (const line of value.split("\n")) {
|
|
141
148
|
lines.push(`${indent}${line}`);
|
|
@@ -356,7 +363,7 @@ function renderTaskPlanMarkdown(task: TaskRow, taskGates: GateRow[] = []): strin
|
|
|
356
363
|
if (gate && gate.verdict !== "omitted") {
|
|
357
364
|
lines.push(`## ${label}`);
|
|
358
365
|
lines.push("");
|
|
359
|
-
lines.push(
|
|
366
|
+
lines.push(renderGateFindings(gate));
|
|
360
367
|
lines.push("");
|
|
361
368
|
}
|
|
362
369
|
}
|
|
@@ -390,7 +397,7 @@ function renderSlicePlanMarkdown(slice: SliceRow, tasks: TaskRow[], gates: GateR
|
|
|
390
397
|
if (q3 && q3.verdict !== "omitted") {
|
|
391
398
|
lines.push("## Threat Surface");
|
|
392
399
|
lines.push("");
|
|
393
|
-
lines.push(
|
|
400
|
+
lines.push(renderGateFindings(q3));
|
|
394
401
|
lines.push("");
|
|
395
402
|
}
|
|
396
403
|
|
|
@@ -398,7 +405,7 @@ function renderSlicePlanMarkdown(slice: SliceRow, tasks: TaskRow[], gates: GateR
|
|
|
398
405
|
if (q4 && q4.verdict !== "omitted") {
|
|
399
406
|
lines.push("## Requirement Impact");
|
|
400
407
|
lines.push("");
|
|
401
|
-
lines.push(
|
|
408
|
+
lines.push(renderGateFindings(q4));
|
|
402
409
|
lines.push("");
|
|
403
410
|
}
|
|
404
411
|
|
|
@@ -632,16 +639,8 @@ export async function renderRoadmapCheckboxes(
|
|
|
632
639
|
basePath: string,
|
|
633
640
|
milestoneId: string,
|
|
634
641
|
): Promise<boolean> {
|
|
635
|
-
const
|
|
636
|
-
|
|
637
|
-
process.stderr.write(
|
|
638
|
-
`markdown-renderer: no slices found for milestone ${milestoneId}\n`,
|
|
639
|
-
);
|
|
640
|
-
return false;
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
await renderRoadmapFromDb(basePath, milestoneId);
|
|
644
|
-
return true;
|
|
642
|
+
const rendered = await renderRoadmapFromDb(basePath, milestoneId);
|
|
643
|
+
return !("skipped" in rendered);
|
|
645
644
|
}
|
|
646
645
|
|
|
647
646
|
/**
|
|
@@ -884,6 +883,17 @@ export async function renderAllFromDb(basePath: string): Promise<RenderAllResult
|
|
|
884
883
|
const result: RenderAllResult = { rendered: 0, skipped: 0, errors: [] };
|
|
885
884
|
const milestones = getAllMilestones();
|
|
886
885
|
|
|
886
|
+
// Pre-fetch slices once per milestone and batch-load all tasks in one query
|
|
887
|
+
// family, avoiding an N+1 (previously one task query per slice).
|
|
888
|
+
const slicesByMilestone = new Map<string, SliceRow[]>();
|
|
889
|
+
const slicePairs: Array<{ milestoneId: string; sliceId: string }> = [];
|
|
890
|
+
for (const milestone of milestones) {
|
|
891
|
+
const slices = getMilestoneSlices(milestone.id);
|
|
892
|
+
slicesByMilestone.set(milestone.id, slices);
|
|
893
|
+
for (const slice of slices) slicePairs.push({ milestoneId: milestone.id, sliceId: slice.id });
|
|
894
|
+
}
|
|
895
|
+
const tasksBySlice = getTasksBySliceIds(slicePairs);
|
|
896
|
+
|
|
887
897
|
for (const milestone of milestones) {
|
|
888
898
|
// Render roadmap checkboxes
|
|
889
899
|
try {
|
|
@@ -902,8 +912,8 @@ export async function renderAllFromDb(basePath: string): Promise<RenderAllResult
|
|
|
902
912
|
result.errors.push(`milestone artifacts ${milestone.id}: ${(err as Error).message}`);
|
|
903
913
|
}
|
|
904
914
|
|
|
905
|
-
// Iterate slices
|
|
906
|
-
const slices =
|
|
915
|
+
// Iterate slices (pre-fetched above)
|
|
916
|
+
const slices = slicesByMilestone.get(milestone.id) ?? [];
|
|
907
917
|
for (const slice of slices) {
|
|
908
918
|
// Preserve slice-scoped artifacts imported from disk, including real PLAN
|
|
909
919
|
// fallback content when task rows cannot regenerate it.
|
|
@@ -939,8 +949,8 @@ export async function renderAllFromDb(basePath: string): Promise<RenderAllResult
|
|
|
939
949
|
);
|
|
940
950
|
}
|
|
941
951
|
|
|
942
|
-
// Iterate tasks
|
|
943
|
-
const tasks =
|
|
952
|
+
// Iterate tasks (batched above)
|
|
953
|
+
const tasks = tasksBySlice.get(`${milestone.id}\0${slice.id}`) ?? [];
|
|
944
954
|
for (const task of tasks) {
|
|
945
955
|
try {
|
|
946
956
|
const ok = await renderTaskSummary(
|
|
@@ -49,8 +49,8 @@ type DecisionContentFields = Pick<DecisionRow, "decision" | "choice" | "rational
|
|
|
49
49
|
* decision is checked individually; only decisions whose id is already
|
|
50
50
|
* present in the memory store are skipped. A user-authored memory with
|
|
51
51
|
* their own `sourceDecisionId` does NOT abort the backfill.
|
|
52
|
-
* - Best-effort: never throws.
|
|
53
|
-
* backfill cannot block
|
|
52
|
+
* - Best-effort: never throws. Failed memory inserts are logged and skipped;
|
|
53
|
+
* setup/read failures log and return 0 so backfill cannot block startup.
|
|
54
54
|
* - Full migration (ADR-013 Stage 2a): both active and superseded rows are
|
|
55
55
|
* migrated. `structured_fields.superseded_by` preserves the supersedes
|
|
56
56
|
* chain so the DECISIONS.md projection regen can source from memories
|
|
@@ -146,24 +146,30 @@ export function backfillDecisionsToMemories(): number {
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
const content = synthesizeDecisionMemoryContent(row);
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
149
|
+
try {
|
|
150
|
+
const id = createMemory({
|
|
151
|
+
category: "architecture",
|
|
152
|
+
content,
|
|
153
|
+
scope: row.scope || "project",
|
|
154
|
+
confidence: 0.85,
|
|
155
|
+
structuredFields: {
|
|
156
|
+
sourceDecisionId: row.id,
|
|
157
|
+
when_context: row.when_context,
|
|
158
|
+
scope: row.scope,
|
|
159
|
+
decision: row.decision,
|
|
160
|
+
choice: row.choice,
|
|
161
|
+
rationale: row.rationale,
|
|
162
|
+
made_by: row.made_by,
|
|
163
|
+
revisable: row.revisable,
|
|
164
|
+
superseded_by: row.superseded_by,
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
if (id) written += 1;
|
|
168
|
+
} catch (rowErr) {
|
|
169
|
+
const message = rowErr instanceof Error ? rowErr.message : String(rowErr);
|
|
170
|
+
logWarning("memory-backfill", `decisions->memories backfill skipped ${row.id}: ${message}`);
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
167
173
|
}
|
|
168
174
|
|
|
169
175
|
if (healed > 0) {
|
|
@@ -19,7 +19,7 @@ import { openSync, closeSync, unlinkSync, statSync, writeFileSync } from "node:f
|
|
|
19
19
|
import type { ExtensionContext } from "@gsd/pi-coding-agent";
|
|
20
20
|
import { gsdRoot } from "./paths.js";
|
|
21
21
|
import { getAndClearSkills } from "./skill-telemetry.js";
|
|
22
|
-
import { loadJsonFile, loadJsonFileOrNull,
|
|
22
|
+
import { loadJsonFile, loadJsonFileOrNull, saveJsonFileCompact } from "./json-persistence.js";
|
|
23
23
|
import { parseUnitId } from "./unit-id.js";
|
|
24
24
|
import { buildAuditEnvelope, emitUokAuditEvent } from "./uok/audit.js";
|
|
25
25
|
import { isUnifiedAuditEnabled } from "./uok/audit-toggle.js";
|
|
@@ -873,7 +873,7 @@ export function pruneMetricsLedger(base: string, keepCount: number): number {
|
|
|
873
873
|
if (!disk || disk.units.length <= keepCount) return 0;
|
|
874
874
|
const removed = disk.units.length - keepCount;
|
|
875
875
|
disk.units = keepNewestUnits(disk.units, keepCount);
|
|
876
|
-
|
|
876
|
+
saveJsonFileCompact(metricsPath(base), disk);
|
|
877
877
|
// Keep the in-memory ledger in sync if it is loaded for this session.
|
|
878
878
|
if (ledger) {
|
|
879
879
|
ledger.units = keepNewestUnits(ledger.units, keepCount);
|
|
@@ -1041,7 +1041,7 @@ function saveLedger(base: string, data: MetricsLedger): void {
|
|
|
1041
1041
|
: dataUnits;
|
|
1042
1042
|
merged.sort(compareUnitsByTime);
|
|
1043
1043
|
data.units = keepNewestUnits(merged);
|
|
1044
|
-
|
|
1044
|
+
saveJsonFileCompact(path, data);
|
|
1045
1045
|
} finally {
|
|
1046
1046
|
releaseLock(lockPath);
|
|
1047
1047
|
}
|
|
@@ -1053,6 +1053,6 @@ function saveLedger(base: string, data: MetricsLedger): void {
|
|
|
1053
1053
|
// read-merge-write sequence without mutual exclusion.
|
|
1054
1054
|
logWarning("fs", "saveLedger: lock not acquired — falling back to direct write (no merge)");
|
|
1055
1055
|
data.units = keepNewestUnits(data.units);
|
|
1056
|
-
|
|
1056
|
+
saveJsonFileCompact(path, data);
|
|
1057
1057
|
}
|
|
1058
1058
|
}
|
|
@@ -118,6 +118,7 @@ export function migrateToExternalState(basePath: string): MigrationResult {
|
|
|
118
118
|
|
|
119
119
|
// Copy contents to external dir, skipping worktrees/
|
|
120
120
|
const entries = readdirSync(migratingPath, { withFileTypes: true });
|
|
121
|
+
const copyFailures: string[] = [];
|
|
121
122
|
for (const entry of entries) {
|
|
122
123
|
if (entry.name === "worktrees") continue; // worktrees stay local
|
|
123
124
|
|
|
@@ -130,10 +131,15 @@ export function migrateToExternalState(basePath: string): MigrationResult {
|
|
|
130
131
|
} else {
|
|
131
132
|
cpSync(src, dst, { force: true });
|
|
132
133
|
}
|
|
133
|
-
} catch {
|
|
134
|
-
|
|
134
|
+
} catch (copyErr) {
|
|
135
|
+
copyFailures.push(`${entry.name}: ${getErrorMessage(copyErr)}`);
|
|
135
136
|
}
|
|
136
137
|
}
|
|
138
|
+
if (copyFailures.length > 0) {
|
|
139
|
+
try { rmSync(localGsd, { force: true }); } catch { /* may not exist */ }
|
|
140
|
+
renameSync(migratingPath, localGsd);
|
|
141
|
+
return { migrated: false, error: `Migration copy failed: ${copyFailures.join("; ")}` };
|
|
142
|
+
}
|
|
137
143
|
|
|
138
144
|
// Create symlink .gsd -> external path
|
|
139
145
|
symlinkSync(externalPath, localGsd, "junction");
|
|
@@ -231,7 +237,7 @@ function isLocalGsdExternalStateJunction(basePath: string, localGsd: string): bo
|
|
|
231
237
|
* Recover from a failed migration (`.gsd.migrating` exists).
|
|
232
238
|
* Moves `.gsd.migrating` back to `.gsd` if `.gsd` doesn't exist, or removes an
|
|
233
239
|
* orphaned staging directory when `.gsd` is already a verified external state
|
|
234
|
-
* junction with intact current state.
|
|
240
|
+
* junction, or an intact real directory, with intact current state.
|
|
235
241
|
*/
|
|
236
242
|
export function recoverFailedMigration(basePath: string): boolean {
|
|
237
243
|
const localGsd = join(basePath, ".gsd");
|
|
@@ -239,8 +245,15 @@ export function recoverFailedMigration(basePath: string): boolean {
|
|
|
239
245
|
|
|
240
246
|
if (!existsSync(migratingPath)) return false;
|
|
241
247
|
if (existsSync(localGsd)) {
|
|
242
|
-
if (!isLocalGsdExternalStateJunction(basePath, localGsd)) return false;
|
|
243
248
|
if (!isCurrentGsdStateIntactForMigratingCleanup(basePath)) return false;
|
|
249
|
+
if (!isLocalGsdExternalStateJunction(basePath, localGsd)) {
|
|
250
|
+
try {
|
|
251
|
+
const stat = lstatSync(localGsd);
|
|
252
|
+
if (!stat.isDirectory()) return false;
|
|
253
|
+
} catch {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
244
257
|
try {
|
|
245
258
|
rmSync(migratingPath, { recursive: true, force: true });
|
|
246
259
|
return true;
|