gsd-pi 2.81.0 → 2.82.0-dev.ed17d078d
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 +60 -30
- package/dist/resources/.managed-resources-content-hash +1 -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/gsd/auto/loop.js +111 -8
- package/dist/resources/extensions/gsd/auto/orchestrator.js +113 -6
- package/dist/resources/extensions/gsd/auto/phases.js +199 -97
- package/dist/resources/extensions/gsd/auto/run-unit.js +66 -3
- package/dist/resources/extensions/gsd/auto/session.js +9 -0
- package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +43 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +182 -178
- package/dist/resources/extensions/gsd/auto-dispatch.js +14 -11
- package/dist/resources/extensions/gsd/auto-post-unit.js +7 -1
- package/dist/resources/extensions/gsd/auto-prompts.js +11 -3
- package/dist/resources/extensions/gsd/auto-recovery.js +6 -181
- package/dist/resources/extensions/gsd/auto-runtime-state.js +5 -0
- package/dist/resources/extensions/gsd/auto-start.js +20 -23
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +33 -5
- package/dist/resources/extensions/gsd/auto-verification.js +12 -6
- package/dist/resources/extensions/gsd/auto-worktree.js +8 -0
- package/dist/resources/extensions/gsd/auto.js +386 -106
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +13 -6
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +13 -2
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +4 -8
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
- package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -1
- package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +4 -10
- package/dist/resources/extensions/gsd/commands/handlers/parallel.js +9 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
- package/dist/resources/extensions/gsd/context-store.js +112 -0
- package/dist/resources/extensions/gsd/db-writer.js +150 -84
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/doctor-git-checks.js +41 -6
- package/dist/resources/extensions/gsd/git-service.js +2 -1
- package/dist/resources/extensions/gsd/gsd-db.js +7 -23
- package/dist/resources/extensions/gsd/health-widget-core.js +1 -1
- package/dist/resources/extensions/gsd/health-widget.js +4 -10
- 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 +6 -96
- 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/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/native-git-bridge.js +14 -14
- package/dist/resources/extensions/gsd/notification-overlay.js +35 -40
- package/dist/resources/extensions/gsd/parallel-merge.js +53 -30
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +25 -33
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +14 -12
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +20 -2
- package/dist/resources/extensions/gsd/prompts/discuss.md +20 -2
- 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/recovery-classification.js +15 -1
- package/dist/resources/extensions/gsd/session-lock.js +40 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +131 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +247 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +50 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +87 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.js +50 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +124 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-worker.js +32 -0
- package/dist/resources/extensions/gsd/state-reconciliation/errors.js +41 -0
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +99 -0
- package/dist/resources/extensions/gsd/state-reconciliation/registry.js +24 -0
- package/dist/resources/extensions/gsd/state-reconciliation/spawn-gate.js +43 -0
- package/dist/resources/extensions/gsd/state-reconciliation/types.js +3 -0
- package/dist/resources/extensions/gsd/state-reconciliation.js +5 -26
- package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
- package/dist/resources/extensions/gsd/tui/render-kit.js +74 -0
- package/dist/resources/extensions/gsd/watch/header-renderer.js +92 -69
- package/dist/resources/extensions/gsd/watch/splash-palette.js +10 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +2 -2
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +722 -316
- package/dist/resources/extensions/gsd/worktree-telemetry.js +3 -1
- 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 +6 -6
- 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/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- 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_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 +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- 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 +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +6 -6
- package/dist/web/standalone/.next/server/chunks/63.js +3 -3
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- 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/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-752f1e2ebdaa3e45.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/dist/welcome-screen.d.ts +0 -7
- package/dist/welcome-screen.js +60 -69
- package/package.json +3 -2
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/README.md +2 -0
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/workflow-tools-parity.test.ts +244 -0
- package/packages/native/package.json +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/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/transform-messages.ts +24 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +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/__tests__/assistant-message-design.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js +47 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +76 -9
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js +40 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +0 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +30 -29
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +10 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +13 -13
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +58 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +12 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.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 +14 -41
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +0 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +86 -82
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts +35 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js +152 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts +16 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js +73 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +12 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +105 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +27 -26
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +9 -6
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.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/system-prompt.ts +4 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/assistant-message-design.test.ts +56 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +113 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/user-message-design.test.ts +48 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +10 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +43 -42
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +14 -14
- package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +64 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +13 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +15 -42
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +84 -104
- package/packages/pi-coding-agent/src/modes/interactive/components/transcript-design.ts +196 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tui-style-kit.ts +94 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +14 -9
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme-highlight.test.ts +23 -0
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +106 -1
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +27 -26
- package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +9 -6
- 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__/overlay-layout.test.js +14 -1
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
- package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -1
- package/packages/pi-tui/dist/overlay-layout.js +9 -6
- package/packages/pi-tui/dist/overlay-layout.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__/overlay-layout.test.ts +20 -1
- package/packages/pi-tui/src/overlay-layout.ts +10 -7
- 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/pkg/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
- package/pkg/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
- package/pkg/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
- package/pkg/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
- package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.js +105 -1
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js +27 -26
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/pkg/package.json +1 -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/gsd/auto/contracts.ts +46 -11
- package/src/resources/extensions/gsd/auto/loop-deps.ts +9 -5
- package/src/resources/extensions/gsd/auto/loop.ts +113 -9
- package/src/resources/extensions/gsd/auto/orchestrator.ts +118 -6
- package/src/resources/extensions/gsd/auto/phases.ts +158 -19
- package/src/resources/extensions/gsd/auto/run-unit.ts +69 -4
- package/src/resources/extensions/gsd/auto/session.ts +10 -0
- package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +82 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +230 -183
- package/src/resources/extensions/gsd/auto-dispatch.ts +15 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +7 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +11 -3
- package/src/resources/extensions/gsd/auto-recovery.ts +7 -209
- package/src/resources/extensions/gsd/auto-runtime-state.ts +5 -0
- package/src/resources/extensions/gsd/auto-start.ts +22 -22
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +51 -0
- package/src/resources/extensions/gsd/auto-verification.ts +12 -6
- package/src/resources/extensions/gsd/auto-worktree.ts +8 -0
- package/src/resources/extensions/gsd/auto.ts +424 -106
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +21 -6
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +12 -2
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +5 -8
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
- package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -1
- package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +4 -10
- package/src/resources/extensions/gsd/commands/handlers/parallel.ts +12 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
- package/src/resources/extensions/gsd/context-store.ts +120 -1
- package/src/resources/extensions/gsd/db-writer.ts +167 -84
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/doctor-git-checks.ts +44 -6
- package/src/resources/extensions/gsd/doctor-types.ts +2 -0
- package/src/resources/extensions/gsd/git-service.ts +2 -0
- package/src/resources/extensions/gsd/gsd-db.ts +7 -23
- package/src/resources/extensions/gsd/health-widget-core.ts +1 -1
- package/src/resources/extensions/gsd/health-widget.ts +6 -10
- package/src/resources/extensions/gsd/journal.ts +2 -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 +10 -96
- 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/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/native-git-bridge.ts +14 -13
- package/src/resources/extensions/gsd/notification-overlay.ts +50 -46
- package/src/resources/extensions/gsd/parallel-merge.ts +61 -34
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +33 -35
- package/src/resources/extensions/gsd/prompts/complete-slice.md +14 -12
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +20 -2
- package/src/resources/extensions/gsd/prompts/discuss.md +20 -2
- 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/recovery-classification.ts +18 -1
- package/src/resources/extensions/gsd/session-lock.ts +41 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +172 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +337 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +69 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +109 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.ts +68 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +185 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-worker.ts +46 -0
- package/src/resources/extensions/gsd/state-reconciliation/errors.ts +67 -0
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +142 -0
- package/src/resources/extensions/gsd/state-reconciliation/registry.ts +27 -0
- package/src/resources/extensions/gsd/state-reconciliation/spawn-gate.ts +60 -0
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +83 -0
- package/src/resources/extensions/gsd/state-reconciliation.ts +21 -53
- package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +729 -176
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +408 -4
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +291 -4
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +20 -5
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +28 -1
- 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 +20 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
- package/src/resources/extensions/gsd/tests/header-renderer.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +14 -4
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
- package/src/resources/extensions/gsd/tests/integration/integration-proof.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +116 -24
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -1
- 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/markdown-renderer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +46 -11
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +78 -41
- package/src/resources/extensions/gsd/tests/notifications-handler.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +12 -217
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +38 -6
- package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
- package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +6 -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 +24 -0
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +65 -58
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +952 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +83 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +158 -58
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +572 -118
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +59 -2
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +18 -0
- package/src/resources/extensions/gsd/tui/render-kit.ts +109 -0
- package/src/resources/extensions/gsd/watch/header-renderer.ts +121 -79
- package/src/resources/extensions/gsd/watch/splash-palette.ts +11 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +2 -2
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +1151 -524
- package/src/resources/extensions/gsd/worktree-telemetry.ts +7 -2
- package/dist/web/standalone/.next/static/chunks/app/page-200592a7f3baf579.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +0 -1544
- /package/dist/web/standalone/.next/static/{drLMkgfHQ8lzS229_HWYR → YEvjuT-fsFfYQhDSWtueS}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{drLMkgfHQ8lzS229_HWYR → YEvjuT-fsFfYQhDSWtueS}/_ssgManifest.js +0 -0
|
@@ -235,14 +235,63 @@ export async function nextDecisionId(): Promise<string> {
|
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
/**
|
|
239
|
-
|
|
238
|
+
/**
|
|
239
|
+
* ADR-013 Stage 3: compute the next `D###` identifier across both the legacy
|
|
240
|
+
* `decisions` table AND the `memories.structured_fields.sourceDecisionId`
|
|
241
|
+
* surface. Returns the max numeric suffix from either side + 1, three-digit
|
|
242
|
+
* padded.
|
|
243
|
+
*
|
|
244
|
+
* Used by `saveDecisionToDb` once writes to the `decisions` table stop —
|
|
245
|
+
* new decisions live only in memories, but historical IDs sit in both
|
|
246
|
+
* places during the cutover bake. The cross-surface max keeps IDs
|
|
247
|
+
* monotonic and avoids collisions on the next save.
|
|
248
|
+
*/
|
|
249
|
+
function nextDecisionIdAcrossSurfaces(
|
|
250
|
+
adapter: ReturnType<typeof import('./gsd-db.js')._getAdapter>,
|
|
251
|
+
): string {
|
|
240
252
|
if (!adapter) return 'D001';
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
253
|
+
|
|
254
|
+
let maxNum = 0;
|
|
255
|
+
|
|
256
|
+
// Legacy table — best-effort.
|
|
257
|
+
try {
|
|
258
|
+
const row = adapter
|
|
259
|
+
.prepare('SELECT MAX(CAST(SUBSTR(id, 2) AS INTEGER)) as max_num FROM decisions')
|
|
260
|
+
.get();
|
|
261
|
+
const candidate = row ? (row['max_num'] as number | null) : null;
|
|
262
|
+
if (typeof candidate === 'number' && Number.isFinite(candidate)) {
|
|
263
|
+
maxNum = Math.max(maxNum, candidate);
|
|
264
|
+
}
|
|
265
|
+
} catch {
|
|
266
|
+
// fall through to memory-only
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Memory surface: scan structuredFields.sourceDecisionId for D### values.
|
|
270
|
+
// SQLite LIKE on the JSON-stringified field is sufficient — rows tagged
|
|
271
|
+
// with sourceDecisionId are bounded by the decisions count.
|
|
272
|
+
try {
|
|
273
|
+
const rows = adapter
|
|
274
|
+
.prepare(
|
|
275
|
+
"SELECT structured_fields FROM memories WHERE structured_fields LIKE '%\"sourceDecisionId\":\"D%'",
|
|
276
|
+
)
|
|
277
|
+
.all() as Array<{ structured_fields: string | null }>;
|
|
278
|
+
for (const row of rows) {
|
|
279
|
+
if (!row.structured_fields) continue;
|
|
280
|
+
let sf: Record<string, unknown>;
|
|
281
|
+
try {
|
|
282
|
+
sf = JSON.parse(row.structured_fields) as Record<string, unknown>;
|
|
283
|
+
} catch {
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
const sourceId = sf['sourceDecisionId'];
|
|
287
|
+
if (typeof sourceId !== 'string' || !sourceId.startsWith('D')) continue;
|
|
288
|
+
const num = parseInt(sourceId.slice(1), 10);
|
|
289
|
+
if (Number.isFinite(num) && num > maxNum) maxNum = num;
|
|
290
|
+
}
|
|
291
|
+
} catch {
|
|
292
|
+
// best-effort
|
|
293
|
+
}
|
|
294
|
+
|
|
246
295
|
const next = maxNum + 1;
|
|
247
296
|
return `D${String(next).padStart(3, '0')}`;
|
|
248
297
|
}
|
|
@@ -416,6 +465,16 @@ export interface SaveDecisionFields {
|
|
|
416
465
|
source?: string;
|
|
417
466
|
}
|
|
418
467
|
|
|
468
|
+
type NormalizedSaveDecisionFields = Omit<
|
|
469
|
+
SaveDecisionFields,
|
|
470
|
+
'when_context' | 'revisable' | 'made_by' | 'source'
|
|
471
|
+
> & {
|
|
472
|
+
when_context: string;
|
|
473
|
+
revisable: string;
|
|
474
|
+
made_by: NonNullable<SaveDecisionFields['made_by']>;
|
|
475
|
+
source: string;
|
|
476
|
+
};
|
|
477
|
+
|
|
419
478
|
/**
|
|
420
479
|
* Save a new decision to DB and regenerate DECISIONS.md.
|
|
421
480
|
* Auto-assigns the next ID via nextDecisionId().
|
|
@@ -445,44 +504,59 @@ export async function saveDecisionToDb(
|
|
|
445
504
|
|
|
446
505
|
try {
|
|
447
506
|
const db = await import('./gsd-db.js');
|
|
448
|
-
|
|
449
507
|
const adapter = db._getAdapter();
|
|
508
|
+
const normalized: NormalizedSaveDecisionFields = {
|
|
509
|
+
...fields,
|
|
510
|
+
when_context: fields.when_context ?? '',
|
|
511
|
+
revisable: fields.revisable ?? 'Yes',
|
|
512
|
+
made_by: fields.made_by ?? 'agent',
|
|
513
|
+
source: fields.source ?? 'discussion',
|
|
514
|
+
};
|
|
450
515
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
516
|
+
// ADR-013 Stage 3 (destructive): writes to the `decisions` table stop
|
|
517
|
+
// here. New decisions live only in the `memories` table; the projection
|
|
518
|
+
// regen below sources from memories (Stage 2a). The decisions table
|
|
519
|
+
// remains for backwards-compat reads (queryDecisions, md-importer,
|
|
520
|
+
// commands-inspect, workflow-manifest) until #5756 drops it.
|
|
521
|
+
//
|
|
522
|
+
// Reversal: a code revert of this change restores the upsertDecision
|
|
523
|
+
// call. Memory rows written between merge and revert stay durable; the
|
|
524
|
+
// legacy table simply doesn't grow during the cutover window.
|
|
525
|
+
const id = nextDecisionIdAcrossSurfaces(adapter);
|
|
526
|
+
|
|
527
|
+
// The mirror-to-memories write is what persists the new decision. Must
|
|
528
|
+
// run before the projection regen — the regen sources from memories
|
|
529
|
+
// (Stage 2a) and would otherwise miss the just-saved decision. Pass
|
|
530
|
+
// the normalized field set so defaults (revisable, made_by, source)
|
|
531
|
+
// are recorded on the memory row.
|
|
532
|
+
await mirrorDecisionToMemory(id, normalized);
|
|
533
|
+
|
|
534
|
+
// Fetch all decisions (including superseded for the full register).
|
|
535
|
+
// ADR-013 Stage 2a: source from the `memories` table. The Phase 5
|
|
536
|
+
// dual-write keeps memories in sync with each decision save; the backfill
|
|
537
|
+
// (memory-backfill.ts) absorbs the historical chain and drift-heals
|
|
538
|
+
// superseded_by on every session start.
|
|
539
|
+
const { getAllDecisionsFromMemories } = await import('./context-store.js');
|
|
540
|
+
let allDecisions: Decision[] = getAllDecisionsFromMemories();
|
|
541
|
+
if (!allDecisions.some(d => d.id === id)) {
|
|
542
|
+
logWarning('projection', 'just-saved decision missing from memories after mirror; injecting fallback for projection', {
|
|
543
|
+
fn: 'saveDecisionToDb',
|
|
544
|
+
decisionId: id,
|
|
464
545
|
});
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
decision: row['decision'] as string,
|
|
480
|
-
choice: row['choice'] as string,
|
|
481
|
-
rationale: row['rationale'] as string,
|
|
482
|
-
revisable: row['revisable'] as string,
|
|
483
|
-
made_by: (row['made_by'] as string as import('./types.js').DecisionMadeBy) ?? 'agent',
|
|
484
|
-
superseded_by: (row['superseded_by'] as string) ?? null,
|
|
485
|
-
}));
|
|
546
|
+
const nextSeq = allDecisions.reduce((max, d) => Math.max(max, d.seq ?? 0), 0) + 1;
|
|
547
|
+
const fallback: Decision = {
|
|
548
|
+
seq: nextSeq,
|
|
549
|
+
id,
|
|
550
|
+
when_context: normalized.when_context,
|
|
551
|
+
scope: normalized.scope,
|
|
552
|
+
decision: normalized.decision,
|
|
553
|
+
choice: normalized.choice,
|
|
554
|
+
rationale: normalized.rationale,
|
|
555
|
+
revisable: normalized.revisable,
|
|
556
|
+
made_by: normalized.made_by,
|
|
557
|
+
superseded_by: null,
|
|
558
|
+
};
|
|
559
|
+
allDecisions = [...allDecisions, fallback];
|
|
486
560
|
}
|
|
487
561
|
|
|
488
562
|
const filePath = resolveGsdRootFile(basePath, 'DECISIONS');
|
|
@@ -538,48 +612,6 @@ export async function saveDecisionToDb(
|
|
|
538
612
|
clearPathCache();
|
|
539
613
|
clearParseCache();
|
|
540
614
|
|
|
541
|
-
// ADR-013 dual-write: keep the memory store in sync with every decision
|
|
542
|
-
// persisted via the legacy gsd_save_decision path. Without this, prompts
|
|
543
|
-
// that still call gsd_save_decision (discuss.md, plan-milestone.md,
|
|
544
|
-
// plan-slice.md, et al.) would create decisions rows invisible to
|
|
545
|
-
// memory_query and loadMemoryBlock.
|
|
546
|
-
// Best-effort — never throw, never roll back the decision on failure.
|
|
547
|
-
try {
|
|
548
|
-
const { createMemory } = await import('./memory-store.js');
|
|
549
|
-
const decisionText = (fields.decision ?? '').trim();
|
|
550
|
-
const choiceText = (fields.choice ?? '').trim();
|
|
551
|
-
const rationaleText = (fields.rationale ?? '').trim();
|
|
552
|
-
const contentParts: string[] = [];
|
|
553
|
-
if (decisionText) contentParts.push(decisionText);
|
|
554
|
-
if (choiceText) contentParts.push(`Chose: ${choiceText}.`);
|
|
555
|
-
if (rationaleText) contentParts.push(`Rationale: ${rationaleText}.`);
|
|
556
|
-
const content = contentParts.join(' ').slice(0, 600);
|
|
557
|
-
if (content) {
|
|
558
|
-
createMemory({
|
|
559
|
-
category: 'architecture',
|
|
560
|
-
content,
|
|
561
|
-
scope: fields.scope || 'project',
|
|
562
|
-
confidence: 0.85,
|
|
563
|
-
structuredFields: {
|
|
564
|
-
sourceDecisionId: id,
|
|
565
|
-
when_context: fields.when_context ?? '',
|
|
566
|
-
scope: fields.scope,
|
|
567
|
-
decision: fields.decision,
|
|
568
|
-
choice: fields.choice,
|
|
569
|
-
rationale: fields.rationale,
|
|
570
|
-
made_by: fields.made_by ?? 'agent',
|
|
571
|
-
revisable: fields.revisable ?? '',
|
|
572
|
-
},
|
|
573
|
-
});
|
|
574
|
-
}
|
|
575
|
-
} catch (mirrorErr) {
|
|
576
|
-
logError('manifest', 'memory-store mirror write failed (non-fatal)', {
|
|
577
|
-
fn: 'saveDecisionToDb',
|
|
578
|
-
decisionId: id,
|
|
579
|
-
error: String((mirrorErr as Error).message),
|
|
580
|
-
});
|
|
581
|
-
}
|
|
582
|
-
|
|
583
615
|
return { id };
|
|
584
616
|
} catch (err) {
|
|
585
617
|
logError('manifest', 'saveDecisionToDb failed', { fn: 'saveDecisionToDb', error: String((err as Error).message) });
|
|
@@ -589,6 +621,57 @@ export async function saveDecisionToDb(
|
|
|
589
621
|
}
|
|
590
622
|
}
|
|
591
623
|
|
|
624
|
+
/**
|
|
625
|
+
* ADR-013 dual-write — mirror a freshly-saved decision into the `memories`
|
|
626
|
+
* table so the memory store remains the single source of truth for the
|
|
627
|
+
* DECISIONS.md projection (Stage 2a) and for prompt-inline reads (Stage 1).
|
|
628
|
+
*
|
|
629
|
+
* Best-effort mirror: logs failures without throwing to avoid blocking saves.
|
|
630
|
+
* Caller invokes this AFTER the decisions-table write completes and
|
|
631
|
+
* BEFORE the projection regen — the regen sources from memories and would
|
|
632
|
+
* otherwise miss the just-saved decision.
|
|
633
|
+
*/
|
|
634
|
+
async function mirrorDecisionToMemory(
|
|
635
|
+
id: string,
|
|
636
|
+
normalizedFields: NormalizedSaveDecisionFields,
|
|
637
|
+
): Promise<boolean> {
|
|
638
|
+
try {
|
|
639
|
+
const { createMemory } = await import('./memory-store.js');
|
|
640
|
+
const { synthesizeDecisionMemoryContent } = await import('./memory-backfill.js');
|
|
641
|
+
const content = synthesizeDecisionMemoryContent(normalizedFields);
|
|
642
|
+
if (!content) return false;
|
|
643
|
+
|
|
644
|
+
createMemory({
|
|
645
|
+
category: 'architecture',
|
|
646
|
+
content,
|
|
647
|
+
scope: normalizedFields.scope || 'project',
|
|
648
|
+
confidence: 0.85,
|
|
649
|
+
structuredFields: {
|
|
650
|
+
sourceDecisionId: id,
|
|
651
|
+
when_context: normalizedFields.when_context,
|
|
652
|
+
scope: normalizedFields.scope,
|
|
653
|
+
decision: normalizedFields.decision,
|
|
654
|
+
choice: normalizedFields.choice,
|
|
655
|
+
rationale: normalizedFields.rationale,
|
|
656
|
+
made_by: normalizedFields.made_by,
|
|
657
|
+
revisable: normalizedFields.revisable,
|
|
658
|
+
// New decisions are always written as active; md-importer can later
|
|
659
|
+
// set superseded_by on the source decision row, and the backfill's
|
|
660
|
+
// drift auto-heal pass propagates that update to this memory.
|
|
661
|
+
superseded_by: null,
|
|
662
|
+
},
|
|
663
|
+
});
|
|
664
|
+
return true;
|
|
665
|
+
} catch (mirrorErr) {
|
|
666
|
+
logError('manifest', 'memory-store mirror write failed', {
|
|
667
|
+
fn: 'saveDecisionToDb',
|
|
668
|
+
decisionId: id,
|
|
669
|
+
error: String((mirrorErr as Error).message),
|
|
670
|
+
});
|
|
671
|
+
return false;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
|
|
592
675
|
/**
|
|
593
676
|
* Extract a milestone/slice reference from a deferral decision.
|
|
594
677
|
*
|
|
@@ -100,7 +100,7 @@ Setting `prefer_skills: []` does **not** disable skill discovery — it just mea
|
|
|
100
100
|
|
|
101
101
|
- `skill_rules`: situational rules with a human-readable `when` trigger and one or more of `use`, `prefer`, or `avoid`.
|
|
102
102
|
|
|
103
|
-
- `custom_instructions`: extra durable instructions related to skill use. For operational project knowledge
|
|
103
|
+
- `custom_instructions`: extra durable instructions related to skill use. For operational project knowledge, use `.gsd/KNOWLEDGE.md` instead. Rules are file-canonical; patterns and lessons are persisted to the `memories` table and projected back into `KNOWLEDGE.md` on the next session start.
|
|
104
104
|
|
|
105
105
|
- `language`: preferred response language for all GSD interactions. Accepts any language name or code — `"Chinese"`, `"zh"`, `"German"`, `"de"`, `"日本語"`, etc. When set, GSD injects "Always respond in \<language\>" into every agent's system prompt, including after `/clear`. Quickest way to set it: `/gsd language <name>`. To clear: `/gsd language off`.
|
|
106
106
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// GSD-2 doctor git health checks
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
1
3
|
import { existsSync, readdirSync, realpathSync, rmSync, statSync } from "node:fs";
|
|
2
4
|
import { join, sep } from "node:path";
|
|
3
5
|
|
|
@@ -52,6 +54,26 @@ function isSameOrNestedPath(candidate: string, container: string): boolean {
|
|
|
52
54
|
normalizedCandidate.startsWith(`${normalizedContainer}/`);
|
|
53
55
|
}
|
|
54
56
|
|
|
57
|
+
function getSnapshotDiffCheckFailure(basePath: string): string | null {
|
|
58
|
+
const failures: string[] = [];
|
|
59
|
+
|
|
60
|
+
for (const args of [["--cached"], []]) {
|
|
61
|
+
const result = spawnSync("git", ["diff", "--check", ...args], {
|
|
62
|
+
cwd: basePath,
|
|
63
|
+
encoding: "utf-8",
|
|
64
|
+
});
|
|
65
|
+
if (result.status === 0) continue;
|
|
66
|
+
|
|
67
|
+
const output = [result.stdout, result.stderr, result.error?.message]
|
|
68
|
+
.filter(Boolean)
|
|
69
|
+
.join("\n")
|
|
70
|
+
.trim();
|
|
71
|
+
failures.push(output || `git diff --check ${args.join(" ")} failed`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return failures.length > 0 ? failures.join("\n") : null;
|
|
75
|
+
}
|
|
76
|
+
|
|
55
77
|
async function isCompletedMilestoneTerminal(basePath: string, milestoneId: string): Promise<boolean> {
|
|
56
78
|
const summaryPath = resolveMilestoneFile(basePath, milestoneId, "SUMMARY");
|
|
57
79
|
if (!summaryPath) return false;
|
|
@@ -411,15 +433,31 @@ export async function checkGitHealth(
|
|
|
411
433
|
fixable: true,
|
|
412
434
|
});
|
|
413
435
|
|
|
436
|
+
const diffCheckFailure = getSnapshotDiffCheckFailure(basePath);
|
|
437
|
+
if (diffCheckFailure) {
|
|
438
|
+
issues.push({
|
|
439
|
+
severity: "error",
|
|
440
|
+
code: "conflict_markers_in_tracked_files",
|
|
441
|
+
scope: "project",
|
|
442
|
+
unitId: "project",
|
|
443
|
+
message: `Cannot create gsd snapshot: tracked changes contain conflict markers or whitespace errors. Resolve conflicts manually before auto-mode can proceed.\n${diffCheckFailure}`,
|
|
444
|
+
fixable: false,
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
|
|
414
448
|
if (shouldFix("stale_uncommitted_changes")) {
|
|
415
449
|
try {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
const result = nativeCommit(basePath, commitMsg);
|
|
419
|
-
if (result) {
|
|
420
|
-
fixesApplied.push(`created gsd snapshot after ${mins}m of uncommitted changes`);
|
|
450
|
+
if (diffCheckFailure) {
|
|
451
|
+
fixesApplied.push("gsd snapshot skipped - conflict markers detected in tracked files");
|
|
421
452
|
} else {
|
|
422
|
-
|
|
453
|
+
nativeAddTracked(basePath);
|
|
454
|
+
const commitMsg = `gsd snapshot: uncommitted changes after ${mins}m inactivity`;
|
|
455
|
+
const result = nativeCommit(basePath, commitMsg);
|
|
456
|
+
if (result) {
|
|
457
|
+
fixesApplied.push(`created gsd snapshot after ${mins}m of uncommitted changes`);
|
|
458
|
+
} else {
|
|
459
|
+
fixesApplied.push("gsd snapshot skipped — nothing to commit after staging tracked files");
|
|
460
|
+
}
|
|
423
461
|
}
|
|
424
462
|
} catch {
|
|
425
463
|
fixesApplied.push("failed to create gsd snapshot commit");
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// GSD-2 doctor report types
|
|
1
2
|
export type DoctorSeverity = "info" | "warning" | "error";
|
|
2
3
|
export type DoctorIssueCode =
|
|
3
4
|
| "invalid_preferences"
|
|
@@ -65,6 +66,7 @@ export type DoctorIssueCode =
|
|
|
65
66
|
| "worktree_unpushed"
|
|
66
67
|
// Stale commit safety check
|
|
67
68
|
| "stale_uncommitted_changes"
|
|
69
|
+
| "conflict_markers_in_tracked_files"
|
|
68
70
|
// Snapshot ref bloat
|
|
69
71
|
| "snapshot_ref_bloat"
|
|
70
72
|
// Runtime data integrity
|
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
nativeAddPaths,
|
|
38
38
|
nativeResetSoft,
|
|
39
39
|
nativeCommitSubject,
|
|
40
|
+
nativeIsIgnored,
|
|
40
41
|
_resetHasChangesCache,
|
|
41
42
|
} from "./native-git-bridge.js";
|
|
42
43
|
import { GSDError, GSD_MERGE_CONFLICT, GSD_GIT_ERROR } from "./errors.js";
|
|
@@ -760,6 +761,7 @@ export class GitServiceImpl {
|
|
|
760
761
|
const normalized = keyFiles
|
|
761
762
|
.map(file => normalizeRepoRelativePath(this.basePath, file))
|
|
762
763
|
.filter((file): file is string => file !== null)
|
|
764
|
+
.filter(file => !nativeIsIgnored(this.basePath, file))
|
|
763
765
|
.filter(file => !isExcludedScopedPath(file, allExclusions));
|
|
764
766
|
|
|
765
767
|
// Drop entries that don't exist on disk. The LLM occasionally lists files
|
|
@@ -1136,33 +1136,17 @@ export function setSliceSketchFlag(milestoneId: string, sliceId: string, isSketc
|
|
|
1136
1136
|
}
|
|
1137
1137
|
|
|
1138
1138
|
/**
|
|
1139
|
-
* ADR-
|
|
1140
|
-
*
|
|
1141
|
-
*
|
|
1142
|
-
*
|
|
1143
|
-
* to keep path logic in one place — do not hand-roll the path inside the callback.
|
|
1144
|
-
*
|
|
1145
|
-
* Recovers from two scenarios:
|
|
1146
|
-
* 1. Crash between `gsd_plan_slice` write and the sketch flag flip.
|
|
1147
|
-
* 2. Flag-OFF downgrade path: when `progressive_planning` is off, the dispatch
|
|
1148
|
-
* rule routes sketch slices to plan-slice, which writes PLAN.md but leaves
|
|
1149
|
-
* `is_sketch=1` — the next state derivation auto-heals it to 0 here.
|
|
1150
|
-
*
|
|
1151
|
-
* Not aggressive in practice: PLAN.md is only written via the DB-backed
|
|
1152
|
-
* `gsd_plan_slice` tool (which also inserts tasks), so a "stale PLAN.md with
|
|
1153
|
-
* is_sketch=1" is extremely unlikely to indicate anything other than the two
|
|
1154
|
-
* recovery scenarios above.
|
|
1139
|
+
* ADR-017 raw primitive: returns slice IDs in a milestone whose is_sketch flag
|
|
1140
|
+
* is still 1. The stale-sketch-flag drift handler at
|
|
1141
|
+
* `state-reconciliation/drift/sketch-flag.ts` composes this with PLAN.md
|
|
1142
|
+
* existence checks to detect drift, then writes via `setSliceSketchFlag`.
|
|
1155
1143
|
*/
|
|
1156
|
-
export function
|
|
1157
|
-
if (!currentDb) return;
|
|
1144
|
+
export function getSketchedSliceIds(milestoneId: string): string[] {
|
|
1145
|
+
if (!currentDb) return [];
|
|
1158
1146
|
const rows = currentDb.prepare(
|
|
1159
1147
|
`SELECT id FROM slices WHERE milestone_id = :mid AND is_sketch = 1`,
|
|
1160
1148
|
).all({ ":mid": milestoneId }) as Array<{ id: string }>;
|
|
1161
|
-
|
|
1162
|
-
if (hasPlanFile(row.id)) {
|
|
1163
|
-
setSliceSketchFlag(milestoneId, row.id, false);
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
1149
|
+
return rows.map((r) => r.id);
|
|
1166
1150
|
}
|
|
1167
1151
|
|
|
1168
1152
|
export function upsertSlicePlanning(milestoneId: string, sliceId: string, planning: Partial<SlicePlanningRecord>): void {
|
|
@@ -70,7 +70,7 @@ export function buildHealthLines(data: HealthWidgetData, width?: number): string
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
if (data.projectState === "initialized") {
|
|
73
|
-
return [" GSD Project
|
|
73
|
+
return [" GSD Project Initialized"];
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
const leftParts: string[] = [];
|
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* Shows a compact 1-2 line summary: progress score, budget, provider key
|
|
5
|
-
* status, and doctor/environment issue count. Refreshes every 60 seconds.
|
|
6
|
-
* Quiet when everything is healthy; turns amber/red when issues arise.
|
|
7
|
-
*
|
|
8
|
-
* Widget key: "gsd-health", placement: "belowEditor"
|
|
9
|
-
*/
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Always-on ambient health signal rendered below the editor.
|
|
10
3
|
|
|
11
4
|
import type { ExtensionContext } from "@gsd/pi-coding-agent";
|
|
12
5
|
import type { GSDState } from "./types.js";
|
|
@@ -24,6 +17,9 @@ import {
|
|
|
24
17
|
type HealthWidgetData,
|
|
25
18
|
} from "./health-widget-core.js";
|
|
26
19
|
|
|
20
|
+
export const HEALTH_WIDGET_ACTIVE_HINTS =
|
|
21
|
+
" /gsd auto to run · /gsd status for overview · /gsd visualize to inspect · /gsd notifications for history · /gsd help";
|
|
22
|
+
|
|
27
23
|
// ── Data loader ────────────────────────────────────────────────────────────────
|
|
28
24
|
|
|
29
25
|
function loadHealthWidgetData(basePath: string): HealthWidgetData {
|
|
@@ -136,7 +132,7 @@ export function initHealthWidget(ctx: ExtensionContext): void {
|
|
|
136
132
|
if (!cachedLines || cachedWidth !== width) {
|
|
137
133
|
cachedLines = buildHealthLines(data, width);
|
|
138
134
|
if (data.projectState === "active") {
|
|
139
|
-
cachedLines = [...cachedLines, _theme.fg("dim",
|
|
135
|
+
cachedLines = [...cachedLines, _theme.fg("dim", HEALTH_WIDGET_ACTIVE_HINTS)];
|
|
140
136
|
}
|
|
141
137
|
cachedWidth = width;
|
|
142
138
|
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// GSD2 — KNOWLEDGE.md -> memories backfill (ADR-013 Stage 2b).
|
|
2
|
+
//
|
|
3
|
+
// Idempotent migration of `.gsd/KNOWLEDGE.md` Patterns and Lessons rows into
|
|
4
|
+
// the `memories` table. Patterns become memories with `category: "pattern"`;
|
|
5
|
+
// Lessons become memories with `category: "gotcha"` (mirroring the ADR-013
|
|
6
|
+
// line 38 contract). Rules (K###) are NOT migrated — they remain manually
|
|
7
|
+
// maintained in `KNOWLEDGE.md` per ADR-013 line 39.
|
|
8
|
+
//
|
|
9
|
+
// Idempotency is enforced by tagging each backfilled memory with
|
|
10
|
+
// `structured_fields.sourceKnowledgeId = "<P|L>NNN"`. The
|
|
11
|
+
// memory-consolidation-scanner (PR #5765) checks for the same marker.
|
|
12
|
+
//
|
|
13
|
+
// Triggered opportunistically by `buildBeforeAgentStartResult` so the cost
|
|
14
|
+
// only ever fires once per project. Costs O(N) inserts on first run where N
|
|
15
|
+
// is the row count; subsequent runs are an O(N) lookup that finds existing
|
|
16
|
+
// markers and exits.
|
|
17
|
+
|
|
18
|
+
import { _getAdapter, isDbAvailable } from "./gsd-db.js";
|
|
19
|
+
import { createMemory } from "./memory-store.js";
|
|
20
|
+
import { parseKnowledgeRows, readKnowledgeMd, type KnowledgeRow } from "./knowledge-parser.js";
|
|
21
|
+
import { logWarning } from "./workflow-logger.js";
|
|
22
|
+
|
|
23
|
+
interface SynthesizedRow {
|
|
24
|
+
table: "patterns" | "lessons";
|
|
25
|
+
id: string;
|
|
26
|
+
category: "pattern" | "gotcha";
|
|
27
|
+
content: string;
|
|
28
|
+
scope: string;
|
|
29
|
+
structuredFields: Record<string, unknown>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Backfill KNOWLEDGE.md Patterns + Lessons rows into the memories table.
|
|
34
|
+
*
|
|
35
|
+
* - Idempotent (per-row): each migrated memory carries
|
|
36
|
+
* `structured_fields.sourceKnowledgeId = "<P|L>NNN"`. Rows whose ID is
|
|
37
|
+
* already present in the memory store are skipped.
|
|
38
|
+
* - Best-effort: never throws. Logs and returns 0 on failure so a broken
|
|
39
|
+
* backfill cannot block agent startup.
|
|
40
|
+
* - Rules (K###) are intentionally skipped — they remain manually maintained
|
|
41
|
+
* in `KNOWLEDGE.md` per ADR-013.
|
|
42
|
+
*
|
|
43
|
+
* Returns the number of memories written (0 when there's nothing to migrate
|
|
44
|
+
* or when the file is absent).
|
|
45
|
+
*/
|
|
46
|
+
export function backfillKnowledgeToMemories(basePath: string): number {
|
|
47
|
+
if (!isDbAvailable()) return 0;
|
|
48
|
+
const adapter = _getAdapter();
|
|
49
|
+
if (!adapter) return 0;
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
const content = readKnowledgeMd(basePath);
|
|
53
|
+
if (!content.trim()) return 0;
|
|
54
|
+
|
|
55
|
+
const rows = parseKnowledgeRows(content);
|
|
56
|
+
if (rows.length === 0) return 0;
|
|
57
|
+
|
|
58
|
+
const checkExisting = adapter.prepare(
|
|
59
|
+
"SELECT 1 FROM memories WHERE structured_fields LIKE :pattern LIMIT 1",
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
let written = 0;
|
|
63
|
+
for (const row of rows) {
|
|
64
|
+
const synth = synthesize(row);
|
|
65
|
+
if (!synth) continue;
|
|
66
|
+
|
|
67
|
+
// Pattern is anchored on both sides of the value to avoid prefix
|
|
68
|
+
// collisions (e.g. P1 vs P10).
|
|
69
|
+
const matchPattern = `%"sourceKnowledgeId":"${synth.id}"%`;
|
|
70
|
+
if (checkExisting.get({ ":pattern": matchPattern })) continue;
|
|
71
|
+
|
|
72
|
+
const id = createMemory({
|
|
73
|
+
category: synth.category,
|
|
74
|
+
content: synth.content,
|
|
75
|
+
scope: synth.scope,
|
|
76
|
+
confidence: 0.85,
|
|
77
|
+
structuredFields: synth.structuredFields,
|
|
78
|
+
});
|
|
79
|
+
if (id) written += 1;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return written;
|
|
83
|
+
} catch (e) {
|
|
84
|
+
logWarning(
|
|
85
|
+
"memory-backfill",
|
|
86
|
+
`KNOWLEDGE.md -> memories backfill failed: ${(e as Error).message}`,
|
|
87
|
+
);
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Convert a parsed KNOWLEDGE.md row into the memory payload we insert.
|
|
94
|
+
* Returns `null` for Rules (K###) which are not migrated, or for rows whose
|
|
95
|
+
* primary content cell is empty (defensive against malformed manual edits).
|
|
96
|
+
*/
|
|
97
|
+
function synthesize(row: KnowledgeRow): SynthesizedRow | null {
|
|
98
|
+
if (row.table === "rules") return null;
|
|
99
|
+
|
|
100
|
+
if (row.table === "patterns") {
|
|
101
|
+
// Cells: [P###, Pattern, Where, Notes]
|
|
102
|
+
const [, pattern, where, notes] = row.cells;
|
|
103
|
+
const cleaned = (pattern ?? "").trim();
|
|
104
|
+
if (!cleaned) return null;
|
|
105
|
+
|
|
106
|
+
const contentParts: string[] = [cleaned];
|
|
107
|
+
if (where && where.trim() && where.trim() !== "—") {
|
|
108
|
+
contentParts.push(`Where: ${where.trim()}.`);
|
|
109
|
+
}
|
|
110
|
+
if (notes && notes.trim() && notes.trim() !== "—") {
|
|
111
|
+
contentParts.push(`Notes: ${notes.trim()}.`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
table: "patterns",
|
|
116
|
+
id: row.id,
|
|
117
|
+
category: "pattern",
|
|
118
|
+
content: trim(contentParts.join(" "), 600),
|
|
119
|
+
scope: (where ?? "").trim() || "project",
|
|
120
|
+
structuredFields: {
|
|
121
|
+
sourceKnowledgeId: row.id,
|
|
122
|
+
sourceKnowledgeTable: "patterns",
|
|
123
|
+
pattern: cleaned,
|
|
124
|
+
where: (where ?? "").trim(),
|
|
125
|
+
notes: (notes ?? "").trim(),
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// table === "lessons"
|
|
131
|
+
// Cells: [L###, What Happened, Root Cause, Fix, Scope]
|
|
132
|
+
const [, whatHappened, rootCause, fix, scope] = row.cells;
|
|
133
|
+
const cleanedWhat = (whatHappened ?? "").trim();
|
|
134
|
+
if (!cleanedWhat) return null;
|
|
135
|
+
|
|
136
|
+
const contentParts: string[] = [cleanedWhat];
|
|
137
|
+
if (rootCause && rootCause.trim() && rootCause.trim() !== "—") {
|
|
138
|
+
contentParts.push(`Root cause: ${rootCause.trim()}.`);
|
|
139
|
+
}
|
|
140
|
+
if (fix && fix.trim() && fix.trim() !== "—") {
|
|
141
|
+
contentParts.push(`Fix: ${fix.trim()}.`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
table: "lessons",
|
|
146
|
+
id: row.id,
|
|
147
|
+
category: "gotcha",
|
|
148
|
+
content: trim(contentParts.join(" "), 600),
|
|
149
|
+
scope: (scope ?? "").trim() || "project",
|
|
150
|
+
structuredFields: {
|
|
151
|
+
sourceKnowledgeId: row.id,
|
|
152
|
+
sourceKnowledgeTable: "lessons",
|
|
153
|
+
whatHappened: cleanedWhat,
|
|
154
|
+
rootCause: (rootCause ?? "").trim(),
|
|
155
|
+
fix: (fix ?? "").trim(),
|
|
156
|
+
scopeText: (scope ?? "").trim(),
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function trim(value: string, max: number): string {
|
|
162
|
+
const cleaned = value.replace(/\s+/g, " ").trim();
|
|
163
|
+
return cleaned.length > max ? cleaned.slice(0, max - 1) + "…" : cleaned;
|
|
164
|
+
}
|