gsd-pi 2.82.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -32
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +10 -1
- package/dist/resources/extensions/browser-tools/tools/screenshot.js +1 -0
- package/dist/resources/extensions/browser-tools/tools/zoom.js +1 -0
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +1 -1
- package/dist/resources/extensions/cmux/index.js +5 -0
- package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
- package/dist/resources/extensions/gsd/auto/loop.js +19 -6
- package/dist/resources/extensions/gsd/auto/orchestrator.js +124 -6
- package/dist/resources/extensions/gsd/auto/phases.js +90 -31
- package/dist/resources/extensions/gsd/auto/session.js +4 -0
- package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
- package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +20 -19
- package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +246 -133
- package/dist/resources/extensions/gsd/auto-prompts.js +13 -5
- package/dist/resources/extensions/gsd/auto-recovery.js +71 -14
- package/dist/resources/extensions/gsd/auto-start.js +87 -14
- package/dist/resources/extensions/gsd/auto-verification.js +45 -26
- package/dist/resources/extensions/gsd/auto-worktree.js +176 -10
- package/dist/resources/extensions/gsd/auto.js +178 -63
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +31 -7
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +10 -9
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +9 -2
- package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +17 -3
- package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
- package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +39 -1
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
- package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +7 -2
- package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
- package/dist/resources/extensions/gsd/context-store.js +112 -0
- package/dist/resources/extensions/gsd/crash-recovery.js +43 -5
- package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
- package/dist/resources/extensions/gsd/db-writer.js +150 -84
- package/dist/resources/extensions/gsd/dispatch-guard.js +2 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/doctor-git-checks.js +87 -7
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
- package/dist/resources/extensions/gsd/doctor.js +2 -28
- package/dist/resources/extensions/gsd/export-html.js +27 -425
- package/dist/resources/extensions/gsd/forensics.js +3 -3
- package/dist/resources/extensions/gsd/git-service.js +45 -3
- package/dist/resources/extensions/gsd/gsd-db.js +21 -6
- package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
- package/dist/resources/extensions/gsd/guided-flow.js +101 -116
- package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
- package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
- package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
- package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
- package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +16 -9
- package/dist/resources/extensions/gsd/md-importer.js +1 -1
- package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
- package/dist/resources/extensions/gsd/migrate/command.js +5 -0
- package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
- package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
- package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
- package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
- package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
- package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
- package/dist/resources/extensions/gsd/native-git-bridge.js +48 -12
- package/dist/resources/extensions/gsd/paths.js +4 -0
- package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
- package/dist/resources/extensions/gsd/post-execution-checks.js +73 -2
- package/dist/resources/extensions/gsd/pre-execution-checks.js +28 -1
- package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/prompts/system.md +2 -2
- package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
- package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
- package/dist/resources/extensions/gsd/state.js +3 -3
- package/dist/resources/extensions/gsd/status-guards.js +11 -0
- package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
- package/dist/resources/extensions/gsd/templates/plan.md +9 -5
- package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
- package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
- package/dist/resources/extensions/gsd/tools/plan-slice.js +87 -14
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +32 -10
- package/dist/resources/extensions/gsd/validation.js +23 -1
- package/dist/resources/extensions/gsd/verification-gate.js +68 -7
- package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
- package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +54 -10
- package/dist/resources/extensions/gsd/worktree-manager.js +1 -1
- package/dist/resources/extensions/shared/html-shell.js +388 -0
- package/dist/resources/extensions/subagent/index.js +448 -78
- package/dist/resources/extensions/subagent/launch.js +77 -0
- package/dist/resources/extensions/subagent/run-store.js +148 -0
- package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
- package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
- package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/dist/resources/extensions/visual-brief/index.js +5 -0
- package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
- package/dist/resources/extensions/visual-brief/prompts.js +140 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +5 -5
- 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.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +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 +4 -7
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
- 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 +4 -5
- 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 +2 -5
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -7
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
- 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 +4 -5
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page.js.nft.json +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 +9 -9
- package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
- 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/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +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/2973.33f26573894b6153.js +2 -0
- package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
- package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/layout-b23b3f6858dc6dc8.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
- package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
- package/package.json +6 -5
- package/packages/contracts/dist/rpc.test.js +7 -0
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +21 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +24 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/src/rpc.test.ts +8 -0
- package/packages/contracts/src/workflow.ts +24 -0
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/README.md +14 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +80 -0
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/workflow-tools-parity.test.ts +244 -0
- package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
- package/packages/mcp-server/src/workflow-tools.ts +168 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/native/tsconfig.json +2 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/index.d.ts +2 -2
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -1
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +5 -6
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/transform-messages.d.ts +11 -0
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/index.ts +7 -2
- package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
- package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
- package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
- package/packages/pi-ai/src/providers/simple-options.ts +5 -6
- package/packages/pi-ai/src/providers/transform-messages.ts +24 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +71 -97
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
- package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
- package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -102
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
- package/packages/pi-coding-agent/src/tests/system-prompt-file-safety.test.ts +22 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
- package/packages/pi-tui/dist/terminal.d.ts +2 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +12 -0
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +5 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
- package/packages/pi-tui/src/terminal.ts +11 -0
- package/packages/pi-tui/src/tui.ts +6 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +10 -1
- package/src/resources/extensions/browser-tools/tools/screenshot.ts +1 -0
- package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +1 -1
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +9 -0
- package/src/resources/extensions/cmux/index.ts +6 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +59 -16
- package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
- package/src/resources/extensions/gsd/auto/loop.ts +22 -6
- package/src/resources/extensions/gsd/auto/orchestrator.ts +129 -6
- package/src/resources/extensions/gsd/auto/phases.ts +104 -38
- package/src/resources/extensions/gsd/auto/session.ts +4 -0
- package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
- package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +21 -19
- package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +279 -144
- package/src/resources/extensions/gsd/auto-prompts.ts +13 -5
- package/src/resources/extensions/gsd/auto-recovery.ts +74 -11
- package/src/resources/extensions/gsd/auto-start.ts +94 -12
- package/src/resources/extensions/gsd/auto-verification.ts +58 -36
- package/src/resources/extensions/gsd/auto-worktree.ts +193 -10
- package/src/resources/extensions/gsd/auto.ts +187 -61
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +42 -7
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +10 -9
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +10 -2
- package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +20 -4
- package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
- package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +42 -1
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
- package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +8 -3
- package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
- package/src/resources/extensions/gsd/context-store.ts +120 -1
- package/src/resources/extensions/gsd/crash-recovery.ts +44 -4
- package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
- package/src/resources/extensions/gsd/db-writer.ts +167 -84
- package/src/resources/extensions/gsd/dispatch-guard.ts +2 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/doctor-git-checks.ts +89 -7
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
- package/src/resources/extensions/gsd/doctor-types.ts +3 -0
- package/src/resources/extensions/gsd/doctor.ts +2 -27
- package/src/resources/extensions/gsd/export-html.ts +27 -427
- package/src/resources/extensions/gsd/forensics.ts +3 -3
- package/src/resources/extensions/gsd/git-service.ts +51 -4
- package/src/resources/extensions/gsd/gsd-db.ts +21 -6
- package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
- package/src/resources/extensions/gsd/guided-flow.ts +134 -133
- package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
- package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
- package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
- package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
- package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +16 -9
- package/src/resources/extensions/gsd/md-importer.ts +1 -1
- package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
- package/src/resources/extensions/gsd/migrate/command.ts +5 -0
- package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
- package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
- package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
- package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
- package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
- package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
- package/src/resources/extensions/gsd/native-git-bridge.ts +54 -12
- package/src/resources/extensions/gsd/paths.ts +5 -0
- package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
- package/src/resources/extensions/gsd/post-execution-checks.ts +87 -2
- package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -1
- package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/src/resources/extensions/gsd/prompts/queue.md +4 -4
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/prompts/system.md +2 -2
- package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
- package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
- package/src/resources/extensions/gsd/state.ts +3 -3
- package/src/resources/extensions/gsd/status-guards.ts +13 -0
- package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
- package/src/resources/extensions/gsd/templates/plan.md +9 -5
- package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +131 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +487 -4
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +91 -6
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
- package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +11 -2
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -9
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
- package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +86 -2
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +13 -8
- package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
- package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +59 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
- package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +112 -1
- package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
- package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
- package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
- package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +63 -2
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +251 -2
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +86 -0
- package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
- package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
- package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +53 -2
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +13 -1
- package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +103 -7
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +110 -1
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
- package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +54 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
- package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
- package/src/resources/extensions/gsd/tools/plan-slice.ts +97 -12
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
- package/src/resources/extensions/gsd/types.ts +1 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +47 -11
- package/src/resources/extensions/gsd/validation.ts +23 -1
- package/src/resources/extensions/gsd/verification-gate.ts +78 -6
- package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
- package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +61 -10
- package/src/resources/extensions/gsd/worktree-manager.ts +1 -1
- package/src/resources/extensions/shared/html-shell.ts +412 -0
- package/src/resources/extensions/subagent/index.ts +567 -103
- package/src/resources/extensions/subagent/launch.ts +131 -0
- package/src/resources/extensions/subagent/run-store.ts +218 -0
- package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
- package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
- package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
- package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
- package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/src/resources/extensions/visual-brief/index.ts +8 -0
- package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
- package/src/resources/extensions/visual-brief/prompts.ts +183 -0
- package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
- package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
- package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
- package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/layout-9ecfd95f343793f0.js +0 -1
- package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
- package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
- package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- /package/dist/web/standalone/.next/static/{S44UQTFCUdA44dkjfYt6S → qoMxZh-xuwuvpFW0x0k01}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{S44UQTFCUdA44dkjfYt6S → qoMxZh-xuwuvpFW0x0k01}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// GSD2 — KNOWLEDGE.md hybrid projection renderer (ADR-013 Stage 2b).
|
|
2
|
+
//
|
|
3
|
+
// Renders `.gsd/KNOWLEDGE.md` as a hybrid file:
|
|
4
|
+
// - Rules section: read directly from the existing KNOWLEDGE.md (manual,
|
|
5
|
+
// per ADR-013 line 39 — Rules are not migrated to memories).
|
|
6
|
+
// - Patterns section: read from `memories` where `category = "pattern"`
|
|
7
|
+
// AND `structured_fields.sourceKnowledgeId` is set (matches the marker
|
|
8
|
+
// written by knowledge-backfill.ts).
|
|
9
|
+
// - Lessons Learned section: read from `memories` where
|
|
10
|
+
// `category = "gotcha"` AND `structured_fields.sourceKnowledgeId` is set.
|
|
11
|
+
//
|
|
12
|
+
// Triggered opportunistically by `buildBeforeAgentStartResult` after the
|
|
13
|
+
// knowledge backfill runs. Output is byte-stable when nothing has changed
|
|
14
|
+
// (atomic write). The Rules section is preserved verbatim — including
|
|
15
|
+
// indentation, trailing whitespace, and comments — so manual edits to that
|
|
16
|
+
// section continue to round-trip through `/gsd knowledge`.
|
|
17
|
+
//
|
|
18
|
+
// Memories captured directly via `capture_thought` (without a
|
|
19
|
+
// `sourceKnowledgeId` marker) are intentionally NOT rendered into
|
|
20
|
+
// KNOWLEDGE.md. They remain accessible via the loadMemoryBlock auto-injection
|
|
21
|
+
// surface; KNOWLEDGE.md projects only the KNOWLEDGE.md-originating subset.
|
|
22
|
+
|
|
23
|
+
import { atomicWriteSync } from "./atomic-write.js";
|
|
24
|
+
import { _getAdapter, isDbAvailable } from "./gsd-db.js";
|
|
25
|
+
import {
|
|
26
|
+
KNOWLEDGE_SECTIONS,
|
|
27
|
+
knowledgeMdPath,
|
|
28
|
+
readKnowledgeMd,
|
|
29
|
+
} from "./knowledge-parser.js";
|
|
30
|
+
import { logWarning } from "./workflow-logger.js";
|
|
31
|
+
|
|
32
|
+
const RULES_HEADING = "## Rules";
|
|
33
|
+
const PATTERNS_HEADING = "## Patterns";
|
|
34
|
+
const LESSONS_HEADING = "## Lessons Learned";
|
|
35
|
+
|
|
36
|
+
const PATTERNS_HEADER = "| # | Pattern | Where | Notes |";
|
|
37
|
+
const PATTERNS_SEPARATOR = "|---|---------|-------|-------|";
|
|
38
|
+
|
|
39
|
+
const LESSONS_HEADER = "| # | What Happened | Root Cause | Fix | Scope |";
|
|
40
|
+
const LESSONS_SEPARATOR = "|---|--------------|------------|-----|-------|";
|
|
41
|
+
|
|
42
|
+
const DEFAULT_INTRO = [
|
|
43
|
+
"# Project Knowledge",
|
|
44
|
+
"",
|
|
45
|
+
"Append-only register of project-specific rules, patterns, and lessons learned.",
|
|
46
|
+
"Agents read this before every unit. Add entries when you discover something worth remembering.",
|
|
47
|
+
"",
|
|
48
|
+
].join("\n");
|
|
49
|
+
|
|
50
|
+
interface KnowledgeMemoryRow {
|
|
51
|
+
sourceId: string;
|
|
52
|
+
structured: Record<string, unknown>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface KnowledgeMemoryReadResult {
|
|
56
|
+
ok: boolean;
|
|
57
|
+
rows: KnowledgeMemoryRow[];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface KnowledgeProjectionResult {
|
|
61
|
+
written: boolean;
|
|
62
|
+
content: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Read pattern memories that originated from KNOWLEDGE.md, ordered by
|
|
67
|
+
* `sourceKnowledgeId` (lexicographic — P001 < P002 < P010). Memories whose
|
|
68
|
+
* structuredFields fail to parse are skipped silently; they are diagnosed
|
|
69
|
+
* separately by the memory-consolidation scanner.
|
|
70
|
+
*/
|
|
71
|
+
function readKnowledgeMemories(category: "pattern" | "gotcha"): KnowledgeMemoryReadResult {
|
|
72
|
+
if (!isDbAvailable()) return { ok: false, rows: [] };
|
|
73
|
+
const adapter = _getAdapter();
|
|
74
|
+
if (!adapter) return { ok: false, rows: [] };
|
|
75
|
+
try {
|
|
76
|
+
const rows = adapter
|
|
77
|
+
.prepare(
|
|
78
|
+
"SELECT structured_fields FROM memories WHERE category = :cat AND structured_fields IS NOT NULL",
|
|
79
|
+
)
|
|
80
|
+
.all({ ":cat": category }) as Array<{ structured_fields: string | null }>;
|
|
81
|
+
|
|
82
|
+
const out: KnowledgeMemoryRow[] = [];
|
|
83
|
+
for (const row of rows) {
|
|
84
|
+
if (!row.structured_fields) continue;
|
|
85
|
+
let sf: Record<string, unknown>;
|
|
86
|
+
try {
|
|
87
|
+
sf = JSON.parse(row.structured_fields) as Record<string, unknown>;
|
|
88
|
+
} catch {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const sourceId = sf["sourceKnowledgeId"];
|
|
92
|
+
if (typeof sourceId !== "string" || sourceId.length === 0) continue;
|
|
93
|
+
out.push({ sourceId, structured: sf });
|
|
94
|
+
}
|
|
95
|
+
// Lexicographic sort matches the docstring contract (P001 < P002 < P010).
|
|
96
|
+
// DB seq order is creation-time; sorting by sourceId stabilizes the
|
|
97
|
+
// rendered output across reruns.
|
|
98
|
+
out.sort((a, b) => a.sourceId.localeCompare(b.sourceId));
|
|
99
|
+
return { ok: true, rows: out };
|
|
100
|
+
} catch {
|
|
101
|
+
return { ok: false, rows: [] };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function escapeCell(value: string | undefined): string {
|
|
106
|
+
return (value ?? "")
|
|
107
|
+
.replace(/\s+/g, " ")
|
|
108
|
+
.replace(/\|/g, "\\|")
|
|
109
|
+
.trim();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function renderPatternsSection(memories: KnowledgeMemoryRow[]): string[] {
|
|
113
|
+
const lines = [PATTERNS_HEADING, "", PATTERNS_HEADER, PATTERNS_SEPARATOR];
|
|
114
|
+
for (const m of memories) {
|
|
115
|
+
const pattern = escapeCell(typeof m.structured["pattern"] === "string" ? (m.structured["pattern"] as string) : "");
|
|
116
|
+
const where = escapeCell(typeof m.structured["where"] === "string" ? (m.structured["where"] as string) : "");
|
|
117
|
+
const notes = escapeCell(typeof m.structured["notes"] === "string" ? (m.structured["notes"] as string) : "");
|
|
118
|
+
lines.push(`| ${m.sourceId} | ${pattern} | ${where || "—"} | ${notes || "—"} |`);
|
|
119
|
+
}
|
|
120
|
+
lines.push("");
|
|
121
|
+
return lines;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function renderLessonsSection(memories: KnowledgeMemoryRow[]): string[] {
|
|
125
|
+
const lines = [LESSONS_HEADING, "", LESSONS_HEADER, LESSONS_SEPARATOR];
|
|
126
|
+
for (const m of memories) {
|
|
127
|
+
const what = escapeCell(typeof m.structured["whatHappened"] === "string" ? (m.structured["whatHappened"] as string) : "");
|
|
128
|
+
const rootCause = escapeCell(typeof m.structured["rootCause"] === "string" ? (m.structured["rootCause"] as string) : "");
|
|
129
|
+
const fix = escapeCell(typeof m.structured["fix"] === "string" ? (m.structured["fix"] as string) : "");
|
|
130
|
+
const scope = escapeCell(typeof m.structured["scopeText"] === "string" ? (m.structured["scopeText"] as string) : "");
|
|
131
|
+
lines.push(`| ${m.sourceId} | ${what} | ${rootCause || "—"} | ${fix || "—"} | ${scope || "project"} |`);
|
|
132
|
+
}
|
|
133
|
+
lines.push("");
|
|
134
|
+
return lines;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Extract the Rules section (heading + table) from the existing
|
|
139
|
+
* `KNOWLEDGE.md` content, verbatim. Returns an empty default section
|
|
140
|
+
* (heading + empty table) when the source has no `## Rules` heading.
|
|
141
|
+
*/
|
|
142
|
+
function extractRulesSection(existing: string): string[] {
|
|
143
|
+
const lines = existing.split("\n");
|
|
144
|
+
const startIdx = lines.findIndex((l) => l.trim() === RULES_HEADING);
|
|
145
|
+
if (startIdx === -1) {
|
|
146
|
+
return [
|
|
147
|
+
RULES_HEADING,
|
|
148
|
+
"",
|
|
149
|
+
"| # | Scope | Rule | Why | Added |",
|
|
150
|
+
"|---|-------|------|-----|-------|",
|
|
151
|
+
"",
|
|
152
|
+
];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Find the next H2 heading that ends the Rules section.
|
|
156
|
+
let endIdx = lines.length;
|
|
157
|
+
for (let i = startIdx + 1; i < lines.length; i++) {
|
|
158
|
+
if (lines[i]!.startsWith("## ")) {
|
|
159
|
+
endIdx = i;
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Strip trailing blank lines from the captured slice — the assembled
|
|
165
|
+
// output adds its own separator blank line between sections.
|
|
166
|
+
const slice = lines.slice(startIdx, endIdx);
|
|
167
|
+
while (slice.length > 0 && slice[slice.length - 1]!.trim() === "") {
|
|
168
|
+
slice.pop();
|
|
169
|
+
}
|
|
170
|
+
slice.push("");
|
|
171
|
+
return slice;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Extract the intro prose (anything before `## Rules`) verbatim, preserving
|
|
176
|
+
* any title (`# Project Knowledge`), comments, and description text. Falls
|
|
177
|
+
* back to the `DEFAULT_INTRO` template when the source has no Rules heading
|
|
178
|
+
* yet.
|
|
179
|
+
*/
|
|
180
|
+
function extractIntro(existing: string): string {
|
|
181
|
+
if (!existing.trim()) return DEFAULT_INTRO;
|
|
182
|
+
const lines = existing.split("\n");
|
|
183
|
+
const rulesIdx = lines.findIndex((l) => l.trim() === RULES_HEADING);
|
|
184
|
+
if (rulesIdx === -1) return DEFAULT_INTRO;
|
|
185
|
+
// Trim trailing blank lines so the assembly adds its own separator.
|
|
186
|
+
const slice = lines.slice(0, rulesIdx);
|
|
187
|
+
while (slice.length > 0 && slice[slice.length - 1]!.trim() === "") {
|
|
188
|
+
slice.pop();
|
|
189
|
+
}
|
|
190
|
+
slice.push("");
|
|
191
|
+
return slice.join("\n");
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Render the hybrid `KNOWLEDGE.md`: manual Rules + projected Patterns +
|
|
196
|
+
* projected Lessons. Returns the rendered content and a flag indicating
|
|
197
|
+
* whether the file was written (skipped when content is byte-identical to
|
|
198
|
+
* what's on disk).
|
|
199
|
+
*
|
|
200
|
+
* Best-effort: catches all errors and returns `{ written: false, content: "" }`.
|
|
201
|
+
*/
|
|
202
|
+
export function renderKnowledgeProjection(basePath: string): KnowledgeProjectionResult {
|
|
203
|
+
try {
|
|
204
|
+
const existing = readKnowledgeMd(basePath);
|
|
205
|
+
const intro = extractIntro(existing);
|
|
206
|
+
const rules = extractRulesSection(existing);
|
|
207
|
+
const patternMemories = readKnowledgeMemories("pattern");
|
|
208
|
+
const lessonMemories = readKnowledgeMemories("gotcha");
|
|
209
|
+
if (!patternMemories.ok || !lessonMemories.ok) {
|
|
210
|
+
return { written: false, content: existing };
|
|
211
|
+
}
|
|
212
|
+
const patterns = renderPatternsSection(patternMemories.rows);
|
|
213
|
+
const lessons = renderLessonsSection(lessonMemories.rows);
|
|
214
|
+
|
|
215
|
+
const introText = intro
|
|
216
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
217
|
+
.replace(/\s+$/g, "");
|
|
218
|
+
const projectedText = [...patterns, ...lessons]
|
|
219
|
+
.join("\n")
|
|
220
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
221
|
+
.replace(/\s+$/g, "");
|
|
222
|
+
const content = [introText, rules.join("\n"), projectedText]
|
|
223
|
+
.join("\n")
|
|
224
|
+
.replace(/\s+$/g, "")
|
|
225
|
+
+ "\n";
|
|
226
|
+
|
|
227
|
+
if (content === existing) {
|
|
228
|
+
return { written: false, content };
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
atomicWriteSync(knowledgeMdPath(basePath), content, "utf-8");
|
|
232
|
+
return { written: true, content };
|
|
233
|
+
} catch (e) {
|
|
234
|
+
logWarning("renderer", `KNOWLEDGE.md projection render failed: ${(e as Error).message}`);
|
|
235
|
+
return { written: false, content: "" };
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Re-export the section headings so tests can assert on the canonical
|
|
240
|
+
// structure without re-defining the strings.
|
|
241
|
+
export { KNOWLEDGE_SECTIONS };
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
resolveMilestoneFile,
|
|
33
33
|
resolveSliceFile,
|
|
34
34
|
resolveSlicePath,
|
|
35
|
-
|
|
35
|
+
gsdProjectionRoot,
|
|
36
36
|
gsdRoot,
|
|
37
37
|
buildTaskFileName,
|
|
38
38
|
buildSliceFileName,
|
|
@@ -48,7 +48,11 @@ import { clearPathCache } from "./paths.js";
|
|
|
48
48
|
* E.g. "/project/.gsd/milestones/M001/M001-ROADMAP.md" → "milestones/M001/M001-ROADMAP.md"
|
|
49
49
|
*/
|
|
50
50
|
function toArtifactPath(absPath: string, basePath: string): string {
|
|
51
|
-
const
|
|
51
|
+
const projectionRoot = gsdProjectionRoot(basePath);
|
|
52
|
+
const projectionRel = relative(projectionRoot, absPath);
|
|
53
|
+
const root = projectionRel && !projectionRel.startsWith("..") && !projectionRel.startsWith("/")
|
|
54
|
+
? projectionRoot
|
|
55
|
+
: gsdRoot(basePath);
|
|
52
56
|
const rel = relative(root, absPath);
|
|
53
57
|
// Normalize to forward slashes for consistent DB keys
|
|
54
58
|
return rel.replace(/\\/g, "/");
|
|
@@ -157,7 +161,12 @@ function renderRoadmapMarkdown(milestone: MilestoneRow, slices: SliceRow[]): str
|
|
|
157
161
|
for (const slice of slices) {
|
|
158
162
|
const done = isClosedStatus(slice.status) ? "x" : " ";
|
|
159
163
|
const depends = `[${(slice.depends ?? []).join(",")}]`;
|
|
160
|
-
|
|
164
|
+
// ADR-011: sketch slices get a `[sketch]` badge so the roadmap shows at a
|
|
165
|
+
// glance which slices are still pending refine-slice expansion. The badge
|
|
166
|
+
// sits in front of `risk:` so it's visible in narrow terminals that may
|
|
167
|
+
// truncate the line.
|
|
168
|
+
const sketchBadge = slice.is_sketch === 1 ? "`[sketch]` " : "";
|
|
169
|
+
lines.push(`- [${done}] **${slice.id}: ${slice.title}** ${sketchBadge}\`risk:${slice.risk}\` \`depends:${depends}\``);
|
|
161
170
|
lines.push(` > After this: ${slice.demo}`);
|
|
162
171
|
lines.push("");
|
|
163
172
|
}
|
|
@@ -369,10 +378,9 @@ export async function renderPlanFromDb(
|
|
|
369
378
|
throw new Error(`no tasks found for ${milestoneId}/${sliceId}`);
|
|
370
379
|
}
|
|
371
380
|
|
|
372
|
-
const slicePath =
|
|
373
|
-
|
|
374
|
-
const absPath =
|
|
375
|
-
?? join(slicePath, `${sliceId}-PLAN.md`);
|
|
381
|
+
const slicePath = join(gsdProjectionRoot(basePath), "milestones", milestoneId, "slices", sliceId);
|
|
382
|
+
mkdirSync(slicePath, { recursive: true });
|
|
383
|
+
const absPath = join(slicePath, `${sliceId}-PLAN.md`);
|
|
376
384
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
377
385
|
const sliceGates = getGateResults(milestoneId, sliceId, "slice");
|
|
378
386
|
const content = renderSlicePlanMarkdown(slice, tasks, sliceGates);
|
|
@@ -403,8 +411,7 @@ export async function renderTaskPlanFromDb(
|
|
|
403
411
|
throw new Error(`task ${milestoneId}/${sliceId}/${taskId} not found`);
|
|
404
412
|
}
|
|
405
413
|
|
|
406
|
-
const tasksDir =
|
|
407
|
-
?? join(gsdRoot(basePath), "milestones", milestoneId, "slices", sliceId, "tasks");
|
|
414
|
+
const tasksDir = join(gsdProjectionRoot(basePath), "milestones", milestoneId, "slices", sliceId, "tasks");
|
|
408
415
|
mkdirSync(tasksDir, { recursive: true });
|
|
409
416
|
const absPath = join(tasksDir, buildTaskFileName(taskId, "PLAN"));
|
|
410
417
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
@@ -306,7 +306,7 @@ function importRequirements(gsdDir: string): number {
|
|
|
306
306
|
// ─── Hierarchy Artifact Walker ─────────────────────────────────────────────
|
|
307
307
|
|
|
308
308
|
/** Artifact suffixes to look for at each hierarchy level */
|
|
309
|
-
const MILESTONE_SUFFIXES = ['ROADMAP', 'CONTEXT', 'RESEARCH', 'ASSESSMENT'];
|
|
309
|
+
const MILESTONE_SUFFIXES = ['ROADMAP', 'CONTEXT', 'RESEARCH', 'ASSESSMENT', 'SUMMARY', 'VALIDATION'];
|
|
310
310
|
const SLICE_SUFFIXES = ['PLAN', 'SUMMARY', 'RESEARCH', 'CONTEXT', 'ASSESSMENT', 'UAT'];
|
|
311
311
|
const TASK_SUFFIXES = ['PLAN', 'SUMMARY', 'CONTINUE', 'CONTEXT', 'RESEARCH'];
|
|
312
312
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// GSD2 — Decisions -> memories backfill (ADR-013 step 5)
|
|
2
2
|
//
|
|
3
|
-
// Idempotent
|
|
4
|
-
// the memories table with
|
|
5
|
-
//
|
|
6
|
-
//
|
|
3
|
+
// Idempotent migration that copies every decisions row (active and
|
|
4
|
+
// superseded — see Stage 2a note below) into the memories table with
|
|
5
|
+
// category="architecture" and a structured_fields payload preserving the
|
|
6
|
+
// original gsd_save_decision schema (when_context, scope, decision, choice,
|
|
7
|
+
// rationale, made_by, revisable, superseded_by, sourceDecisionId).
|
|
7
8
|
//
|
|
8
9
|
// The backfill exists so the cutover in ADR-013 step 6 can drop the
|
|
9
10
|
// decisions table without losing schema fidelity. Idempotency is enforced
|
|
@@ -14,6 +15,13 @@
|
|
|
14
15
|
// only ever fires once per project. Costs O(N) inserts on first run where
|
|
15
16
|
// N is the active-decisions count; subsequent runs are an O(N) lookup that
|
|
16
17
|
// finds existing markers and exits.
|
|
18
|
+
//
|
|
19
|
+
// ADR-013 Stage 2a (PR #5755): backfill now includes superseded rows so the
|
|
20
|
+
// DECISIONS.md projection regen can source from memories without losing
|
|
21
|
+
// historical entries. An auto-heal pass runs after the initial migration to
|
|
22
|
+
// pick up superseded_by changes that occurred after the source decision was
|
|
23
|
+
// already migrated (e.g. a fresh md-importer run that introduced a new
|
|
24
|
+
// supersedes-chain).
|
|
17
25
|
|
|
18
26
|
import { isDbAvailable, _getAdapter } from "./gsd-db.js";
|
|
19
27
|
import { createMemory } from "./memory-store.js";
|
|
@@ -31,8 +39,10 @@ interface DecisionRow {
|
|
|
31
39
|
superseded_by: string | null;
|
|
32
40
|
}
|
|
33
41
|
|
|
42
|
+
type DecisionContentFields = Pick<DecisionRow, "decision" | "choice" | "rationale">;
|
|
43
|
+
|
|
34
44
|
/**
|
|
35
|
-
* Backfill
|
|
45
|
+
* Backfill decisions rows into the memories table.
|
|
36
46
|
*
|
|
37
47
|
* - Idempotent (per-row): every row written carries
|
|
38
48
|
* `structured_fields.sourceDecisionId = "<decisionId>"`. Each candidate
|
|
@@ -41,13 +51,18 @@ interface DecisionRow {
|
|
|
41
51
|
* their own `sourceDecisionId` does NOT abort the backfill.
|
|
42
52
|
* - Best-effort: never throws. Logs and returns 0 on failure so a broken
|
|
43
53
|
* backfill cannot block agent startup.
|
|
44
|
-
* -
|
|
45
|
-
*
|
|
46
|
-
*
|
|
54
|
+
* - Full migration (ADR-013 Stage 2a): both active and superseded rows are
|
|
55
|
+
* migrated. `structured_fields.superseded_by` preserves the supersedes
|
|
56
|
+
* chain so the DECISIONS.md projection regen can source from memories
|
|
57
|
+
* without losing historical entries.
|
|
58
|
+
* - Drift auto-heal: after the initial insert pass, the function updates
|
|
59
|
+
* any pre-existing memory whose `structured_fields.superseded_by` drifted
|
|
60
|
+
* from the source decision (e.g. a fresh md-importer run introduced a
|
|
61
|
+
* new supersedes annotation after the initial migration).
|
|
47
62
|
*
|
|
48
63
|
* Returns the number of memories written (0 when already backfilled or
|
|
49
|
-
* when the DB has no decisions).
|
|
50
|
-
*
|
|
64
|
+
* when the DB has no decisions). Drift-heal updates are not counted in
|
|
65
|
+
* this return — they are logged separately.
|
|
51
66
|
*/
|
|
52
67
|
export function backfillDecisionsToMemories(): number {
|
|
53
68
|
if (!isDbAvailable()) return 0;
|
|
@@ -56,7 +71,7 @@ export function backfillDecisionsToMemories(): number {
|
|
|
56
71
|
|
|
57
72
|
try {
|
|
58
73
|
const decisions = adapter
|
|
59
|
-
.prepare("SELECT id, when_context, scope, decision, choice, rationale, made_by, revisable, superseded_by FROM decisions
|
|
74
|
+
.prepare("SELECT id, when_context, scope, decision, choice, rationale, made_by, revisable, superseded_by FROM decisions ORDER BY seq")
|
|
60
75
|
.all() as Array<Record<string, unknown>>;
|
|
61
76
|
|
|
62
77
|
if (decisions.length === 0) return 0;
|
|
@@ -67,10 +82,14 @@ export function backfillDecisionsToMemories(): number {
|
|
|
67
82
|
// sentinel would silently abort the backfill if a user manually called
|
|
68
83
|
// capture_thought with their own structuredFields.sourceDecisionId.
|
|
69
84
|
const checkExisting = adapter.prepare(
|
|
70
|
-
"SELECT
|
|
85
|
+
"SELECT id, structured_fields FROM memories WHERE structured_fields LIKE :pattern LIMIT 1",
|
|
86
|
+
);
|
|
87
|
+
const updateStructuredFields = adapter.prepare(
|
|
88
|
+
"UPDATE memories SET structured_fields = :sf, updated_at = :ts WHERE id = :id",
|
|
71
89
|
);
|
|
72
90
|
|
|
73
91
|
let written = 0;
|
|
92
|
+
let healed = 0;
|
|
74
93
|
for (const raw of decisions) {
|
|
75
94
|
const row: DecisionRow = {
|
|
76
95
|
id: String(raw["id"] ?? ""),
|
|
@@ -85,11 +104,48 @@ export function backfillDecisionsToMemories(): number {
|
|
|
85
104
|
};
|
|
86
105
|
if (!row.id) continue;
|
|
87
106
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
107
|
+
const pattern = `%"sourceDecisionId":"${row.id}"%`;
|
|
108
|
+
const existing = checkExisting.get({ ":pattern": pattern }) as
|
|
109
|
+
| { id: string; structured_fields: string | null }
|
|
110
|
+
| undefined;
|
|
91
111
|
|
|
92
|
-
|
|
112
|
+
if (existing) {
|
|
113
|
+
// Drift auto-heal: if the source decision's superseded_by has changed
|
|
114
|
+
// since the original migration, update the memory in place. Read-side
|
|
115
|
+
// queries reconstruct Decision.superseded_by from this field, so the
|
|
116
|
+
// DECISIONS.md projection stays accurate without us having to track
|
|
117
|
+
// supersedes events at the write site.
|
|
118
|
+
const parsedSf = existing.structured_fields
|
|
119
|
+
? safeParse(existing.structured_fields)
|
|
120
|
+
: {};
|
|
121
|
+
if (existing.structured_fields && !parsedSf) {
|
|
122
|
+
logWarning(
|
|
123
|
+
"memory-backfill",
|
|
124
|
+
`decisions->memories drift heal skipped for ${row.id}: invalid structured_fields JSON`,
|
|
125
|
+
);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
const currentSf = parsedSf ?? {};
|
|
129
|
+
const memorySuperseded =
|
|
130
|
+
typeof currentSf["superseded_by"] === "string" || currentSf["superseded_by"] === null
|
|
131
|
+
? (currentSf["superseded_by"] as string | null | undefined)
|
|
132
|
+
: null;
|
|
133
|
+
if (memorySuperseded !== row.superseded_by) {
|
|
134
|
+
const merged = {
|
|
135
|
+
...currentSf,
|
|
136
|
+
superseded_by: row.superseded_by,
|
|
137
|
+
};
|
|
138
|
+
updateStructuredFields.run({
|
|
139
|
+
":id": existing.id,
|
|
140
|
+
":sf": JSON.stringify(merged),
|
|
141
|
+
":ts": new Date().toISOString(),
|
|
142
|
+
});
|
|
143
|
+
healed += 1;
|
|
144
|
+
}
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const content = synthesizeDecisionMemoryContent(row);
|
|
93
149
|
const id = createMemory({
|
|
94
150
|
category: "architecture",
|
|
95
151
|
content,
|
|
@@ -104,11 +160,19 @@ export function backfillDecisionsToMemories(): number {
|
|
|
104
160
|
rationale: row.rationale,
|
|
105
161
|
made_by: row.made_by,
|
|
106
162
|
revisable: row.revisable,
|
|
163
|
+
superseded_by: row.superseded_by,
|
|
107
164
|
},
|
|
108
165
|
});
|
|
109
166
|
if (id) written += 1;
|
|
110
167
|
}
|
|
111
168
|
|
|
169
|
+
if (healed > 0) {
|
|
170
|
+
logWarning(
|
|
171
|
+
"memory-backfill",
|
|
172
|
+
`decisions->memories drift healed: ${healed} row${healed === 1 ? "" : "s"} updated superseded_by`,
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
112
176
|
return written;
|
|
113
177
|
} catch (e) {
|
|
114
178
|
logWarning("memory-backfill", `decisions->memories backfill failed: ${(e as Error).message}`);
|
|
@@ -116,6 +180,14 @@ export function backfillDecisionsToMemories(): number {
|
|
|
116
180
|
}
|
|
117
181
|
}
|
|
118
182
|
|
|
183
|
+
function safeParse(raw: string): Record<string, unknown> | null {
|
|
184
|
+
try {
|
|
185
|
+
return JSON.parse(raw) as Record<string, unknown>;
|
|
186
|
+
} catch {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
119
191
|
/**
|
|
120
192
|
* Combine the decision's structured fields into a 1-3 sentence content
|
|
121
193
|
* string suitable for keyword retrieval and human review.
|
|
@@ -124,7 +196,7 @@ export function backfillDecisionsToMemories(): number {
|
|
|
124
196
|
* Truncates each field to keep the synthesized line under ~600 chars so
|
|
125
197
|
* memory_query rendering stays readable.
|
|
126
198
|
*/
|
|
127
|
-
function
|
|
199
|
+
export function synthesizeDecisionMemoryContent(row: DecisionContentFields): string {
|
|
128
200
|
const trim = (value: string, max: number): string => {
|
|
129
201
|
const cleaned = value.replace(/\s+/g, " ").trim();
|
|
130
202
|
return cleaned.length > max ? cleaned.slice(0, max - 1) + "\u2026" : cleaned;
|