@opengsd/gsd-pi 1.3.0-dev.65546769 → 1.3.0-dev.738160b9
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 +1 -1
- 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/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/claude-code-cli/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +11 -2
- package/dist/resources/extensions/google-cli/stream-adapter.js +82 -15
- package/dist/resources/extensions/gsd/artifact-verification.js +427 -0
- package/dist/resources/extensions/gsd/auto/orchestrator.js +12 -3
- 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 +34 -20
- package/dist/resources/extensions/gsd/auto-post-unit.js +1 -1
- package/dist/resources/extensions/gsd/auto-prompts.js +29 -14
- package/dist/resources/extensions/gsd/auto-recovery.js +9 -510
- package/dist/resources/extensions/gsd/auto-runtime-state.js +4 -5
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +3 -3
- package/dist/resources/extensions/gsd/auto-verification.js +5 -2
- package/dist/resources/extensions/gsd/auto.js +19 -10
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +103 -13
- package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +39 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +11 -5
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +41 -21
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -19
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +96 -10
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +1 -1
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +3 -1
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +1 -1
- package/dist/resources/extensions/gsd/commands-context.js +19 -1
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +17 -11
- package/dist/resources/extensions/gsd/commands-usage.js +1 -1
- package/dist/resources/extensions/gsd/commands-worktree.js +12 -10
- package/dist/resources/extensions/gsd/dashboard-overlay.js +32 -3
- package/dist/resources/extensions/gsd/db/engine.js +4 -1
- package/dist/resources/extensions/gsd/db/queries.js +60 -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/docs/preferences-reference.md +2 -2
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +192 -4
- package/dist/resources/extensions/gsd/doctor-providers.js +92 -8
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +3 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +53 -11
- package/dist/resources/extensions/gsd/flat-phase-migration.js +45 -0
- package/dist/resources/extensions/gsd/forensics.js +2 -32
- package/dist/resources/extensions/gsd/git-service.js +61 -4
- package/dist/resources/extensions/gsd/gitignore.js +4 -1
- package/dist/resources/extensions/gsd/guided-flow-queue.js +66 -5
- package/dist/resources/extensions/gsd/health-widget.js +55 -29
- package/dist/resources/extensions/gsd/json-persistence.js +20 -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 +8 -9
- package/dist/resources/extensions/gsd/memory-backfill.js +28 -21
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +44 -21
- package/dist/resources/extensions/gsd/metrics.js +4 -4
- package/dist/resources/extensions/gsd/migrate-external.js +11 -2
- 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/milestone-implementation-evidence.js +26 -20
- package/dist/resources/extensions/gsd/orphan-stash-audit.js +92 -16
- 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 +3 -3
- package/dist/resources/extensions/gsd/quick.js +45 -2
- package/dist/resources/extensions/gsd/root-write-leak-guard.js +7 -1
- 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/session-forensics.js +11 -1
- package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -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 +45 -2
- 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 +2 -2
- package/dist/resources/extensions/gsd/tools/complete-task.js +43 -14
- package/dist/resources/extensions/gsd/tools/exec-tool.js +7 -2
- package/dist/resources/extensions/gsd/tools/plan-slice.js +59 -44
- package/dist/resources/extensions/gsd/tools/plan-task.js +28 -5
- package/dist/resources/extensions/gsd/undo.js +43 -6
- package/dist/resources/extensions/gsd/unit-context-composer.js +23 -7
- package/dist/resources/extensions/gsd/unit-registry.js +36 -6
- package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +33 -3
- package/dist/resources/extensions/gsd/validation-block-guard.js +9 -4
- 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-git-preflight.js +30 -1
- package/dist/resources/extensions/gsd/worktree-manager.js +44 -2
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
- package/dist/web/standalone/.next/build-manifest.json +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/visualizer/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 +10 -10
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/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/node-pty/build/Makefile +1 -1
- package/package.json +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/workflow.d.ts +1 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +2 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- 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/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 -829
- 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 +258 -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 +23 -5
- 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/README.md +1 -1
- package/packages/mcp-server/dist/server.d.ts +1 -1
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +3 -3
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +13 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +35 -21
- 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/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/package.json +1 -1
- package/packages/pi-coding-agent/README.md +3 -2
- 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/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/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +20 -2
- 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 +80 -0
- package/src/resources/extensions/google-cli/stream-adapter.ts +106 -19
- package/src/resources/extensions/gsd/artifact-verification.ts +464 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/orchestrator.ts +25 -11
- 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 +35 -24
- package/src/resources/extensions/gsd/auto-post-unit.ts +1 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +41 -15
- package/src/resources/extensions/gsd/auto-recovery.ts +13 -511
- package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -5
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +3 -2
- package/src/resources/extensions/gsd/auto-verification.ts +5 -1
- package/src/resources/extensions/gsd/auto.ts +23 -8
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +125 -12
- package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +44 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +11 -5
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -0
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +52 -21
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +52 -18
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +104 -10
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +1 -1
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +2 -1
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +1 -1
- package/src/resources/extensions/gsd/commands-context.ts +18 -1
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +15 -10
- package/src/resources/extensions/gsd/commands-usage.ts +1 -1
- package/src/resources/extensions/gsd/commands-worktree.ts +12 -10
- package/src/resources/extensions/gsd/dashboard-overlay.ts +32 -3
- package/src/resources/extensions/gsd/db/engine.ts +8 -1
- package/src/resources/extensions/gsd/db/queries.ts +79 -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/docs/preferences-reference.md +2 -2
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +233 -5
- package/src/resources/extensions/gsd/doctor-providers.ts +103 -9
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +3 -0
- package/src/resources/extensions/gsd/doctor-types.ts +3 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +56 -11
- package/src/resources/extensions/gsd/flat-phase-migration.ts +44 -0
- package/src/resources/extensions/gsd/forensics.ts +2 -33
- package/src/resources/extensions/gsd/git-service.ts +69 -5
- package/src/resources/extensions/gsd/gitignore.ts +4 -1
- package/src/resources/extensions/gsd/guided-flow-queue.ts +89 -4
- package/src/resources/extensions/gsd/health-widget.ts +69 -32
- package/src/resources/extensions/gsd/json-persistence.ts +20 -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 +8 -11
- package/src/resources/extensions/gsd/memory-backfill.ts +26 -20
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +51 -19
- package/src/resources/extensions/gsd/metrics.ts +4 -4
- package/src/resources/extensions/gsd/migrate-external.ts +8 -2
- 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/milestone-implementation-evidence.ts +35 -21
- package/src/resources/extensions/gsd/orphan-stash-audit.ts +108 -20
- 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 +3 -3
- package/src/resources/extensions/gsd/quick.ts +43 -2
- package/src/resources/extensions/gsd/root-write-leak-guard.ts +13 -1
- 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/session-forensics.ts +11 -1
- package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -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 +81 -7
- 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-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 +146 -1
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/commands-context.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/commands-worktree-clean.test.ts +80 -0
- 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/complete-slice.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +48 -8
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +55 -2
- 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/dispatch-rule-coverage.test.ts +26 -1
- package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +70 -2
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +239 -2
- package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +45 -1
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +37 -2
- package/src/resources/extensions/gsd/tests/forensics-error-filter.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +268 -3
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +130 -3
- package/src/resources/extensions/gsd/tests/integration/queue-active-milestone-context-budget.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/integration/quick-branch-lifecycle.test.ts +56 -9
- 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/knowledge-cold-start.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +78 -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/orchestrator-logs.test.ts +43 -1
- package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +91 -7
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +103 -4
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +44 -1
- package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +54 -1
- 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/provider-errors.test.ts +195 -1
- package/src/resources/extensions/gsd/tests/read-uat-gate-verdict.test.ts +185 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +103 -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 +56 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +191 -0
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +208 -0
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +32 -3
- package/src/resources/extensions/gsd/tests/undo.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +193 -14
- package/src/resources/extensions/gsd/tests/unmerged-milestone-guard.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +69 -4
- package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +66 -0
- 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 +6 -5
- package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +151 -2
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +39 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
- package/src/resources/extensions/gsd/tools/complete-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/complete-task.ts +53 -15
- package/src/resources/extensions/gsd/tools/exec-tool.ts +7 -3
- package/src/resources/extensions/gsd/tools/plan-slice.ts +60 -47
- package/src/resources/extensions/gsd/tools/plan-task.ts +30 -5
- package/src/resources/extensions/gsd/undo.ts +47 -6
- package/src/resources/extensions/gsd/unit-context-composer.ts +33 -7
- package/src/resources/extensions/gsd/unit-registry.ts +36 -6
- package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +41 -5
- package/src/resources/extensions/gsd/validation-block-guard.ts +13 -7
- 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-git-preflight.ts +31 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +41 -1
- package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +0 -1
- package/dist/web/standalone/.next/static/chunks/796.e0bdc932325d7e03.js +0 -10
- package/dist/web/standalone/.next/static/chunks/webpack-f46ea08200a0227e.js +0 -1
- /package/dist/web/standalone/.next/static/{BTKtGFF1Y-hvVJEGhBRo9 → 2A_WqqCS-EoYZxN9_v3d2}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{BTKtGFF1Y-hvVJEGhBRo9 → 2A_WqqCS-EoYZxN9_v3d2}/_ssgManifest.js +0 -0
|
@@ -20,6 +20,7 @@ import { invalidateAllCaches } from "./cache.js";
|
|
|
20
20
|
import {
|
|
21
21
|
gsdRoot, resolveMilestoneFile, resolveSliceFile,
|
|
22
22
|
resolveGsdRootFile, relGsdRootFile, relSliceFile,
|
|
23
|
+
relMilestoneFile,
|
|
23
24
|
} from "./paths.js";
|
|
24
25
|
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
25
26
|
import { atomicWriteSync } from "./atomic-write.js";
|
|
@@ -29,6 +30,10 @@ import { loadQueueOrder, sortByQueueOrder, saveQueueOrder } from "./queue-order.
|
|
|
29
30
|
import { findMilestoneIds, nextMilestoneId } from "./milestone-ids.js";
|
|
30
31
|
import { isFutureMilestoneStatus } from "./status-guards.js";
|
|
31
32
|
|
|
33
|
+
const QUEUE_ARTIFACT_EXCERPT_MAX_CHARS = 20_000;
|
|
34
|
+
const QUEUE_EXISTING_MILESTONES_CONTEXT_MAX_CHARS = 120_000;
|
|
35
|
+
const QUEUE_CONTEXT_SECTION_SEPARATOR = "\n\n---\n\n";
|
|
36
|
+
|
|
32
37
|
// ─── Queue Entry Point ──────────────────────────────────────────────────────
|
|
33
38
|
|
|
34
39
|
/**
|
|
@@ -280,7 +285,9 @@ export async function buildExistingMilestonesContext(
|
|
|
280
285
|
if (contextFile) {
|
|
281
286
|
const content = await loadFile(contextFile);
|
|
282
287
|
if (content) {
|
|
283
|
-
parts.push(
|
|
288
|
+
parts.push(
|
|
289
|
+
`\n**Context:**\n${summarizeArtifactForQueue(content, relMilestoneFile(basePath, mid, "CONTEXT"))}`,
|
|
290
|
+
);
|
|
284
291
|
}
|
|
285
292
|
} else {
|
|
286
293
|
// No full CONTEXT.md — check for CONTEXT-DRAFT.md (draft seed from prior discussion)
|
|
@@ -288,7 +295,9 @@ export async function buildExistingMilestonesContext(
|
|
|
288
295
|
if (draftFile) {
|
|
289
296
|
const draftContent = await loadFile(draftFile);
|
|
290
297
|
if (draftContent) {
|
|
291
|
-
parts.push(
|
|
298
|
+
parts.push(
|
|
299
|
+
`\n**Draft context available:**\n${summarizeArtifactForQueue(draftContent, relMilestoneFile(basePath, mid, "CONTEXT-DRAFT"))}`,
|
|
300
|
+
);
|
|
292
301
|
}
|
|
293
302
|
}
|
|
294
303
|
}
|
|
@@ -300,7 +309,9 @@ export async function buildExistingMilestonesContext(
|
|
|
300
309
|
if (roadmapFile) {
|
|
301
310
|
const content = await loadFile(roadmapFile);
|
|
302
311
|
if (content) {
|
|
303
|
-
parts.push(
|
|
312
|
+
parts.push(
|
|
313
|
+
`\n**Roadmap:**\n${summarizeArtifactForQueue(content, relMilestoneFile(basePath, mid, "ROADMAP"))}`,
|
|
314
|
+
);
|
|
304
315
|
}
|
|
305
316
|
}
|
|
306
317
|
}
|
|
@@ -317,7 +328,81 @@ export async function buildExistingMilestonesContext(
|
|
|
317
328
|
}
|
|
318
329
|
}
|
|
319
330
|
|
|
320
|
-
return sections
|
|
331
|
+
return capExistingMilestonesContext(sections);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function summarizeArtifactForQueue(
|
|
335
|
+
content: string,
|
|
336
|
+
sourcePath: string,
|
|
337
|
+
cap = QUEUE_ARTIFACT_EXCERPT_MAX_CHARS,
|
|
338
|
+
): string {
|
|
339
|
+
const trimmed = content.trim();
|
|
340
|
+
if (trimmed.length <= cap) {
|
|
341
|
+
return `Source: \`${sourcePath}\`\n\n${trimmed}`;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const excerpt = trimmed.slice(0, cap).trimEnd();
|
|
345
|
+
const omittedChars = trimmed.length - excerpt.length;
|
|
346
|
+
return [
|
|
347
|
+
`Source: \`${sourcePath}\``,
|
|
348
|
+
"",
|
|
349
|
+
excerpt,
|
|
350
|
+
"",
|
|
351
|
+
`[Truncated ${omittedChars} chars. Read \`${sourcePath}\` for full content.]`,
|
|
352
|
+
].join("\n");
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function capExistingMilestonesContext(
|
|
356
|
+
sections: string[],
|
|
357
|
+
cap = QUEUE_EXISTING_MILESTONES_CONTEXT_MAX_CHARS,
|
|
358
|
+
): string {
|
|
359
|
+
const fullContext = sections.join(QUEUE_CONTEXT_SECTION_SEPARATOR);
|
|
360
|
+
if (fullContext.length <= cap) return fullContext;
|
|
361
|
+
|
|
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 noticeSuffix = `${QUEUE_CONTEXT_SECTION_SEPARATOR}${notice}`;
|
|
364
|
+
|
|
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
|
+
}
|
|
374
|
+
|
|
375
|
+
if (selected.length === sections.length) {
|
|
376
|
+
return selected.join(QUEUE_CONTEXT_SECTION_SEPARATOR) + noticeSuffix;
|
|
377
|
+
}
|
|
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;
|
|
386
|
+
|
|
387
|
+
return `${compactContext.slice(0, Math.max(0, cap - notice.length - 2)).trimEnd()}\n\n${notice}`;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function compactSectionForQueueBudget(section: string): string {
|
|
391
|
+
const lines = section.split("\n");
|
|
392
|
+
const compact: string[] = [];
|
|
393
|
+
|
|
394
|
+
if (lines[0]) compact.push(lines[0]);
|
|
395
|
+
|
|
396
|
+
const statusLine = lines.find(line => line.startsWith("**Status:**"));
|
|
397
|
+
if (statusLine) compact.push(statusLine);
|
|
398
|
+
|
|
399
|
+
const sourceLines = lines.filter(line => line.startsWith("Source: `"));
|
|
400
|
+
if (sourceLines.length > 0) {
|
|
401
|
+
compact.push("", "**Sources:**", ...sourceLines);
|
|
402
|
+
compact.push("", "[Artifact excerpts omitted due to total queue/rethink context budget.]");
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
return compact.join("\n");
|
|
321
406
|
}
|
|
322
407
|
|
|
323
408
|
// ─── Internal Helpers ───────────────────────────────────────────────────────
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
// File Purpose: Always-on ambient health signal rendered below the editor.
|
|
3
3
|
|
|
4
4
|
import type { ExtensionContext } from "@gsd/pi-coding-agent";
|
|
5
|
+
import { execFile } from "node:child_process";
|
|
5
6
|
import type { GSDState } from "./types.js";
|
|
6
|
-
import { runProviderChecks, summariseProviderIssues } from "./doctor-providers.js";
|
|
7
|
+
import { runProviderChecks, runProviderChecksAsync, summariseProviderIssues } from "./doctor-providers.js";
|
|
7
8
|
import { runEnvironmentChecks, runEnvironmentChecksAsync } from "./doctor-environment.js";
|
|
8
9
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
9
|
-
import {
|
|
10
|
+
import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
|
|
10
11
|
import { loadLedgerFromDisk, getProjectTotals } from "./metrics.js";
|
|
11
12
|
import { describeNextUnit, estimateTimeRemaining, updateSliceProgressCache } from "./auto-dashboard.js";
|
|
12
13
|
import { projectRoot } from "./commands/context.js";
|
|
@@ -15,32 +16,75 @@ import {
|
|
|
15
16
|
buildHealthLines,
|
|
16
17
|
detectHealthWidgetProjectState,
|
|
17
18
|
type HealthWidgetData,
|
|
19
|
+
type HealthWidgetProjectState,
|
|
18
20
|
} from "./health-widget-core.js";
|
|
19
21
|
|
|
20
22
|
export const HEALTH_WIDGET_ACTIVE_HINTS =
|
|
21
23
|
" /gsd auto to run · /gsd status to inspect · /gsd report for snapshots · /gsd notifications for history · /gsd help";
|
|
22
24
|
|
|
25
|
+
const LAST_COMMIT_LOOKUP_TIMEOUT_MS = 3_000;
|
|
26
|
+
const REFRESH_INTERVAL_MS = 60_000;
|
|
27
|
+
const PROJECT_STATE_CACHE_TTL_MS = REFRESH_INTERVAL_MS;
|
|
28
|
+
|
|
23
29
|
// ── Data loader ────────────────────────────────────────────────────────────────
|
|
24
30
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
const projectStateCache = new Map<string, { state: HealthWidgetProjectState; computedAt: number }>();
|
|
32
|
+
|
|
33
|
+
export function getCachedProjectState(basePath: string, force?: boolean): HealthWidgetProjectState {
|
|
34
|
+
const now = Date.now();
|
|
35
|
+
const cached = projectStateCache.get(basePath);
|
|
36
|
+
if (!force && cached && now - cached.computedAt <= PROJECT_STATE_CACHE_TTL_MS) {
|
|
37
|
+
return cached.state;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const state = detectHealthWidgetProjectState(basePath);
|
|
41
|
+
projectStateCache.set(basePath, { state, computedAt: now });
|
|
42
|
+
return state;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function runHealthWidgetGit(basePath: string, args: string[]): Promise<string | null> {
|
|
46
|
+
return new Promise((resolve) => {
|
|
47
|
+
const child = execFile(
|
|
48
|
+
"git",
|
|
49
|
+
args,
|
|
50
|
+
{
|
|
51
|
+
cwd: basePath,
|
|
52
|
+
timeout: LAST_COMMIT_LOOKUP_TIMEOUT_MS,
|
|
53
|
+
encoding: "utf-8",
|
|
54
|
+
env: GIT_NO_PROMPT_ENV,
|
|
55
|
+
},
|
|
56
|
+
(err, stdout) => resolve(err ? null : String(stdout).trimEnd()),
|
|
57
|
+
);
|
|
58
|
+
child.on("error", () => resolve(null));
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function loadLastCommitInfoAsync(basePath: string): Promise<{ epoch: number | null; message: string | null }> {
|
|
29
63
|
try {
|
|
30
|
-
if (
|
|
31
|
-
|
|
32
|
-
const epoch = nativeLastCommitEpoch(basePath, branch || "HEAD");
|
|
33
|
-
if (epoch > 0) {
|
|
34
|
-
return { epoch, message: nativeCommitSubject(basePath, branch || "HEAD") || null };
|
|
35
|
-
}
|
|
64
|
+
if ((await runHealthWidgetGit(basePath, ["rev-parse", "--git-dir"])) === null) {
|
|
65
|
+
return { epoch: null, message: null };
|
|
36
66
|
}
|
|
37
|
-
|
|
38
|
-
|
|
67
|
+
|
|
68
|
+
const branch = await runHealthWidgetGit(basePath, ["branch", "--show-current"]);
|
|
69
|
+
const ref = branch || "HEAD";
|
|
70
|
+
const raw = await runHealthWidgetGit(basePath, ["log", "-1", "--format=%ct%x00%s", ref]);
|
|
71
|
+
if (!raw) return { epoch: null, message: null };
|
|
72
|
+
|
|
73
|
+
const separator = raw.indexOf("\0");
|
|
74
|
+
const epochText = separator >= 0 ? raw.slice(0, separator) : raw;
|
|
75
|
+
const epoch = parseInt(epochText.trim(), 10) || 0;
|
|
76
|
+
if (epoch <= 0) return { epoch: null, message: null };
|
|
77
|
+
|
|
78
|
+
const message = separator >= 0 ? raw.slice(separator + 1).trim() : "";
|
|
79
|
+
return { epoch, message: message || null };
|
|
80
|
+
} catch {
|
|
81
|
+
return { epoch: null, message: null };
|
|
82
|
+
}
|
|
39
83
|
}
|
|
40
84
|
|
|
41
85
|
function loadHealthWidgetData(
|
|
42
86
|
basePath: string,
|
|
43
|
-
options?: { includeChecks?: boolean },
|
|
87
|
+
options?: { includeChecks?: boolean; forceProjectState?: boolean },
|
|
44
88
|
): HealthWidgetData {
|
|
45
89
|
// `includeChecks` gates the expensive subprocess-backed checks (provider +
|
|
46
90
|
// environment doctor: `lsof`, `docker`, `node --version`, ...). The initial
|
|
@@ -55,7 +99,7 @@ function loadHealthWidgetData(
|
|
|
55
99
|
let lastCommitEpoch: number | null = null;
|
|
56
100
|
let lastCommitMessage: string | null = null;
|
|
57
101
|
|
|
58
|
-
const projectState =
|
|
102
|
+
const projectState = getCachedProjectState(basePath, options?.forceProjectState);
|
|
59
103
|
|
|
60
104
|
try {
|
|
61
105
|
const prefs = loadEffectiveGSDPreferences();
|
|
@@ -83,13 +127,6 @@ function loadHealthWidgetData(
|
|
|
83
127
|
} catch { /* non-fatal */ }
|
|
84
128
|
}
|
|
85
129
|
|
|
86
|
-
// ── Last commit info ── (git spawns — gated like the other expensive checks)
|
|
87
|
-
if (includeChecks) {
|
|
88
|
-
const commit = loadLastCommitInfo(basePath);
|
|
89
|
-
lastCommitEpoch = commit.epoch;
|
|
90
|
-
lastCommitMessage = commit.message;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
130
|
return {
|
|
94
131
|
projectState,
|
|
95
132
|
budgetCeiling,
|
|
@@ -104,10 +141,8 @@ function loadHealthWidgetData(
|
|
|
104
141
|
}
|
|
105
142
|
|
|
106
143
|
// Non-blocking variant used by the widget's background refresh: the cheap fields
|
|
107
|
-
// come from the synchronous snapshot, then provider
|
|
108
|
-
// layered in off the event-loop critical path
|
|
109
|
-
// runEnvironmentChecksAsync). Keeps the always-on widget from stalling the UI on
|
|
110
|
-
// its initial enrichment or its 60s refresh.
|
|
144
|
+
// come from the synchronous snapshot, then provider, environment, and last-commit
|
|
145
|
+
// checks are layered in off the event-loop critical path.
|
|
111
146
|
async function loadHealthWidgetDataAsync(basePath: string): Promise<HealthWidgetData> {
|
|
112
147
|
const data = loadHealthWidgetData(basePath, { includeChecks: false });
|
|
113
148
|
let providerIssue = data.providerIssue;
|
|
@@ -115,7 +150,7 @@ async function loadHealthWidgetDataAsync(basePath: string): Promise<HealthWidget
|
|
|
115
150
|
let environmentWarningCount = 0;
|
|
116
151
|
|
|
117
152
|
try {
|
|
118
|
-
providerIssue = summariseProviderIssues(
|
|
153
|
+
providerIssue = summariseProviderIssues(await runProviderChecksAsync());
|
|
119
154
|
} catch { /* non-fatal */ }
|
|
120
155
|
|
|
121
156
|
try {
|
|
@@ -126,7 +161,7 @@ async function loadHealthWidgetDataAsync(basePath: string): Promise<HealthWidget
|
|
|
126
161
|
}
|
|
127
162
|
} catch { /* non-fatal */ }
|
|
128
163
|
|
|
129
|
-
const commit =
|
|
164
|
+
const commit = await loadLastCommitInfoAsync(basePath);
|
|
130
165
|
|
|
131
166
|
return {
|
|
132
167
|
...data,
|
|
@@ -141,8 +176,6 @@ async function loadHealthWidgetDataAsync(basePath: string): Promise<HealthWidget
|
|
|
141
176
|
|
|
142
177
|
// ── Widget init ────────────────────────────────────────────────────────────────
|
|
143
178
|
|
|
144
|
-
const REFRESH_INTERVAL_MS = 60_000;
|
|
145
|
-
|
|
146
179
|
/**
|
|
147
180
|
* Initialize the always-on gsd-health widget (belowEditor).
|
|
148
181
|
* Call once from the extension entry point after context is available.
|
|
@@ -152,13 +185,17 @@ export function initHealthWidget(ctx: ExtensionContext): void {
|
|
|
152
185
|
|
|
153
186
|
const basePath = projectRoot();
|
|
154
187
|
|
|
188
|
+
// Re-init must reflect filesystem changes immediately; the TTL cache is for
|
|
189
|
+
// interval refreshes, not this one-off synchronous paint.
|
|
190
|
+
projectStateCache.delete(basePath);
|
|
191
|
+
|
|
155
192
|
// String-array fallback — used in RPC mode (factory is a no-op there).
|
|
156
193
|
// Skip the expensive provider/environment doctor checks here: this runs
|
|
157
194
|
// synchronously on the interactive-startup path, where running them would
|
|
158
195
|
// block first paint by ~0.9s (lsof/docker probes, otherwise run again
|
|
159
196
|
// immediately by the factory below). The factory's async refresh fills in
|
|
160
197
|
// real health once the screen is up.
|
|
161
|
-
const initialData = loadHealthWidgetData(basePath, { includeChecks: false });
|
|
198
|
+
const initialData = loadHealthWidgetData(basePath, { includeChecks: false, forceProjectState: true });
|
|
162
199
|
ctx.ui.setWidget("gsd-health", buildHealthLines(initialData), { placement: "belowEditor" });
|
|
163
200
|
|
|
164
201
|
// Factory-based widget for TUI mode — replaces the string-array above
|
|
@@ -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.
|
|
@@ -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
|
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
insertArtifact,
|
|
26
26
|
deleteArtifactByPath,
|
|
27
27
|
getGateResults,
|
|
28
|
+
isDbAvailable,
|
|
28
29
|
} from "./gsd-db.js";
|
|
29
30
|
import type { MilestoneRow, ArtifactRow } from "./db-milestone-artifact-rows.js";
|
|
30
31
|
import type { SliceRow, TaskRow } from "./db-task-slice-rows.js";
|
|
@@ -631,16 +632,8 @@ export async function renderRoadmapCheckboxes(
|
|
|
631
632
|
basePath: string,
|
|
632
633
|
milestoneId: string,
|
|
633
634
|
): Promise<boolean> {
|
|
634
|
-
const
|
|
635
|
-
|
|
636
|
-
process.stderr.write(
|
|
637
|
-
`markdown-renderer: no slices found for milestone ${milestoneId}\n`,
|
|
638
|
-
);
|
|
639
|
-
return false;
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
await renderRoadmapFromDb(basePath, milestoneId);
|
|
643
|
-
return true;
|
|
635
|
+
const rendered = await renderRoadmapFromDb(basePath, milestoneId);
|
|
636
|
+
return !("skipped" in rendered);
|
|
644
637
|
}
|
|
645
638
|
|
|
646
639
|
/**
|
|
@@ -737,7 +730,8 @@ function isAutoRecoveryPlaceholderPlan(content: string): boolean {
|
|
|
737
730
|
* projection (the 4S/0T-vs-5S/13T drift class). The artifacts table is an
|
|
738
731
|
* output sink, never a render input.
|
|
739
732
|
*
|
|
740
|
-
* @returns true if the plan was written, false
|
|
733
|
+
* @returns true if the plan was written, false when the DB slice has no tasks
|
|
734
|
+
* @throws when the DB connection is unavailable or the render write fails
|
|
741
735
|
*/
|
|
742
736
|
export async function renderPlanCheckboxes(
|
|
743
737
|
basePath: string,
|
|
@@ -747,6 +741,9 @@ export async function renderPlanCheckboxes(
|
|
|
747
741
|
): Promise<boolean> {
|
|
748
742
|
const tasks = getSliceTasks(milestoneId, sliceId);
|
|
749
743
|
if (tasks.length === 0) {
|
|
744
|
+
if (!isDbAvailable()) {
|
|
745
|
+
throw new Error(`database unavailable while rendering plan checkboxes for ${milestoneId}/${sliceId}`);
|
|
746
|
+
}
|
|
750
747
|
process.stderr.write(
|
|
751
748
|
`markdown-renderer: no tasks found for ${milestoneId}/${sliceId}\n`,
|
|
752
749
|
);
|
|
@@ -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) {
|
|
@@ -142,23 +142,53 @@ function getActiveDecisions(): DecisionRow[] {
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
/**
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
* backfill's idempotency check.
|
|
145
|
+
* Source IDs already present in memory `structured_fields`. Collected with one
|
|
146
|
+
* pass over the memories table so the scanner does not perform a non-indexable
|
|
147
|
+
* LIKE probe for every decision and KNOWLEDGE.md row.
|
|
149
148
|
*/
|
|
150
|
-
|
|
151
|
-
|
|
149
|
+
interface MemorySourceMarkers {
|
|
150
|
+
decisionIds: Set<string>;
|
|
151
|
+
knowledgeIds: Set<string>;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function emptyMemorySourceMarkers(): MemorySourceMarkers {
|
|
155
|
+
return { decisionIds: new Set(), knowledgeIds: new Set() };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function getMemorySourceMarkers(): MemorySourceMarkers {
|
|
159
|
+
const markers = emptyMemorySourceMarkers();
|
|
160
|
+
if (!isDbAvailable()) return markers;
|
|
152
161
|
const adapter = _getAdapter();
|
|
153
|
-
if (!adapter) return
|
|
162
|
+
if (!adapter) return markers;
|
|
163
|
+
try {
|
|
164
|
+
const rows = adapter
|
|
165
|
+
.prepare("SELECT structured_fields FROM memories WHERE structured_fields IS NOT NULL")
|
|
166
|
+
.all() as Array<Record<string, unknown>>;
|
|
167
|
+
for (const row of rows) {
|
|
168
|
+
collectMemorySourceMarker(markers, row["structured_fields"]);
|
|
169
|
+
}
|
|
170
|
+
} catch {
|
|
171
|
+
return markers;
|
|
172
|
+
}
|
|
173
|
+
return markers;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function collectMemorySourceMarker(markers: MemorySourceMarkers, raw: unknown): void {
|
|
177
|
+
if (typeof raw !== "string" || raw.length === 0) return;
|
|
154
178
|
try {
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
179
|
+
const parsed = JSON.parse(raw);
|
|
180
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return;
|
|
181
|
+
const fields = parsed as Record<string, unknown>;
|
|
182
|
+
const decisionId = fields["sourceDecisionId"];
|
|
183
|
+
if (typeof decisionId === "string" && decisionId.length > 0) {
|
|
184
|
+
markers.decisionIds.add(decisionId);
|
|
185
|
+
}
|
|
186
|
+
const knowledgeId = fields["sourceKnowledgeId"];
|
|
187
|
+
if (typeof knowledgeId === "string" && knowledgeId.length > 0) {
|
|
188
|
+
markers.knowledgeIds.add(knowledgeId);
|
|
189
|
+
}
|
|
160
190
|
} catch {
|
|
161
|
-
return
|
|
191
|
+
return;
|
|
162
192
|
}
|
|
163
193
|
}
|
|
164
194
|
|
|
@@ -174,10 +204,14 @@ const SAMPLE_LIMIT = 5;
|
|
|
174
204
|
export function scanConsolidationGaps(basePath: string): ConsolidationGapReport {
|
|
175
205
|
// ── Decisions ────────────────────────────────────────────────────────
|
|
176
206
|
const decisions = getActiveDecisions();
|
|
207
|
+
const knowledgeRows = parseKnowledgeRows(knowledgeMdContent(basePath));
|
|
208
|
+
const memorySourceMarkers = decisions.length > 0 || knowledgeRows.length > 0
|
|
209
|
+
? getMemorySourceMarkers()
|
|
210
|
+
: emptyMemorySourceMarkers();
|
|
177
211
|
const decisionSamples: DecisionsSurfaceReport["samples"] = [];
|
|
178
212
|
let decisionMigrated = 0;
|
|
179
213
|
for (const decision of decisions) {
|
|
180
|
-
if (
|
|
214
|
+
if (memorySourceMarkers.decisionIds.has(decision.id)) {
|
|
181
215
|
decisionMigrated += 1;
|
|
182
216
|
continue;
|
|
183
217
|
}
|
|
@@ -190,16 +224,14 @@ export function scanConsolidationGaps(basePath: string): ConsolidationGapReport
|
|
|
190
224
|
}
|
|
191
225
|
|
|
192
226
|
// ── KNOWLEDGE.md ─────────────────────────────────────────────────────
|
|
193
|
-
const knowledgeRows = parseKnowledgeRows(knowledgeMdContent(basePath));
|
|
194
227
|
const knowledgeByTable = { rules: 0, patterns: 0, lessons: 0 };
|
|
195
228
|
const knowledgeSamples: KnowledgeSurfaceReport["samples"] = [];
|
|
196
229
|
let knowledgeMigrated = 0;
|
|
197
230
|
for (const row of knowledgeRows) {
|
|
198
231
|
knowledgeByTable[row.table] += 1;
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
|
|
202
|
-
if (memoryHasSourceMarker("sourceKnowledgeId", row.id)) {
|
|
232
|
+
// KNOWLEDGE.md backfill writes `sourceKnowledgeId`; rows without that
|
|
233
|
+
// marker are still reported as consolidation gaps.
|
|
234
|
+
if (memorySourceMarkers.knowledgeIds.has(row.id)) {
|
|
203
235
|
knowledgeMigrated += 1;
|
|
204
236
|
continue;
|
|
205
237
|
}
|
|
@@ -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
|
}
|