paths-engine 0.0.0-stage → 0.1.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 +600 -3
- package/dist/cli/commands/context.d.ts +3 -0
- package/dist/cli/commands/context.d.ts.map +1 -0
- package/dist/cli/commands/context.js +89 -0
- package/dist/cli/commands/context.js.map +1 -0
- package/dist/cli/commands/gui.d.ts +5 -0
- package/dist/cli/commands/gui.d.ts.map +1 -0
- package/dist/cli/commands/gui.js +28 -0
- package/dist/cli/commands/gui.js.map +1 -0
- package/dist/cli/commands/identity.d.ts +3 -0
- package/dist/cli/commands/identity.d.ts.map +1 -0
- package/dist/cli/commands/identity.js +83 -0
- package/dist/cli/commands/identity.js.map +1 -0
- package/dist/cli/commands/ingest.d.ts +3 -0
- package/dist/cli/commands/ingest.d.ts.map +1 -0
- package/dist/cli/commands/ingest.js +75 -0
- package/dist/cli/commands/ingest.js.map +1 -0
- package/dist/cli/commands/knowledge.d.ts +3 -0
- package/dist/cli/commands/knowledge.d.ts.map +1 -0
- package/dist/cli/commands/knowledge.js +104 -0
- package/dist/cli/commands/knowledge.js.map +1 -0
- package/dist/cli/commands/lineage.d.ts +3 -0
- package/dist/cli/commands/lineage.d.ts.map +1 -0
- package/dist/cli/commands/lineage.js +130 -0
- package/dist/cli/commands/lineage.js.map +1 -0
- package/dist/cli/commands/mcp-setup.d.ts +23 -0
- package/dist/cli/commands/mcp-setup.d.ts.map +1 -0
- package/dist/cli/commands/mcp-setup.js +190 -0
- package/dist/cli/commands/mcp-setup.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +8 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +230 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/session.d.ts +3 -0
- package/dist/cli/commands/session.d.ts.map +1 -0
- package/dist/cli/commands/session.js +82 -0
- package/dist/cli/commands/session.js.map +1 -0
- package/dist/cli/commands/status.d.ts +3 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +65 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/sync.d.ts +3 -0
- package/dist/cli/commands/sync.d.ts.map +1 -0
- package/dist/cli/commands/sync.js +168 -0
- package/dist/cli/commands/sync.js.map +1 -0
- package/dist/cli/commands/todo.d.ts +3 -0
- package/dist/cli/commands/todo.d.ts.map +1 -0
- package/dist/cli/commands/todo.js +116 -0
- package/dist/cli/commands/todo.js.map +1 -0
- package/dist/cli/file-reader.d.ts +3 -0
- package/dist/cli/file-reader.d.ts.map +1 -0
- package/dist/cli/file-reader.js +29 -0
- package/dist/cli/file-reader.js.map +1 -0
- package/dist/cli/formatters/context.d.ts +3 -0
- package/dist/cli/formatters/context.d.ts.map +1 -0
- package/dist/cli/formatters/context.js +58 -0
- package/dist/cli/formatters/context.js.map +1 -0
- package/dist/cli/formatters/errors.d.ts +2 -0
- package/dist/cli/formatters/errors.d.ts.map +1 -0
- package/dist/cli/formatters/errors.js +7 -0
- package/dist/cli/formatters/errors.js.map +1 -0
- package/dist/cli/formatters/status.d.ts +6 -0
- package/dist/cli/formatters/status.d.ts.map +1 -0
- package/dist/cli/formatters/status.js +79 -0
- package/dist/cli/formatters/status.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +40 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/compiler.d.ts +50 -0
- package/dist/core/compiler.d.ts.map +1 -0
- package/dist/core/compiler.js +424 -0
- package/dist/core/compiler.js.map +1 -0
- package/dist/core/db/case-mapper.d.ts +3 -0
- package/dist/core/db/case-mapper.d.ts.map +1 -0
- package/dist/core/db/case-mapper.js +21 -0
- package/dist/core/db/case-mapper.js.map +1 -0
- package/dist/core/db/embedding-repository.d.ts +14 -0
- package/dist/core/db/embedding-repository.d.ts.map +1 -0
- package/dist/core/db/embedding-repository.js +57 -0
- package/dist/core/db/embedding-repository.js.map +1 -0
- package/dist/core/db/external-event-repository.d.ts +13 -0
- package/dist/core/db/external-event-repository.d.ts.map +1 -0
- package/dist/core/db/external-event-repository.js +73 -0
- package/dist/core/db/external-event-repository.js.map +1 -0
- package/dist/core/db/identity-repository.d.ts +9 -0
- package/dist/core/db/identity-repository.d.ts.map +1 -0
- package/dist/core/db/identity-repository.js +37 -0
- package/dist/core/db/identity-repository.js.map +1 -0
- package/dist/core/db/index.d.ts +12 -0
- package/dist/core/db/index.d.ts.map +1 -0
- package/dist/core/db/index.js +33 -0
- package/dist/core/db/index.js.map +1 -0
- package/dist/core/db/knowledge-confirmation-repository.d.ts +12 -0
- package/dist/core/db/knowledge-confirmation-repository.d.ts.map +1 -0
- package/dist/core/db/knowledge-confirmation-repository.js +40 -0
- package/dist/core/db/knowledge-confirmation-repository.js.map +1 -0
- package/dist/core/db/knowledge-repository.d.ts +18 -0
- package/dist/core/db/knowledge-repository.d.ts.map +1 -0
- package/dist/core/db/knowledge-repository.js +77 -0
- package/dist/core/db/knowledge-repository.js.map +1 -0
- package/dist/core/db/lineage-repository.d.ts +14 -0
- package/dist/core/db/lineage-repository.d.ts.map +1 -0
- package/dist/core/db/lineage-repository.js +35 -0
- package/dist/core/db/lineage-repository.js.map +1 -0
- package/dist/core/db/node-repository.d.ts +33 -0
- package/dist/core/db/node-repository.d.ts.map +1 -0
- package/dist/core/db/node-repository.js +116 -0
- package/dist/core/db/node-repository.js.map +1 -0
- package/dist/core/db/path.d.ts +3 -0
- package/dist/core/db/path.d.ts.map +1 -0
- package/dist/core/db/path.js +57 -0
- package/dist/core/db/path.js.map +1 -0
- package/dist/core/db/plan-repository.d.ts +17 -0
- package/dist/core/db/plan-repository.d.ts.map +1 -0
- package/dist/core/db/plan-repository.js +56 -0
- package/dist/core/db/plan-repository.js.map +1 -0
- package/dist/core/db/project-repository.d.ts +11 -0
- package/dist/core/db/project-repository.d.ts.map +1 -0
- package/dist/core/db/project-repository.js +24 -0
- package/dist/core/db/project-repository.js.map +1 -0
- package/dist/core/db/rollup-repository.d.ts +10 -0
- package/dist/core/db/rollup-repository.d.ts.map +1 -0
- package/dist/core/db/rollup-repository.js +55 -0
- package/dist/core/db/rollup-repository.js.map +1 -0
- package/dist/core/db/schema.d.ts +4 -0
- package/dist/core/db/schema.d.ts.map +1 -0
- package/dist/core/db/schema.js +315 -0
- package/dist/core/db/schema.js.map +1 -0
- package/dist/core/db/store.d.ts +298 -0
- package/dist/core/db/store.d.ts.map +1 -0
- package/dist/core/db/store.js +1054 -0
- package/dist/core/db/store.js.map +1 -0
- package/dist/core/db/sync-repository.d.ts +23 -0
- package/dist/core/db/sync-repository.d.ts.map +1 -0
- package/dist/core/db/sync-repository.js +117 -0
- package/dist/core/db/sync-repository.js.map +1 -0
- package/dist/core/db/todo-repository.d.ts +14 -0
- package/dist/core/db/todo-repository.d.ts.map +1 -0
- package/dist/core/db/todo-repository.js +37 -0
- package/dist/core/db/todo-repository.js.map +1 -0
- package/dist/core/embedding/cosine.d.ts +5 -0
- package/dist/core/embedding/cosine.d.ts.map +1 -0
- package/dist/core/embedding/cosine.js +50 -0
- package/dist/core/embedding/cosine.js.map +1 -0
- package/dist/core/embedding/embedding.service.d.ts +27 -0
- package/dist/core/embedding/embedding.service.d.ts.map +1 -0
- package/dist/core/embedding/embedding.service.js +99 -0
- package/dist/core/embedding/embedding.service.js.map +1 -0
- package/dist/core/embedding/index.d.ts +3 -0
- package/dist/core/embedding/index.d.ts.map +1 -0
- package/dist/core/embedding/index.js +3 -0
- package/dist/core/embedding/index.js.map +1 -0
- package/dist/core/identity.d.ts +6 -0
- package/dist/core/identity.d.ts.map +1 -0
- package/dist/core/identity.js +24 -0
- package/dist/core/identity.js.map +1 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +13 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/ingestion/generic-adapter.d.ts +5 -0
- package/dist/core/ingestion/generic-adapter.d.ts.map +1 -0
- package/dist/core/ingestion/generic-adapter.js +15 -0
- package/dist/core/ingestion/generic-adapter.js.map +1 -0
- package/dist/core/ingestion/git-adapter.d.ts +12 -0
- package/dist/core/ingestion/git-adapter.d.ts.map +1 -0
- package/dist/core/ingestion/git-adapter.js +31 -0
- package/dist/core/ingestion/git-adapter.js.map +1 -0
- package/dist/core/ingestion/github-adapter.d.ts +23 -0
- package/dist/core/ingestion/github-adapter.d.ts.map +1 -0
- package/dist/core/ingestion/github-adapter.js +55 -0
- package/dist/core/ingestion/github-adapter.js.map +1 -0
- package/dist/core/ingestion/index.d.ts +6 -0
- package/dist/core/ingestion/index.d.ts.map +1 -0
- package/dist/core/ingestion/index.js +6 -0
- package/dist/core/ingestion/index.js.map +1 -0
- package/dist/core/ingestion/ingestion.service.d.ts +25 -0
- package/dist/core/ingestion/ingestion.service.d.ts.map +1 -0
- package/dist/core/ingestion/ingestion.service.js +109 -0
- package/dist/core/ingestion/ingestion.service.js.map +1 -0
- package/dist/core/ingestion/types.d.ts +38 -0
- package/dist/core/ingestion/types.d.ts.map +1 -0
- package/dist/core/ingestion/types.js +2 -0
- package/dist/core/ingestion/types.js.map +1 -0
- package/dist/core/knowledge.d.ts +13 -0
- package/dist/core/knowledge.d.ts.map +1 -0
- package/dist/core/knowledge.js +101 -0
- package/dist/core/knowledge.js.map +1 -0
- package/dist/core/lineage.d.ts +11 -0
- package/dist/core/lineage.d.ts.map +1 -0
- package/dist/core/lineage.js +75 -0
- package/dist/core/lineage.js.map +1 -0
- package/dist/core/node.d.ts +27 -0
- package/dist/core/node.d.ts.map +1 -0
- package/dist/core/node.js +145 -0
- package/dist/core/node.js.map +1 -0
- package/dist/core/plan.d.ts +26 -0
- package/dist/core/plan.d.ts.map +1 -0
- package/dist/core/plan.js +109 -0
- package/dist/core/plan.js.map +1 -0
- package/dist/core/project.d.ts +10 -0
- package/dist/core/project.d.ts.map +1 -0
- package/dist/core/project.js +108 -0
- package/dist/core/project.js.map +1 -0
- package/dist/core/rollup.d.ts +7 -0
- package/dist/core/rollup.d.ts.map +1 -0
- package/dist/core/rollup.js +48 -0
- package/dist/core/rollup.js.map +1 -0
- package/dist/core/security/error-classifier.d.ts +35 -0
- package/dist/core/security/error-classifier.d.ts.map +1 -0
- package/dist/core/security/error-classifier.js +169 -0
- package/dist/core/security/error-classifier.js.map +1 -0
- package/dist/core/sync/bundle-auth.d.ts +23 -0
- package/dist/core/sync/bundle-auth.d.ts.map +1 -0
- package/dist/core/sync/bundle-auth.js +184 -0
- package/dist/core/sync/bundle-auth.js.map +1 -0
- package/dist/core/sync/device.d.ts +8 -0
- package/dist/core/sync/device.d.ts.map +1 -0
- package/dist/core/sync/device.js +32 -0
- package/dist/core/sync/device.js.map +1 -0
- package/dist/core/sync/hlc.d.ts +12 -0
- package/dist/core/sync/hlc.d.ts.map +1 -0
- package/dist/core/sync/hlc.js +83 -0
- package/dist/core/sync/hlc.js.map +1 -0
- package/dist/core/sync/index.d.ts +6 -0
- package/dist/core/sync/index.d.ts.map +1 -0
- package/dist/core/sync/index.js +5 -0
- package/dist/core/sync/index.js.map +1 -0
- package/dist/core/sync/sync.service.d.ts +29 -0
- package/dist/core/sync/sync.service.d.ts.map +1 -0
- package/dist/core/sync/sync.service.js +457 -0
- package/dist/core/sync/sync.service.js.map +1 -0
- package/dist/core/sync/types.d.ts +101 -0
- package/dist/core/sync/types.d.ts.map +1 -0
- package/dist/core/sync/types.js +2 -0
- package/dist/core/sync/types.js.map +1 -0
- package/dist/core/task-context-budget.d.ts +5 -0
- package/dist/core/task-context-budget.d.ts.map +1 -0
- package/dist/core/task-context-budget.js +11 -0
- package/dist/core/task-context-budget.js.map +1 -0
- package/dist/core/task-context-order.d.ts +6 -0
- package/dist/core/task-context-order.d.ts.map +1 -0
- package/dist/core/task-context-order.js +26 -0
- package/dist/core/task-context-order.js.map +1 -0
- package/dist/core/task-context-paths.d.ts +6 -0
- package/dist/core/task-context-paths.d.ts.map +1 -0
- package/dist/core/task-context-paths.js +59 -0
- package/dist/core/task-context-paths.js.map +1 -0
- package/dist/core/task-context.d.ts +21 -0
- package/dist/core/task-context.d.ts.map +1 -0
- package/dist/core/task-context.js +283 -0
- package/dist/core/task-context.js.map +1 -0
- package/dist/core/todo.d.ts +16 -0
- package/dist/core/todo.d.ts.map +1 -0
- package/dist/core/todo.js +110 -0
- package/dist/core/todo.js.map +1 -0
- package/dist/core/tokenizer.d.ts +3 -0
- package/dist/core/tokenizer.d.ts.map +1 -0
- package/dist/core/tokenizer.js +9 -0
- package/dist/core/tokenizer.js.map +1 -0
- package/dist/core/types/context.d.ts +50 -0
- package/dist/core/types/context.d.ts.map +1 -0
- package/dist/core/types/context.js +2 -0
- package/dist/core/types/context.js.map +1 -0
- package/dist/core/types/embedding.d.ts +25 -0
- package/dist/core/types/embedding.d.ts.map +1 -0
- package/dist/core/types/embedding.js +2 -0
- package/dist/core/types/embedding.js.map +1 -0
- package/dist/core/types/external-event.d.ts +29 -0
- package/dist/core/types/external-event.d.ts.map +1 -0
- package/dist/core/types/external-event.js +2 -0
- package/dist/core/types/external-event.js.map +1 -0
- package/dist/core/types/hlc.d.ts +12 -0
- package/dist/core/types/hlc.d.ts.map +1 -0
- package/dist/core/types/hlc.js +2 -0
- package/dist/core/types/hlc.js.map +1 -0
- package/dist/core/types/identity.d.ts +26 -0
- package/dist/core/types/identity.d.ts.map +1 -0
- package/dist/core/types/identity.js +2 -0
- package/dist/core/types/identity.js.map +1 -0
- package/dist/core/types/index.d.ts +15 -0
- package/dist/core/types/index.d.ts.map +1 -0
- package/dist/core/types/index.js +15 -0
- package/dist/core/types/index.js.map +1 -0
- package/dist/core/types/installation-identity.d.ts +13 -0
- package/dist/core/types/installation-identity.d.ts.map +1 -0
- package/dist/core/types/installation-identity.js +2 -0
- package/dist/core/types/installation-identity.js.map +1 -0
- package/dist/core/types/knowledge-confirmation.d.ts +25 -0
- package/dist/core/types/knowledge-confirmation.d.ts.map +1 -0
- package/dist/core/types/knowledge-confirmation.js +2 -0
- package/dist/core/types/knowledge-confirmation.js.map +1 -0
- package/dist/core/types/knowledge.d.ts +50 -0
- package/dist/core/types/knowledge.d.ts.map +1 -0
- package/dist/core/types/knowledge.js +12 -0
- package/dist/core/types/knowledge.js.map +1 -0
- package/dist/core/types/lineage.d.ts +37 -0
- package/dist/core/types/lineage.d.ts.map +1 -0
- package/dist/core/types/lineage.js +2 -0
- package/dist/core/types/lineage.js.map +1 -0
- package/dist/core/types/node.d.ts +47 -0
- package/dist/core/types/node.d.ts.map +1 -0
- package/dist/core/types/node.js +2 -0
- package/dist/core/types/node.js.map +1 -0
- package/dist/core/types/plan.d.ts +60 -0
- package/dist/core/types/plan.d.ts.map +1 -0
- package/dist/core/types/plan.js +2 -0
- package/dist/core/types/plan.js.map +1 -0
- package/dist/core/types/project.d.ts +27 -0
- package/dist/core/types/project.d.ts.map +1 -0
- package/dist/core/types/project.js +2 -0
- package/dist/core/types/project.js.map +1 -0
- package/dist/core/types/status-json.d.ts +30 -0
- package/dist/core/types/status-json.d.ts.map +1 -0
- package/dist/core/types/status-json.js +2 -0
- package/dist/core/types/status-json.js.map +1 -0
- package/dist/core/types/sync-change.d.ts +49 -0
- package/dist/core/types/sync-change.d.ts.map +1 -0
- package/dist/core/types/sync-change.js +2 -0
- package/dist/core/types/sync-change.js.map +1 -0
- package/dist/core/types/task-context.d.ts +55 -0
- package/dist/core/types/task-context.d.ts.map +1 -0
- package/dist/core/types/task-context.js +2 -0
- package/dist/core/types/task-context.js.map +1 -0
- package/dist/core/types/todo.d.ts +33 -0
- package/dist/core/types/todo.d.ts.map +1 -0
- package/dist/core/types/todo.js +2 -0
- package/dist/core/types/todo.js.map +1 -0
- package/dist/gui/launcher.d.ts +22 -0
- package/dist/gui/launcher.d.ts.map +1 -0
- package/dist/gui/launcher.js +86 -0
- package/dist/gui/launcher.js.map +1 -0
- package/dist/gui/main/app-bridge.d.ts +21 -0
- package/dist/gui/main/app-bridge.d.ts.map +1 -0
- package/dist/gui/main/app-bridge.js +204 -0
- package/dist/gui/main/app-bridge.js.map +1 -0
- package/dist/gui/main/app-context-manager.d.ts +25 -0
- package/dist/gui/main/app-context-manager.d.ts.map +1 -0
- package/dist/gui/main/app-context-manager.js +141 -0
- package/dist/gui/main/app-context-manager.js.map +1 -0
- package/dist/gui/main/context.d.ts +32 -0
- package/dist/gui/main/context.d.ts.map +1 -0
- package/dist/gui/main/context.js +56 -0
- package/dist/gui/main/context.js.map +1 -0
- package/dist/gui/main/index.d.ts +2 -0
- package/dist/gui/main/index.d.ts.map +1 -0
- package/dist/gui/main/index.js +3 -0
- package/dist/gui/main/index.js.map +1 -0
- package/dist/gui/main/lifecycle.d.ts +45 -0
- package/dist/gui/main/lifecycle.d.ts.map +1 -0
- package/dist/gui/main/lifecycle.js +272 -0
- package/dist/gui/main/lifecycle.js.map +1 -0
- package/dist/gui/main/schemas.d.ts +105 -0
- package/dist/gui/main/schemas.d.ts.map +1 -0
- package/dist/gui/main/schemas.js +131 -0
- package/dist/gui/main/schemas.js.map +1 -0
- package/dist/gui/main/tray.d.ts +9 -0
- package/dist/gui/main/tray.d.ts.map +1 -0
- package/dist/gui/main/tray.js +70 -0
- package/dist/gui/main/tray.js.map +1 -0
- package/dist/gui/preload/api-interface.d.ts +59 -0
- package/dist/gui/preload/api-interface.d.ts.map +1 -0
- package/dist/gui/preload/api-interface.js +2 -0
- package/dist/gui/preload/api-interface.js.map +1 -0
- package/dist/gui/preload/preload.cjs +1 -0
- package/dist/gui/preload/preload.d.ts +3 -0
- package/dist/gui/preload/preload.d.ts.map +1 -0
- package/dist/gui/preload/preload.js +36 -0
- package/dist/gui/preload/preload.js.map +1 -0
- package/dist/gui/renderer/App.d.ts +3 -0
- package/dist/gui/renderer/App.d.ts.map +1 -0
- package/dist/gui/renderer/App.js +33 -0
- package/dist/gui/renderer/App.js.map +1 -0
- package/dist/gui/renderer/components/layout/AppShell.d.ts +15 -0
- package/dist/gui/renderer/components/layout/AppShell.d.ts.map +1 -0
- package/dist/gui/renderer/components/layout/AppShell.js +206 -0
- package/dist/gui/renderer/components/layout/AppShell.js.map +1 -0
- package/dist/gui/renderer/components/layout/NavItem.d.ts +12 -0
- package/dist/gui/renderer/components/layout/NavItem.d.ts.map +1 -0
- package/dist/gui/renderer/components/layout/NavItem.js +72 -0
- package/dist/gui/renderer/components/layout/NavItem.js.map +1 -0
- package/dist/gui/renderer/components/layout/PathsLogo.d.ts +9 -0
- package/dist/gui/renderer/components/layout/PathsLogo.d.ts.map +1 -0
- package/dist/gui/renderer/components/layout/PathsLogo.js +87 -0
- package/dist/gui/renderer/components/layout/PathsLogo.js.map +1 -0
- package/dist/gui/renderer/components/shared/Badge.d.ts +11 -0
- package/dist/gui/renderer/components/shared/Badge.d.ts.map +1 -0
- package/dist/gui/renderer/components/shared/Badge.js +150 -0
- package/dist/gui/renderer/components/shared/Badge.js.map +1 -0
- package/dist/gui/renderer/components/shared/EmptyState.d.ts +10 -0
- package/dist/gui/renderer/components/shared/EmptyState.d.ts.map +1 -0
- package/dist/gui/renderer/components/shared/EmptyState.js +59 -0
- package/dist/gui/renderer/components/shared/EmptyState.js.map +1 -0
- package/dist/gui/renderer/components/shared/ErrorBanner.d.ts +7 -0
- package/dist/gui/renderer/components/shared/ErrorBanner.d.ts.map +1 -0
- package/dist/gui/renderer/components/shared/ErrorBanner.js +33 -0
- package/dist/gui/renderer/components/shared/ErrorBanner.js.map +1 -0
- package/dist/gui/renderer/components/shared/ErrorBoundary.d.ts +18 -0
- package/dist/gui/renderer/components/shared/ErrorBoundary.d.ts.map +1 -0
- package/dist/gui/renderer/components/shared/ErrorBoundary.js +40 -0
- package/dist/gui/renderer/components/shared/ErrorBoundary.js.map +1 -0
- package/dist/gui/renderer/components/shared/GlassSelect.d.ts +17 -0
- package/dist/gui/renderer/components/shared/GlassSelect.d.ts.map +1 -0
- package/dist/gui/renderer/components/shared/GlassSelect.js +147 -0
- package/dist/gui/renderer/components/shared/GlassSelect.js.map +1 -0
- package/dist/gui/renderer/components/shared/LoadingSpinner.d.ts +7 -0
- package/dist/gui/renderer/components/shared/LoadingSpinner.d.ts.map +1 -0
- package/dist/gui/renderer/components/shared/LoadingSpinner.js +27 -0
- package/dist/gui/renderer/components/shared/LoadingSpinner.js.map +1 -0
- package/dist/gui/renderer/components/surfaces/Dashboard.d.ts +3 -0
- package/dist/gui/renderer/components/surfaces/Dashboard.d.ts.map +1 -0
- package/dist/gui/renderer/components/surfaces/Dashboard.js +123 -0
- package/dist/gui/renderer/components/surfaces/Dashboard.js.map +1 -0
- package/dist/gui/renderer/components/surfaces/KnowledgeExplorer.d.ts +3 -0
- package/dist/gui/renderer/components/surfaces/KnowledgeExplorer.d.ts.map +1 -0
- package/dist/gui/renderer/components/surfaces/KnowledgeExplorer.js +202 -0
- package/dist/gui/renderer/components/surfaces/KnowledgeExplorer.js.map +1 -0
- package/dist/gui/renderer/components/surfaces/LineageManager.d.ts +3 -0
- package/dist/gui/renderer/components/surfaces/LineageManager.d.ts.map +1 -0
- package/dist/gui/renderer/components/surfaces/LineageManager.js +148 -0
- package/dist/gui/renderer/components/surfaces/LineageManager.js.map +1 -0
- package/dist/gui/renderer/components/surfaces/SessionTimeline.d.ts +3 -0
- package/dist/gui/renderer/components/surfaces/SessionTimeline.d.ts.map +1 -0
- package/dist/gui/renderer/components/surfaces/SessionTimeline.js +136 -0
- package/dist/gui/renderer/components/surfaces/SessionTimeline.js.map +1 -0
- package/dist/gui/renderer/components/surfaces/TodoBoard.d.ts +3 -0
- package/dist/gui/renderer/components/surfaces/TodoBoard.d.ts.map +1 -0
- package/dist/gui/renderer/components/surfaces/TodoBoard.js +128 -0
- package/dist/gui/renderer/components/surfaces/TodoBoard.js.map +1 -0
- package/dist/gui/renderer/context/paths-context.d.ts +19 -0
- package/dist/gui/renderer/context/paths-context.d.ts.map +1 -0
- package/dist/gui/renderer/context/paths-context.js +122 -0
- package/dist/gui/renderer/context/paths-context.js.map +1 -0
- package/dist/gui/renderer/context/theme-context.d.ts +11 -0
- package/dist/gui/renderer/context/theme-context.d.ts.map +1 -0
- package/dist/gui/renderer/context/theme-context.js +41 -0
- package/dist/gui/renderer/context/theme-context.js.map +1 -0
- package/dist/gui/renderer/hooks/use-api-query.d.ts +9 -0
- package/dist/gui/renderer/hooks/use-api-query.d.ts.map +1 -0
- package/dist/gui/renderer/hooks/use-api-query.js +60 -0
- package/dist/gui/renderer/hooks/use-api-query.js.map +1 -0
- package/dist/gui/renderer/hooks/use-lineage.d.ts +13 -0
- package/dist/gui/renderer/hooks/use-lineage.d.ts.map +1 -0
- package/dist/gui/renderer/hooks/use-lineage.js +15 -0
- package/dist/gui/renderer/hooks/use-lineage.js.map +1 -0
- package/dist/gui/renderer/index.d.ts +2 -0
- package/dist/gui/renderer/index.d.ts.map +1 -0
- package/dist/gui/renderer/index.js +2 -0
- package/dist/gui/renderer/index.js.map +1 -0
- package/dist/gui/shared/errors.d.ts +23 -0
- package/dist/gui/shared/errors.d.ts.map +1 -0
- package/dist/gui/shared/errors.js +10 -0
- package/dist/gui/shared/errors.js.map +1 -0
- package/dist/gui/shared/index.d.ts +4 -0
- package/dist/gui/shared/index.d.ts.map +1 -0
- package/dist/gui/shared/index.js +4 -0
- package/dist/gui/shared/index.js.map +1 -0
- package/dist/gui/shared/ipc-channels.d.ts +53 -0
- package/dist/gui/shared/ipc-channels.d.ts.map +1 -0
- package/dist/gui/shared/ipc-channels.js +63 -0
- package/dist/gui/shared/ipc-channels.js.map +1 -0
- package/dist/gui/shared/ipc-contracts.d.ts +176 -0
- package/dist/gui/shared/ipc-contracts.d.ts.map +1 -0
- package/dist/gui/shared/ipc-contracts.js +2 -0
- package/dist/gui/shared/ipc-contracts.js.map +1 -0
- package/dist/mcp/context.d.ts +55 -0
- package/dist/mcp/context.d.ts.map +1 -0
- package/dist/mcp/context.js +183 -0
- package/dist/mcp/context.js.map +1 -0
- package/dist/mcp/handler-utils.d.ts +22 -0
- package/dist/mcp/handler-utils.d.ts.map +1 -0
- package/dist/mcp/handler-utils.js +26 -0
- package/dist/mcp/handler-utils.js.map +1 -0
- package/dist/mcp/schemas.d.ts +688 -0
- package/dist/mcp/schemas.d.ts.map +1 -0
- package/dist/mcp/schemas.js +278 -0
- package/dist/mcp/schemas.js.map +1 -0
- package/dist/mcp/server.d.ts +8 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +88 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/abandon-plan.d.ts +4 -0
- package/dist/mcp/tools/abandon-plan.d.ts.map +1 -0
- package/dist/mcp/tools/abandon-plan.js +32 -0
- package/dist/mcp/tools/abandon-plan.js.map +1 -0
- package/dist/mcp/tools/add-todo.d.ts +4 -0
- package/dist/mcp/tools/add-todo.d.ts.map +1 -0
- package/dist/mcp/tools/add-todo.js +34 -0
- package/dist/mcp/tools/add-todo.js.map +1 -0
- package/dist/mcp/tools/complete-plan.d.ts +4 -0
- package/dist/mcp/tools/complete-plan.d.ts.map +1 -0
- package/dist/mcp/tools/complete-plan.js +32 -0
- package/dist/mcp/tools/complete-plan.js.map +1 -0
- package/dist/mcp/tools/complete-todo.d.ts +4 -0
- package/dist/mcp/tools/complete-todo.d.ts.map +1 -0
- package/dist/mcp/tools/complete-todo.js +51 -0
- package/dist/mcp/tools/complete-todo.js.map +1 -0
- package/dist/mcp/tools/continue-lineage.d.ts +4 -0
- package/dist/mcp/tools/continue-lineage.d.ts.map +1 -0
- package/dist/mcp/tools/continue-lineage.js +31 -0
- package/dist/mcp/tools/continue-lineage.js.map +1 -0
- package/dist/mcp/tools/create-plan.d.ts +4 -0
- package/dist/mcp/tools/create-plan.d.ts.map +1 -0
- package/dist/mcp/tools/create-plan.js +42 -0
- package/dist/mcp/tools/create-plan.js.map +1 -0
- package/dist/mcp/tools/get-active-plan.d.ts +4 -0
- package/dist/mcp/tools/get-active-plan.d.ts.map +1 -0
- package/dist/mcp/tools/get-active-plan.js +30 -0
- package/dist/mcp/tools/get-active-plan.js.map +1 -0
- package/dist/mcp/tools/get-lineage-history.d.ts +4 -0
- package/dist/mcp/tools/get-lineage-history.d.ts.map +1 -0
- package/dist/mcp/tools/get-lineage-history.js +38 -0
- package/dist/mcp/tools/get-lineage-history.js.map +1 -0
- package/dist/mcp/tools/get-lineages.d.ts +4 -0
- package/dist/mcp/tools/get-lineages.d.ts.map +1 -0
- package/dist/mcp/tools/get-lineages.js +30 -0
- package/dist/mcp/tools/get-lineages.js.map +1 -0
- package/dist/mcp/tools/get-project-context.d.ts +4 -0
- package/dist/mcp/tools/get-project-context.d.ts.map +1 -0
- package/dist/mcp/tools/get-project-context.js +38 -0
- package/dist/mcp/tools/get-project-context.js.map +1 -0
- package/dist/mcp/tools/get-task-context.d.ts +4 -0
- package/dist/mcp/tools/get-task-context.d.ts.map +1 -0
- package/dist/mcp/tools/get-task-context.js +42 -0
- package/dist/mcp/tools/get-task-context.js.map +1 -0
- package/dist/mcp/tools/ingest-event.d.ts +4 -0
- package/dist/mcp/tools/ingest-event.d.ts.map +1 -0
- package/dist/mcp/tools/ingest-event.js +71 -0
- package/dist/mcp/tools/ingest-event.js.map +1 -0
- package/dist/mcp/tools/list-plans.d.ts +4 -0
- package/dist/mcp/tools/list-plans.d.ts.map +1 -0
- package/dist/mcp/tools/list-plans.js +44 -0
- package/dist/mcp/tools/list-plans.js.map +1 -0
- package/dist/mcp/tools/list-todos.d.ts +4 -0
- package/dist/mcp/tools/list-todos.d.ts.map +1 -0
- package/dist/mcp/tools/list-todos.js +31 -0
- package/dist/mcp/tools/list-todos.js.map +1 -0
- package/dist/mcp/tools/log-session.d.ts +4 -0
- package/dist/mcp/tools/log-session.d.ts.map +1 -0
- package/dist/mcp/tools/log-session.js +35 -0
- package/dist/mcp/tools/log-session.js.map +1 -0
- package/dist/mcp/tools/open-gui.d.ts +14 -0
- package/dist/mcp/tools/open-gui.d.ts.map +1 -0
- package/dist/mcp/tools/open-gui.js +42 -0
- package/dist/mcp/tools/open-gui.js.map +1 -0
- package/dist/mcp/tools/save-knowledge.d.ts +4 -0
- package/dist/mcp/tools/save-knowledge.d.ts.map +1 -0
- package/dist/mcp/tools/save-knowledge.js +36 -0
- package/dist/mcp/tools/save-knowledge.js.map +1 -0
- package/dist/mcp/tools/search-knowledge.d.ts +4 -0
- package/dist/mcp/tools/search-knowledge.d.ts.map +1 -0
- package/dist/mcp/tools/search-knowledge.js +31 -0
- package/dist/mcp/tools/search-knowledge.js.map +1 -0
- package/dist/mcp/tools/search-nodes.d.ts +4 -0
- package/dist/mcp/tools/search-nodes.d.ts.map +1 -0
- package/dist/mcp/tools/search-nodes.js +33 -0
- package/dist/mcp/tools/search-nodes.js.map +1 -0
- package/dist/mcp/tools/start-lineage.d.ts +4 -0
- package/dist/mcp/tools/start-lineage.d.ts.map +1 -0
- package/dist/mcp/tools/start-lineage.js +31 -0
- package/dist/mcp/tools/start-lineage.js.map +1 -0
- package/dist/mcp/tools/sync-apply.d.ts +4 -0
- package/dist/mcp/tools/sync-apply.d.ts.map +1 -0
- package/dist/mcp/tools/sync-apply.js +23 -0
- package/dist/mcp/tools/sync-apply.js.map +1 -0
- package/dist/mcp/tools/sync-export.d.ts +4 -0
- package/dist/mcp/tools/sync-export.d.ts.map +1 -0
- package/dist/mcp/tools/sync-export.js +33 -0
- package/dist/mcp/tools/sync-export.js.map +1 -0
- package/dist/mcp/tools/sync-status.d.ts +4 -0
- package/dist/mcp/tools/sync-status.d.ts.map +1 -0
- package/dist/mcp/tools/sync-status.js +29 -0
- package/dist/mcp/tools/sync-status.js.map +1 -0
- package/dist/mcp/tools/update-identity.d.ts +4 -0
- package/dist/mcp/tools/update-identity.d.ts.map +1 -0
- package/dist/mcp/tools/update-identity.js +39 -0
- package/dist/mcp/tools/update-identity.js.map +1 -0
- package/dist/renderer/assets/index-Bs2j5Xf4.css +1 -0
- package/dist/renderer/assets/index-ovMIJ8mi.js +22 -0
- package/dist/renderer/index.html +17 -0
- package/package.json +77 -6
|
@@ -0,0 +1,1054 @@
|
|
|
1
|
+
const VALID_SYNC_TABLES = new Set([
|
|
2
|
+
'projects',
|
|
3
|
+
'lineages',
|
|
4
|
+
'nodes',
|
|
5
|
+
'knowledge',
|
|
6
|
+
'knowledge_confirmations',
|
|
7
|
+
'todos',
|
|
8
|
+
]);
|
|
9
|
+
function assertValidSyncTable(table) {
|
|
10
|
+
if (!VALID_SYNC_TABLES.has(table)) {
|
|
11
|
+
throw new Error(`Table "${table}" is not a valid syncable table.`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function assertRowAffected(changes, entityName, id) {
|
|
15
|
+
if (changes === 0) {
|
|
16
|
+
throw new Error(`${entityName} ${id} does not exist.`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function clampSearchLimit(limit) {
|
|
20
|
+
return Number.isInteger(limit) ? Math.min(Math.max(limit, 1), 100) : 20;
|
|
21
|
+
}
|
|
22
|
+
function escapeLikeWildcards(value) {
|
|
23
|
+
return value.replace(/\\/g, '\\\\').replace(/%/g, '\\%').replace(/_/g, '\\_');
|
|
24
|
+
}
|
|
25
|
+
function buildLineageFilterClause(lineageId) {
|
|
26
|
+
return lineageId !== undefined ? ' AND (lineage_id IS NULL OR lineage_id = ?)' : '';
|
|
27
|
+
}
|
|
28
|
+
const PLAN_CONTENT_FIELDS = [
|
|
29
|
+
{ key: 'title', column: 'title' },
|
|
30
|
+
{ key: 'intent', column: 'intent' },
|
|
31
|
+
{ key: 'approach', column: 'approach' },
|
|
32
|
+
{ key: 'definitionOfDone', column: 'definition_of_done' },
|
|
33
|
+
];
|
|
34
|
+
function buildPlanUpdateAssignments(fields) {
|
|
35
|
+
const assignments = [];
|
|
36
|
+
const params = [];
|
|
37
|
+
for (const { key, column } of PLAN_CONTENT_FIELDS) {
|
|
38
|
+
const value = fields[key];
|
|
39
|
+
if (value !== undefined) {
|
|
40
|
+
assignments.push(`${column} = ?`);
|
|
41
|
+
params.push(value);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return { assignments, params };
|
|
45
|
+
}
|
|
46
|
+
export class SqliteStore {
|
|
47
|
+
db;
|
|
48
|
+
constructor(db) {
|
|
49
|
+
this.db = db;
|
|
50
|
+
}
|
|
51
|
+
statementCache = new Map();
|
|
52
|
+
getPreparedStatement(sql) {
|
|
53
|
+
let stmt = this.statementCache.get(sql);
|
|
54
|
+
if (!stmt) {
|
|
55
|
+
stmt = this.db.prepare(sql);
|
|
56
|
+
this.statementCache.set(sql, stmt);
|
|
57
|
+
}
|
|
58
|
+
return stmt;
|
|
59
|
+
}
|
|
60
|
+
transaction(fn) {
|
|
61
|
+
return this.db.transaction(fn)();
|
|
62
|
+
}
|
|
63
|
+
getProjectByKey(key) {
|
|
64
|
+
const stmt = this.getPreparedStatement('SELECT * FROM projects WHERE key = ?');
|
|
65
|
+
return stmt.get(key);
|
|
66
|
+
}
|
|
67
|
+
getProjectById(id) {
|
|
68
|
+
const stmt = this.getPreparedStatement('SELECT * FROM projects WHERE id = ?');
|
|
69
|
+
return stmt.get(id);
|
|
70
|
+
}
|
|
71
|
+
getLatestProject() {
|
|
72
|
+
const stmt = this.getPreparedStatement('SELECT * FROM projects WHERE path_hint IS NOT NULL ORDER BY id DESC LIMIT 1');
|
|
73
|
+
return stmt.get();
|
|
74
|
+
}
|
|
75
|
+
upsertProject(key, pathHint, name) {
|
|
76
|
+
const existing = this.getProjectByKey(key);
|
|
77
|
+
if (existing) {
|
|
78
|
+
const updateStmt = this.db.prepare('UPDATE projects SET path_hint = ? WHERE id = ?');
|
|
79
|
+
updateStmt.run(pathHint, existing.id);
|
|
80
|
+
return { ...existing, path_hint: pathHint };
|
|
81
|
+
}
|
|
82
|
+
const createdAt = new Date().toISOString();
|
|
83
|
+
const insertStmt = this.db.prepare('INSERT INTO projects (key, path_hint, name, current_lineage_id, created_at, sync_uuid, sync_hlc, sync_origin_device, sync_is_tombstone, sync_version) VALUES (?, ?, ?, ?, ?, NULL, NULL, NULL, 0, 1)');
|
|
84
|
+
const info = insertStmt.run(key, pathHint, name ?? null, null, createdAt);
|
|
85
|
+
return {
|
|
86
|
+
id: Number(info.lastInsertRowid),
|
|
87
|
+
key,
|
|
88
|
+
path_hint: pathHint,
|
|
89
|
+
name: name ?? null,
|
|
90
|
+
current_lineage_id: null,
|
|
91
|
+
created_at: createdAt,
|
|
92
|
+
sync_uuid: null,
|
|
93
|
+
sync_hlc: null,
|
|
94
|
+
sync_origin_device: null,
|
|
95
|
+
sync_is_tombstone: 0,
|
|
96
|
+
sync_version: 1,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
getIdentityRow(projectId) {
|
|
100
|
+
const stmt = this.getPreparedStatement('SELECT * FROM identity WHERE project_id = ?');
|
|
101
|
+
return stmt.get(projectId);
|
|
102
|
+
}
|
|
103
|
+
upsertIdentityRow(projectId, fields, updatedAt) {
|
|
104
|
+
const existing = this.getIdentityRow(projectId);
|
|
105
|
+
const fieldValues = [
|
|
106
|
+
fields.project_name ?? null,
|
|
107
|
+
fields.purpose ?? null,
|
|
108
|
+
fields.architecture ?? null,
|
|
109
|
+
fields.tech_stack ?? null,
|
|
110
|
+
fields.coding_standards ?? null,
|
|
111
|
+
fields.folder_structure ?? null,
|
|
112
|
+
fields.scope ?? null,
|
|
113
|
+
fields.definition_of_done ?? null,
|
|
114
|
+
];
|
|
115
|
+
if (existing) {
|
|
116
|
+
this.getPreparedStatement(`
|
|
117
|
+
UPDATE identity SET
|
|
118
|
+
project_name = COALESCE(?, project_name),
|
|
119
|
+
purpose = COALESCE(?, purpose),
|
|
120
|
+
architecture = COALESCE(?, architecture),
|
|
121
|
+
tech_stack = COALESCE(?, tech_stack),
|
|
122
|
+
coding_standards = COALESCE(?, coding_standards),
|
|
123
|
+
folder_structure = COALESCE(?, folder_structure),
|
|
124
|
+
scope = COALESCE(?, scope),
|
|
125
|
+
definition_of_done = COALESCE(?, definition_of_done),
|
|
126
|
+
updated_at = ?
|
|
127
|
+
WHERE project_id = ?
|
|
128
|
+
`).run(...fieldValues, updatedAt, projectId);
|
|
129
|
+
return this.getIdentityRow(projectId);
|
|
130
|
+
}
|
|
131
|
+
this.getPreparedStatement(`
|
|
132
|
+
INSERT INTO identity (
|
|
133
|
+
project_id, project_name, purpose, architecture, tech_stack,
|
|
134
|
+
coding_standards, folder_structure, scope, definition_of_done, updated_at
|
|
135
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
136
|
+
`).run(projectId, ...fieldValues, updatedAt);
|
|
137
|
+
return this.getIdentityRow(projectId);
|
|
138
|
+
}
|
|
139
|
+
createLineageRow(projectId, name) {
|
|
140
|
+
const now = new Date().toISOString();
|
|
141
|
+
const stmt = this.db.prepare('INSERT INTO lineages (project_id, name, status, created_at, last_active_at, sync_uuid, sync_hlc, sync_origin_device, sync_is_tombstone, sync_version) VALUES (?, ?, ?, ?, ?, NULL, NULL, NULL, 0, 1)');
|
|
142
|
+
const info = stmt.run(projectId, name, 'active', now, now);
|
|
143
|
+
return {
|
|
144
|
+
id: Number(info.lastInsertRowid),
|
|
145
|
+
project_id: projectId,
|
|
146
|
+
name,
|
|
147
|
+
status: 'active',
|
|
148
|
+
created_at: now,
|
|
149
|
+
last_active_at: now,
|
|
150
|
+
sync_uuid: null,
|
|
151
|
+
sync_hlc: null,
|
|
152
|
+
sync_origin_device: null,
|
|
153
|
+
sync_is_tombstone: 0,
|
|
154
|
+
sync_version: 1,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
getLineagesByProjectId(projectId) {
|
|
158
|
+
const stmt = this.getPreparedStatement('SELECT * FROM lineages WHERE project_id = ? ORDER BY id ASC');
|
|
159
|
+
return stmt.all(projectId);
|
|
160
|
+
}
|
|
161
|
+
getLineageById(id) {
|
|
162
|
+
const stmt = this.getPreparedStatement('SELECT * FROM lineages WHERE id = ?');
|
|
163
|
+
return stmt.get(id);
|
|
164
|
+
}
|
|
165
|
+
touchLineageRow(id) {
|
|
166
|
+
const now = new Date().toISOString();
|
|
167
|
+
const stmt = this.getPreparedStatement('UPDATE lineages SET last_active_at = ? WHERE id = ?');
|
|
168
|
+
stmt.run(now, id);
|
|
169
|
+
}
|
|
170
|
+
setCurrentLineageId(projectId, lineageId) {
|
|
171
|
+
const stmt = this.getPreparedStatement('UPDATE projects SET current_lineage_id = ? WHERE id = ?');
|
|
172
|
+
stmt.run(lineageId, projectId);
|
|
173
|
+
}
|
|
174
|
+
createNodeRow(lineageId, tool, summary, parentNodeId, filesTouched, nodeType = 'session') {
|
|
175
|
+
const createdAt = new Date().toISOString();
|
|
176
|
+
const stmt = this.db.prepare(`
|
|
177
|
+
INSERT INTO nodes (lineage_id, tool, summary, files_touched, parent_node_id, created_at, node_type, sync_uuid, sync_hlc, sync_origin_device, sync_is_tombstone, sync_version)
|
|
178
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, NULL, NULL, NULL, 0, 1)
|
|
179
|
+
`);
|
|
180
|
+
const info = stmt.run(lineageId, tool, summary, filesTouched ?? null, parentNodeId ?? null, createdAt, nodeType);
|
|
181
|
+
return {
|
|
182
|
+
id: Number(info.lastInsertRowid),
|
|
183
|
+
lineage_id: lineageId,
|
|
184
|
+
tool,
|
|
185
|
+
summary,
|
|
186
|
+
files_touched: filesTouched ?? null,
|
|
187
|
+
parent_node_id: parentNodeId ?? null,
|
|
188
|
+
created_at: createdAt,
|
|
189
|
+
node_type: nodeType,
|
|
190
|
+
sync_uuid: null,
|
|
191
|
+
sync_hlc: null,
|
|
192
|
+
sync_origin_device: null,
|
|
193
|
+
sync_is_tombstone: 0,
|
|
194
|
+
sync_version: 1,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
getSessionNodesByLineageId(lineageId, limit) {
|
|
198
|
+
const limitClause = limit !== undefined ? ' LIMIT ?' : '';
|
|
199
|
+
const sql = `SELECT * FROM nodes WHERE lineage_id = ? AND node_type = 'session' ORDER BY id DESC${limitClause}`;
|
|
200
|
+
const params = limit !== undefined ? [lineageId, limit] : [lineageId];
|
|
201
|
+
return this.getPreparedStatement(sql).all(...params);
|
|
202
|
+
}
|
|
203
|
+
getAllNodesByLineageId(lineageId, limit) {
|
|
204
|
+
const limitClause = limit !== undefined ? ' LIMIT ?' : '';
|
|
205
|
+
const sql = `SELECT * FROM nodes WHERE lineage_id = ? ORDER BY id DESC${limitClause}`;
|
|
206
|
+
const params = limit !== undefined ? [lineageId, limit] : [lineageId];
|
|
207
|
+
return this.getPreparedStatement(sql).all(...params);
|
|
208
|
+
}
|
|
209
|
+
getNodesByLineageId(lineageId, limit) {
|
|
210
|
+
return this.getSessionNodesByLineageId(lineageId, limit);
|
|
211
|
+
}
|
|
212
|
+
getNodesByLineageIds(lineageIds, limitPerLineage) {
|
|
213
|
+
if (lineageIds.length === 0) {
|
|
214
|
+
return [];
|
|
215
|
+
}
|
|
216
|
+
const placeholders = lineageIds.map(() => '?').join(', ');
|
|
217
|
+
if (limitPerLineage !== undefined) {
|
|
218
|
+
const sql = `
|
|
219
|
+
WITH ranked_nodes AS (
|
|
220
|
+
SELECT *, ROW_NUMBER() OVER (PARTITION BY lineage_id ORDER BY id DESC) AS rn
|
|
221
|
+
FROM nodes
|
|
222
|
+
WHERE lineage_id IN (${placeholders}) AND node_type = 'session'
|
|
223
|
+
)
|
|
224
|
+
SELECT
|
|
225
|
+
id, lineage_id, tool, summary, files_touched, parent_node_id,
|
|
226
|
+
created_at, node_type, sync_uuid, sync_hlc, sync_origin_device,
|
|
227
|
+
sync_is_tombstone, sync_version
|
|
228
|
+
FROM ranked_nodes
|
|
229
|
+
WHERE rn <= ?
|
|
230
|
+
ORDER BY lineage_id ASC, id DESC
|
|
231
|
+
`;
|
|
232
|
+
return this.db.prepare(sql).all(...lineageIds, limitPerLineage);
|
|
233
|
+
}
|
|
234
|
+
const sql = `
|
|
235
|
+
SELECT * FROM nodes
|
|
236
|
+
WHERE lineage_id IN (${placeholders}) AND node_type = 'session'
|
|
237
|
+
ORDER BY lineage_id ASC, id DESC
|
|
238
|
+
`;
|
|
239
|
+
return this.db.prepare(sql).all(...lineageIds);
|
|
240
|
+
}
|
|
241
|
+
searchNodes(projectId, query, lineageId, limit = 20) {
|
|
242
|
+
const trimmed = query.trim();
|
|
243
|
+
if (!trimmed) {
|
|
244
|
+
return [];
|
|
245
|
+
}
|
|
246
|
+
const safeLimit = clampSearchLimit(limit);
|
|
247
|
+
const pattern = `%${escapeLikeWildcards(trimmed)}%`;
|
|
248
|
+
let sql = `
|
|
249
|
+
SELECT
|
|
250
|
+
n.id,
|
|
251
|
+
n.lineage_id,
|
|
252
|
+
l.name AS lineage_name,
|
|
253
|
+
l.project_id,
|
|
254
|
+
n.tool,
|
|
255
|
+
n.summary,
|
|
256
|
+
n.files_touched,
|
|
257
|
+
n.created_at,
|
|
258
|
+
n.node_type
|
|
259
|
+
FROM nodes n
|
|
260
|
+
JOIN lineages l ON n.lineage_id = l.id
|
|
261
|
+
WHERE l.project_id = ?
|
|
262
|
+
AND n.node_type = 'session'
|
|
263
|
+
AND (
|
|
264
|
+
n.summary LIKE ? ESCAPE '\\'
|
|
265
|
+
OR (n.files_touched IS NOT NULL AND n.files_touched LIKE ? ESCAPE '\\')
|
|
266
|
+
)
|
|
267
|
+
`;
|
|
268
|
+
const params = [projectId, pattern, pattern];
|
|
269
|
+
if (lineageId !== undefined) {
|
|
270
|
+
sql += ` AND n.lineage_id = ?`;
|
|
271
|
+
params.push(lineageId);
|
|
272
|
+
}
|
|
273
|
+
sql += ` ORDER BY n.id DESC LIMIT ?`;
|
|
274
|
+
params.push(safeLimit);
|
|
275
|
+
const stmt = this.db.prepare(sql);
|
|
276
|
+
return stmt.all(...params);
|
|
277
|
+
}
|
|
278
|
+
getSessionNodesByTouchedFiles(projectId, filePaths, lineageId, limit = 50) {
|
|
279
|
+
const targets = filePaths
|
|
280
|
+
.map((file) => file.trim())
|
|
281
|
+
.filter((file) => file.length > 0);
|
|
282
|
+
if (targets.length === 0) {
|
|
283
|
+
return [];
|
|
284
|
+
}
|
|
285
|
+
const matchClauses = targets
|
|
286
|
+
.map(() => `(n.files_touched LIKE ? ESCAPE '\\')`)
|
|
287
|
+
.join(' OR ');
|
|
288
|
+
let sql = `
|
|
289
|
+
SELECT n.*
|
|
290
|
+
FROM nodes n
|
|
291
|
+
JOIN lineages l ON n.lineage_id = l.id
|
|
292
|
+
WHERE l.project_id = ?
|
|
293
|
+
AND n.node_type = 'session'
|
|
294
|
+
AND n.files_touched IS NOT NULL
|
|
295
|
+
AND (${matchClauses})
|
|
296
|
+
`;
|
|
297
|
+
const params = [
|
|
298
|
+
projectId,
|
|
299
|
+
...targets.map((file) => `%${escapeLikeWildcards(file)}%`),
|
|
300
|
+
];
|
|
301
|
+
if (lineageId !== undefined) {
|
|
302
|
+
sql += ` AND n.lineage_id = ?`;
|
|
303
|
+
params.push(lineageId);
|
|
304
|
+
}
|
|
305
|
+
sql += ` ORDER BY n.id DESC LIMIT ?`;
|
|
306
|
+
params.push(clampSearchLimit(limit));
|
|
307
|
+
return this.db.prepare(sql).all(...params);
|
|
308
|
+
}
|
|
309
|
+
getLatestNodeByLineageId(lineageId) {
|
|
310
|
+
const stmt = this.getPreparedStatement('SELECT * FROM nodes WHERE lineage_id = ? ORDER BY id DESC LIMIT 1');
|
|
311
|
+
return stmt.get(lineageId);
|
|
312
|
+
}
|
|
313
|
+
getNodeById(id) {
|
|
314
|
+
const stmt = this.getPreparedStatement('SELECT * FROM nodes WHERE id = ?');
|
|
315
|
+
return stmt.get(id);
|
|
316
|
+
}
|
|
317
|
+
findNodesByIds(nodeIds) {
|
|
318
|
+
if (nodeIds.length === 0) {
|
|
319
|
+
return [];
|
|
320
|
+
}
|
|
321
|
+
const placeholders = nodeIds.map(() => '?').join(', ');
|
|
322
|
+
return this.db.prepare(`SELECT * FROM nodes WHERE id IN (${placeholders})`).all(...nodeIds);
|
|
323
|
+
}
|
|
324
|
+
countNodesByLineageId(lineageId) {
|
|
325
|
+
const stmt = this.getPreparedStatement("SELECT COUNT(*) as count FROM nodes WHERE lineage_id = ? AND node_type = 'session'");
|
|
326
|
+
const row = stmt.get(lineageId);
|
|
327
|
+
return Number(row.count);
|
|
328
|
+
}
|
|
329
|
+
countNodesByLineageIds(lineageIds) {
|
|
330
|
+
if (lineageIds.length === 0) {
|
|
331
|
+
return [];
|
|
332
|
+
}
|
|
333
|
+
// Prepared fresh on every call: the placeholder count varies with input
|
|
334
|
+
// length, so a shared cached statement cannot serve all shapes.
|
|
335
|
+
const placeholders = lineageIds.map(() => '?').join(', ');
|
|
336
|
+
const stmt = this.db.prepare(`SELECT lineage_id, COUNT(*) as count FROM nodes WHERE lineage_id IN (${placeholders}) AND node_type = 'session' GROUP BY lineage_id`);
|
|
337
|
+
return stmt.all(...lineageIds);
|
|
338
|
+
}
|
|
339
|
+
findLineageIdsByNodeIds(nodeIds) {
|
|
340
|
+
if (nodeIds.length === 0) {
|
|
341
|
+
return [];
|
|
342
|
+
}
|
|
343
|
+
const placeholders = nodeIds.map(() => '?').join(', ');
|
|
344
|
+
const stmt = this.db.prepare(`SELECT id, lineage_id FROM nodes WHERE id IN (${placeholders})`);
|
|
345
|
+
return stmt.all(...nodeIds);
|
|
346
|
+
}
|
|
347
|
+
createRollupRow(lineageId, fromNodeId, toNodeId, rollupNodeId, createdAt) {
|
|
348
|
+
const stmt = this.db.prepare(`
|
|
349
|
+
INSERT INTO node_rollups (id, lineage_id, from_node_id, to_node_id, created_at)
|
|
350
|
+
VALUES (?, ?, ?, ?, ?)
|
|
351
|
+
`);
|
|
352
|
+
stmt.run(rollupNodeId, lineageId, fromNodeId, toNodeId, createdAt);
|
|
353
|
+
return {
|
|
354
|
+
id: rollupNodeId,
|
|
355
|
+
lineage_id: lineageId,
|
|
356
|
+
from_node_id: fromNodeId,
|
|
357
|
+
to_node_id: toNodeId,
|
|
358
|
+
created_at: createdAt,
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
getRollupsByLineageId(lineageId) {
|
|
362
|
+
const stmt = this.getPreparedStatement('SELECT * FROM node_rollups WHERE lineage_id = ? ORDER BY from_node_id ASC');
|
|
363
|
+
return stmt.all(lineageId);
|
|
364
|
+
}
|
|
365
|
+
createTodoRow(projectId, text, lineageId, originNodeId, planId) {
|
|
366
|
+
const createdAt = new Date().toISOString();
|
|
367
|
+
const stmt = this.db.prepare('INSERT INTO todos (project_id, lineage_id, origin_node_id, plan_id, text, done, created_at, done_at, sync_uuid, sync_hlc, sync_origin_device, sync_is_tombstone, sync_version) VALUES (?, ?, ?, ?, ?, 0, ?, NULL, NULL, NULL, NULL, 0, 1)');
|
|
368
|
+
const info = stmt.run(projectId, lineageId ?? null, originNodeId ?? null, planId ?? null, text, createdAt);
|
|
369
|
+
return {
|
|
370
|
+
id: Number(info.lastInsertRowid),
|
|
371
|
+
project_id: projectId,
|
|
372
|
+
lineage_id: lineageId ?? null,
|
|
373
|
+
origin_node_id: originNodeId ?? null,
|
|
374
|
+
plan_id: planId ?? null,
|
|
375
|
+
text,
|
|
376
|
+
done: 0,
|
|
377
|
+
created_at: createdAt,
|
|
378
|
+
done_at: null,
|
|
379
|
+
sync_uuid: null,
|
|
380
|
+
sync_hlc: null,
|
|
381
|
+
sync_origin_device: null,
|
|
382
|
+
sync_is_tombstone: 0,
|
|
383
|
+
sync_version: 1,
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
findOpenTodosByProjectId(projectId, lineageId, limit) {
|
|
387
|
+
const lineageClause = buildLineageFilterClause(lineageId);
|
|
388
|
+
const limitClause = limit !== undefined ? ' LIMIT ?' : '';
|
|
389
|
+
const sql = `SELECT * FROM todos WHERE project_id = ? AND done = 0${lineageClause} ORDER BY created_at ASC, id ASC${limitClause}`;
|
|
390
|
+
const params = [
|
|
391
|
+
projectId,
|
|
392
|
+
...(lineageId !== undefined ? [lineageId] : []),
|
|
393
|
+
...(limit !== undefined ? [limit] : []),
|
|
394
|
+
];
|
|
395
|
+
return this.getPreparedStatement(sql).all(...params);
|
|
396
|
+
}
|
|
397
|
+
countOpenTodosByProjectId(projectId, lineageId) {
|
|
398
|
+
const lineageClause = buildLineageFilterClause(lineageId);
|
|
399
|
+
const sql = `SELECT COUNT(*) as count FROM todos WHERE project_id = ? AND done = 0${lineageClause}`;
|
|
400
|
+
const params = lineageId !== undefined ? [projectId, lineageId] : [projectId];
|
|
401
|
+
const row = this.getPreparedStatement(sql).get(...params);
|
|
402
|
+
return Number(row.count);
|
|
403
|
+
}
|
|
404
|
+
markTodoDoneRow(id, doneAt) {
|
|
405
|
+
const stmt = this.db.prepare('UPDATE todos SET done = 1, done_at = ? WHERE id = ?');
|
|
406
|
+
const info = stmt.run(doneAt, id);
|
|
407
|
+
assertRowAffected(info.changes, 'Todo', id);
|
|
408
|
+
return this.getTodoById(id);
|
|
409
|
+
}
|
|
410
|
+
markTodoDoneById(id, doneAt) {
|
|
411
|
+
return this.markTodoDoneRow(id, doneAt);
|
|
412
|
+
}
|
|
413
|
+
getTodoById(id) {
|
|
414
|
+
const stmt = this.getPreparedStatement('SELECT * FROM todos WHERE id = ?');
|
|
415
|
+
return stmt.get(id);
|
|
416
|
+
}
|
|
417
|
+
createKnowledgeRow(projectId, category, fact, why, originNodeId, supersedesId) {
|
|
418
|
+
const createdAt = new Date().toISOString();
|
|
419
|
+
const stmt = this.db.prepare(`
|
|
420
|
+
INSERT INTO knowledge (
|
|
421
|
+
project_id, category, fact, why, origin_node_id, supersedes_id,
|
|
422
|
+
status, created_at, last_referenced_at, legacy_reference_count,
|
|
423
|
+
conflicted_at, conflicted_reason, resolved_at, resolved_by, resolution_knowledge_id,
|
|
424
|
+
sync_uuid, sync_hlc, sync_origin_device, sync_is_tombstone, sync_version
|
|
425
|
+
) VALUES (?, ?, ?, ?, ?, ?, 'active', ?, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 1)
|
|
426
|
+
`);
|
|
427
|
+
const info = stmt.run(projectId, category, fact, why, originNodeId ?? null, supersedesId ?? null, createdAt);
|
|
428
|
+
return {
|
|
429
|
+
id: Number(info.lastInsertRowid),
|
|
430
|
+
project_id: projectId,
|
|
431
|
+
category,
|
|
432
|
+
fact,
|
|
433
|
+
why,
|
|
434
|
+
origin_node_id: originNodeId ?? null,
|
|
435
|
+
supersedes_id: supersedesId ?? null,
|
|
436
|
+
status: 'active',
|
|
437
|
+
created_at: createdAt,
|
|
438
|
+
last_referenced_at: null,
|
|
439
|
+
legacy_reference_count: 0,
|
|
440
|
+
conflicted_at: null,
|
|
441
|
+
conflicted_reason: null,
|
|
442
|
+
resolved_at: null,
|
|
443
|
+
resolved_by: null,
|
|
444
|
+
resolution_knowledge_id: null,
|
|
445
|
+
sync_uuid: null,
|
|
446
|
+
sync_hlc: null,
|
|
447
|
+
sync_origin_device: null,
|
|
448
|
+
sync_is_tombstone: 0,
|
|
449
|
+
sync_version: 1,
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
markKnowledgeSupersededRow(id) {
|
|
453
|
+
const stmt = this.db.prepare("UPDATE knowledge SET status = 'superseded' WHERE id = ?");
|
|
454
|
+
const info = stmt.run(id);
|
|
455
|
+
assertRowAffected(info.changes, 'Knowledge', id);
|
|
456
|
+
}
|
|
457
|
+
linkKnowledgeToOriginNodeRow(knowledgeId, originNodeId) {
|
|
458
|
+
const stmt = this.db.prepare('UPDATE knowledge SET origin_node_id = ? WHERE id = ?');
|
|
459
|
+
const info = stmt.run(originNodeId, knowledgeId);
|
|
460
|
+
assertRowAffected(info.changes, 'Knowledge', knowledgeId);
|
|
461
|
+
}
|
|
462
|
+
markKnowledgeConflictedRow(id, conflictedAt, reason) {
|
|
463
|
+
const stmt = this.db.prepare(`
|
|
464
|
+
UPDATE knowledge SET
|
|
465
|
+
status = 'conflicted',
|
|
466
|
+
conflicted_at = ?,
|
|
467
|
+
conflicted_reason = ?
|
|
468
|
+
WHERE id = ?
|
|
469
|
+
`);
|
|
470
|
+
const info = stmt.run(conflictedAt, reason, id);
|
|
471
|
+
assertRowAffected(info.changes, 'Knowledge', id);
|
|
472
|
+
}
|
|
473
|
+
resolveKnowledgeConflictRow(id, resolvedAt, resolvedBy, resolutionKnowledgeId, newStatus) {
|
|
474
|
+
const stmt = this.db.prepare(`
|
|
475
|
+
UPDATE knowledge SET
|
|
476
|
+
status = ?,
|
|
477
|
+
resolved_at = ?,
|
|
478
|
+
resolved_by = ?,
|
|
479
|
+
resolution_knowledge_id = ?
|
|
480
|
+
WHERE id = ?
|
|
481
|
+
`);
|
|
482
|
+
const info = stmt.run(newStatus, resolvedAt, resolvedBy, resolutionKnowledgeId, id);
|
|
483
|
+
assertRowAffected(info.changes, 'Knowledge', id);
|
|
484
|
+
}
|
|
485
|
+
findActiveKnowledgeByProjectId(projectId) {
|
|
486
|
+
const stmt = this.getPreparedStatement("SELECT * FROM knowledge WHERE project_id = ? AND status = 'active' ORDER BY created_at ASC, id ASC");
|
|
487
|
+
return stmt.all(projectId);
|
|
488
|
+
}
|
|
489
|
+
findConflictedKnowledgeByProjectId(projectId) {
|
|
490
|
+
const stmt = this.getPreparedStatement("SELECT * FROM knowledge WHERE project_id = ? AND status = 'conflicted' ORDER BY created_at ASC, id ASC");
|
|
491
|
+
return stmt.all(projectId);
|
|
492
|
+
}
|
|
493
|
+
findAllKnowledgeByProjectId(projectId) {
|
|
494
|
+
const stmt = this.getPreparedStatement('SELECT * FROM knowledge WHERE project_id = ? ORDER BY created_at DESC, id DESC');
|
|
495
|
+
return stmt.all(projectId);
|
|
496
|
+
}
|
|
497
|
+
searchKnowledge(projectId, query, limit) {
|
|
498
|
+
const trimmed = query.trim();
|
|
499
|
+
if (!trimmed) {
|
|
500
|
+
return [];
|
|
501
|
+
}
|
|
502
|
+
const pattern = `%${escapeLikeWildcards(trimmed)}%`;
|
|
503
|
+
// LIKE shape varies with limit, so this stays uncached like searchNodes.
|
|
504
|
+
let sql = `
|
|
505
|
+
SELECT * FROM knowledge
|
|
506
|
+
WHERE project_id = ?
|
|
507
|
+
AND (fact LIKE ? ESCAPE '\\' OR why LIKE ? ESCAPE '\\')
|
|
508
|
+
ORDER BY created_at DESC, id DESC
|
|
509
|
+
`;
|
|
510
|
+
const params = [projectId, pattern, pattern];
|
|
511
|
+
if (limit !== undefined) {
|
|
512
|
+
sql += ' LIMIT ?';
|
|
513
|
+
params.push(clampSearchLimit(limit));
|
|
514
|
+
}
|
|
515
|
+
return this.db.prepare(sql).all(...params);
|
|
516
|
+
}
|
|
517
|
+
getKnowledgeById(id) {
|
|
518
|
+
const stmt = this.getPreparedStatement('SELECT * FROM knowledge WHERE id = ?');
|
|
519
|
+
return stmt.get(id);
|
|
520
|
+
}
|
|
521
|
+
getKnowledgeByOriginNodeIds(originNodeIds) {
|
|
522
|
+
if (originNodeIds.length === 0) {
|
|
523
|
+
return [];
|
|
524
|
+
}
|
|
525
|
+
// Prepared fresh on every call: the placeholder count varies with input
|
|
526
|
+
// length, so a shared cached statement cannot serve all shapes.
|
|
527
|
+
const placeholders = originNodeIds.map(() => '?').join(', ');
|
|
528
|
+
return this.db.prepare(`SELECT * FROM knowledge WHERE origin_node_id IN (${placeholders}) AND status != 'superseded' ORDER BY id DESC`).all(...originNodeIds);
|
|
529
|
+
}
|
|
530
|
+
createKnowledgeConfirmationRow(knowledgeId, originNodeId, tool) {
|
|
531
|
+
const confirmedAt = new Date().toISOString();
|
|
532
|
+
const stmt = this.db.prepare(`
|
|
533
|
+
INSERT INTO knowledge_confirmations (knowledge_id, origin_node_id, tool, confirmed_at, sync_uuid, sync_hlc, sync_origin_device, sync_is_tombstone, sync_version)
|
|
534
|
+
VALUES (?, ?, ?, ?, NULL, NULL, NULL, 0, 1)
|
|
535
|
+
`);
|
|
536
|
+
const info = stmt.run(knowledgeId, originNodeId ?? null, tool ?? null, confirmedAt);
|
|
537
|
+
return {
|
|
538
|
+
id: Number(info.lastInsertRowid),
|
|
539
|
+
knowledge_id: knowledgeId,
|
|
540
|
+
origin_node_id: originNodeId ?? null,
|
|
541
|
+
tool: tool ?? null,
|
|
542
|
+
confirmed_at: confirmedAt,
|
|
543
|
+
sync_uuid: null,
|
|
544
|
+
sync_hlc: null,
|
|
545
|
+
sync_origin_device: null,
|
|
546
|
+
sync_is_tombstone: 0,
|
|
547
|
+
sync_version: 1,
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
findConfirmationsByKnowledgeId(knowledgeId) {
|
|
551
|
+
const stmt = this.getPreparedStatement('SELECT * FROM knowledge_confirmations WHERE knowledge_id = ? ORDER BY confirmed_at ASC, id ASC');
|
|
552
|
+
return stmt.all(knowledgeId);
|
|
553
|
+
}
|
|
554
|
+
countConfirmationsByKnowledgeId(knowledgeId) {
|
|
555
|
+
const stmt = this.getPreparedStatement('SELECT COUNT(*) as count FROM knowledge_confirmations WHERE knowledge_id = ?');
|
|
556
|
+
const row = stmt.get(knowledgeId);
|
|
557
|
+
return Number(row.count);
|
|
558
|
+
}
|
|
559
|
+
countConfirmationsByKnowledgeIds(knowledgeIds) {
|
|
560
|
+
if (knowledgeIds.length === 0) {
|
|
561
|
+
return [];
|
|
562
|
+
}
|
|
563
|
+
// Prepared fresh on every call: the placeholder count varies with input
|
|
564
|
+
// length, so a shared cached statement cannot serve all shapes.
|
|
565
|
+
const placeholders = knowledgeIds.map(() => '?').join(', ');
|
|
566
|
+
const stmt = this.db.prepare(`SELECT knowledge_id, COUNT(*) as count FROM knowledge_confirmations WHERE knowledge_id IN (${placeholders}) GROUP BY knowledge_id`);
|
|
567
|
+
return stmt.all(...knowledgeIds);
|
|
568
|
+
}
|
|
569
|
+
createPlanRow(input) {
|
|
570
|
+
const now = new Date().toISOString();
|
|
571
|
+
const stmt = this.db.prepare(`
|
|
572
|
+
INSERT INTO plans (
|
|
573
|
+
project_id, lineage_id, title, intent, approach, definition_of_done,
|
|
574
|
+
status, created_at, updated_at,
|
|
575
|
+
completed_at, completion_summary, abandoned_at, abandonment_reason, replaced_by_plan_id,
|
|
576
|
+
sync_uuid, sync_hlc, sync_origin_device, sync_is_tombstone, sync_version
|
|
577
|
+
) VALUES (?, ?, ?, ?, ?, ?, 'active', ?, ?, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 1)
|
|
578
|
+
`);
|
|
579
|
+
const info = stmt.run(input.projectId, input.lineageId ?? null, input.title, input.intent, input.approach, input.definitionOfDone, now, now);
|
|
580
|
+
return {
|
|
581
|
+
id: Number(info.lastInsertRowid),
|
|
582
|
+
project_id: input.projectId,
|
|
583
|
+
lineage_id: input.lineageId ?? null,
|
|
584
|
+
title: input.title,
|
|
585
|
+
intent: input.intent,
|
|
586
|
+
approach: input.approach,
|
|
587
|
+
definition_of_done: input.definitionOfDone,
|
|
588
|
+
status: 'active',
|
|
589
|
+
created_at: now,
|
|
590
|
+
updated_at: now,
|
|
591
|
+
completed_at: null,
|
|
592
|
+
completion_summary: null,
|
|
593
|
+
abandoned_at: null,
|
|
594
|
+
abandonment_reason: null,
|
|
595
|
+
replaced_by_plan_id: null,
|
|
596
|
+
sync_uuid: null,
|
|
597
|
+
sync_hlc: null,
|
|
598
|
+
sync_origin_device: null,
|
|
599
|
+
sync_is_tombstone: 0,
|
|
600
|
+
sync_version: 1,
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
getPlanById(id) {
|
|
604
|
+
const stmt = this.getPreparedStatement('SELECT * FROM plans WHERE id = ?');
|
|
605
|
+
return stmt.get(id);
|
|
606
|
+
}
|
|
607
|
+
getActivePlanByProjectId(projectId) {
|
|
608
|
+
const stmt = this.getPreparedStatement("SELECT * FROM plans WHERE project_id = ? AND status = 'active' ORDER BY id ASC LIMIT 1");
|
|
609
|
+
return stmt.get(projectId);
|
|
610
|
+
}
|
|
611
|
+
getLatestPlanByProjectId(projectId) {
|
|
612
|
+
const stmt = this.getPreparedStatement('SELECT * FROM plans WHERE project_id = ? ORDER BY id DESC LIMIT 1');
|
|
613
|
+
return stmt.get(projectId);
|
|
614
|
+
}
|
|
615
|
+
getPlansByProjectId(projectId, includeInactive) {
|
|
616
|
+
const sql = includeInactive
|
|
617
|
+
? 'SELECT * FROM plans WHERE project_id = ? ORDER BY created_at ASC, id ASC'
|
|
618
|
+
: "SELECT * FROM plans WHERE project_id = ? AND status = 'active' ORDER BY created_at ASC, id ASC";
|
|
619
|
+
return this.getPreparedStatement(sql).all(projectId);
|
|
620
|
+
}
|
|
621
|
+
markPlanCompletedRow(id, summary, completedAt) {
|
|
622
|
+
const stmt = this.db.prepare(`
|
|
623
|
+
UPDATE plans SET
|
|
624
|
+
status = 'completed',
|
|
625
|
+
completion_summary = ?,
|
|
626
|
+
completed_at = ?,
|
|
627
|
+
updated_at = ?
|
|
628
|
+
WHERE id = ?
|
|
629
|
+
`);
|
|
630
|
+
const info = stmt.run(summary, completedAt, completedAt, id);
|
|
631
|
+
assertRowAffected(info.changes, 'Plan', id);
|
|
632
|
+
return this.getPlanById(id);
|
|
633
|
+
}
|
|
634
|
+
markPlanAbandonedRow(id, reason, abandonedAt) {
|
|
635
|
+
const stmt = this.db.prepare(`
|
|
636
|
+
UPDATE plans SET
|
|
637
|
+
status = 'abandoned',
|
|
638
|
+
abandonment_reason = ?,
|
|
639
|
+
abandoned_at = ?,
|
|
640
|
+
updated_at = ?
|
|
641
|
+
WHERE id = ?
|
|
642
|
+
`);
|
|
643
|
+
const info = stmt.run(reason, abandonedAt, abandonedAt, id);
|
|
644
|
+
assertRowAffected(info.changes, 'Plan', id);
|
|
645
|
+
return this.getPlanById(id);
|
|
646
|
+
}
|
|
647
|
+
markPlanReplacedRow(id, replacedByPlanId, replacedAt) {
|
|
648
|
+
const stmt = this.db.prepare(`
|
|
649
|
+
UPDATE plans SET
|
|
650
|
+
status = 'replaced',
|
|
651
|
+
replaced_by_plan_id = ?,
|
|
652
|
+
updated_at = ?
|
|
653
|
+
WHERE id = ?
|
|
654
|
+
`);
|
|
655
|
+
const info = stmt.run(replacedByPlanId, replacedAt, id);
|
|
656
|
+
assertRowAffected(info.changes, 'Plan', id);
|
|
657
|
+
return this.getPlanById(id);
|
|
658
|
+
}
|
|
659
|
+
updatePlanContentRow(id, fields, updatedAt) {
|
|
660
|
+
const { assignments, params } = buildPlanUpdateAssignments(fields);
|
|
661
|
+
assignments.push('updated_at = ?');
|
|
662
|
+
params.push(updatedAt, id);
|
|
663
|
+
const info = this.db
|
|
664
|
+
.prepare(`UPDATE plans SET ${assignments.join(', ')} WHERE id = ?`)
|
|
665
|
+
.run(...params);
|
|
666
|
+
assertRowAffected(info.changes, 'Plan', id);
|
|
667
|
+
return this.getPlanById(id);
|
|
668
|
+
}
|
|
669
|
+
getInstallationIdentity(deviceId) {
|
|
670
|
+
if (deviceId) {
|
|
671
|
+
const stmt = this.getPreparedStatement('SELECT * FROM installation_identity WHERE device_id = ?');
|
|
672
|
+
return stmt.get(deviceId);
|
|
673
|
+
}
|
|
674
|
+
return this.getPrimaryInstallationIdentity();
|
|
675
|
+
}
|
|
676
|
+
getPrimaryInstallationIdentity() {
|
|
677
|
+
const stmt = this.getPreparedStatement('SELECT * FROM installation_identity ORDER BY created_at ASC LIMIT 1');
|
|
678
|
+
return stmt.get();
|
|
679
|
+
}
|
|
680
|
+
createInstallationIdentity(deviceId, deviceName) {
|
|
681
|
+
const now = new Date().toISOString();
|
|
682
|
+
const stmt = this.db.prepare(`
|
|
683
|
+
INSERT INTO installation_identity (device_id, device_name, last_sequence, created_at)
|
|
684
|
+
VALUES (?, ?, 0, ?)
|
|
685
|
+
`);
|
|
686
|
+
stmt.run(deviceId, deviceName ?? null, now);
|
|
687
|
+
return {
|
|
688
|
+
device_id: deviceId,
|
|
689
|
+
device_name: deviceName ?? null,
|
|
690
|
+
last_sequence: 0,
|
|
691
|
+
created_at: now,
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
allocateDeviceSequence(deviceId) {
|
|
695
|
+
const stmt = this.getPreparedStatement(`
|
|
696
|
+
UPDATE installation_identity
|
|
697
|
+
SET last_sequence = last_sequence + 1
|
|
698
|
+
WHERE device_id = ?
|
|
699
|
+
RETURNING last_sequence
|
|
700
|
+
`);
|
|
701
|
+
const row = stmt.get(deviceId);
|
|
702
|
+
if (!row) {
|
|
703
|
+
throw new Error(`Installation identity for device ${deviceId} does not exist.`);
|
|
704
|
+
}
|
|
705
|
+
return row.last_sequence;
|
|
706
|
+
}
|
|
707
|
+
getHlcState(deviceId) {
|
|
708
|
+
const stmt = this.getPreparedStatement('SELECT * FROM hlc_state WHERE device_id = ?');
|
|
709
|
+
return stmt.get(deviceId);
|
|
710
|
+
}
|
|
711
|
+
upsertHlcState(deviceId, physicalTimeMs, logicalCounter, updatedAt) {
|
|
712
|
+
const stmt = this.getPreparedStatement(`
|
|
713
|
+
INSERT INTO hlc_state (device_id, physical_time_ms, logical_counter, updated_at)
|
|
714
|
+
VALUES (?, ?, ?, ?)
|
|
715
|
+
ON CONFLICT(device_id) DO UPDATE SET
|
|
716
|
+
physical_time_ms = excluded.physical_time_ms,
|
|
717
|
+
logical_counter = excluded.logical_counter,
|
|
718
|
+
updated_at = excluded.updated_at
|
|
719
|
+
`);
|
|
720
|
+
stmt.run(deviceId, physicalTimeMs, logicalCounter, updatedAt);
|
|
721
|
+
return {
|
|
722
|
+
device_id: deviceId,
|
|
723
|
+
physical_time_ms: physicalTimeMs,
|
|
724
|
+
logical_counter: logicalCounter,
|
|
725
|
+
updated_at: updatedAt,
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
createExternalEventRow(row) {
|
|
729
|
+
const stmt = this.db.prepare(`
|
|
730
|
+
INSERT INTO external_events (
|
|
731
|
+
project_id, external_event_id, source_system, event_type,
|
|
732
|
+
source_record, occurred_at, ingested_at, created_at,
|
|
733
|
+
canonical_entity_type, canonical_entity_id
|
|
734
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
735
|
+
`);
|
|
736
|
+
const info = stmt.run(row.project_id, row.external_event_id, row.source_system, row.event_type, row.source_record, row.occurred_at, row.ingested_at, row.created_at, row.canonical_entity_type ?? null, row.canonical_entity_id ?? null);
|
|
737
|
+
return {
|
|
738
|
+
id: Number(info.lastInsertRowid),
|
|
739
|
+
...row,
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
findExternalEvent(projectId, sourceSystem, externalEventId) {
|
|
743
|
+
const stmt = this.db.prepare(`
|
|
744
|
+
SELECT * FROM external_events
|
|
745
|
+
WHERE project_id = ? AND source_system = ? AND external_event_id = ?
|
|
746
|
+
`);
|
|
747
|
+
return stmt.get(projectId, sourceSystem, externalEventId);
|
|
748
|
+
}
|
|
749
|
+
findExternalEventById(id) {
|
|
750
|
+
const stmt = this.db.prepare('SELECT * FROM external_events WHERE id = ?');
|
|
751
|
+
return stmt.get(id);
|
|
752
|
+
}
|
|
753
|
+
linkExternalEventCanonical(id, canonicalEntityType, canonicalEntityId) {
|
|
754
|
+
const stmt = this.db.prepare(`
|
|
755
|
+
UPDATE external_events
|
|
756
|
+
SET canonical_entity_type = ?, canonical_entity_id = ?
|
|
757
|
+
WHERE id = ?
|
|
758
|
+
`);
|
|
759
|
+
stmt.run(canonicalEntityType, canonicalEntityId, id);
|
|
760
|
+
}
|
|
761
|
+
listExternalEventsByProject(projectId) {
|
|
762
|
+
const stmt = this.db.prepare('SELECT * FROM external_events WHERE project_id = ? ORDER BY occurred_at DESC, id DESC');
|
|
763
|
+
return stmt.all(projectId);
|
|
764
|
+
}
|
|
765
|
+
upsertEmbeddingRow(row) {
|
|
766
|
+
const stmt = this.db.prepare(`
|
|
767
|
+
INSERT INTO embeddings (
|
|
768
|
+
entity_type, entity_id, model_id, dimensions, content_hash, metric, normalization_version, vector, created_at
|
|
769
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
770
|
+
ON CONFLICT(entity_type, entity_id, model_id) DO UPDATE SET
|
|
771
|
+
dimensions = excluded.dimensions,
|
|
772
|
+
content_hash = excluded.content_hash,
|
|
773
|
+
metric = excluded.metric,
|
|
774
|
+
normalization_version = excluded.normalization_version,
|
|
775
|
+
vector = excluded.vector,
|
|
776
|
+
created_at = excluded.created_at
|
|
777
|
+
`);
|
|
778
|
+
const info = stmt.run(row.entity_type, row.entity_id, row.model_id, row.dimensions, row.content_hash, row.metric, row.normalization_version, row.vector, row.created_at);
|
|
779
|
+
return {
|
|
780
|
+
id: Number(info.lastInsertRowid || 0),
|
|
781
|
+
...row,
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
findEmbedding(entityType, entityId, modelId) {
|
|
785
|
+
const stmt = this.db.prepare(`
|
|
786
|
+
SELECT * FROM embeddings
|
|
787
|
+
WHERE entity_type = ? AND entity_id = ? AND model_id = ?
|
|
788
|
+
`);
|
|
789
|
+
return stmt.get(entityType, entityId, modelId);
|
|
790
|
+
}
|
|
791
|
+
listEmbeddingsForEntities(entityType, entityIds, modelId) {
|
|
792
|
+
if (entityIds.length === 0) {
|
|
793
|
+
return [];
|
|
794
|
+
}
|
|
795
|
+
const placeholders = entityIds.map(() => '?').join(', ');
|
|
796
|
+
const stmt = this.db.prepare(`
|
|
797
|
+
SELECT * FROM embeddings
|
|
798
|
+
WHERE entity_type = ? AND model_id = ? AND entity_id IN (${placeholders})
|
|
799
|
+
`);
|
|
800
|
+
return stmt.all(entityType, modelId, ...entityIds);
|
|
801
|
+
}
|
|
802
|
+
deleteEmbedding(entityType, entityId, modelId) {
|
|
803
|
+
const stmt = this.db.prepare(`
|
|
804
|
+
DELETE FROM embeddings
|
|
805
|
+
WHERE entity_type = ? AND entity_id = ? AND model_id = ?
|
|
806
|
+
`);
|
|
807
|
+
stmt.run(entityType, entityId, modelId);
|
|
808
|
+
}
|
|
809
|
+
createSyncChangeRow(row) {
|
|
810
|
+
const stmt = this.db.prepare(`
|
|
811
|
+
INSERT INTO sync_changes (
|
|
812
|
+
project_key, origin_device_id, origin_sequence, entity_type, entity_uuid,
|
|
813
|
+
operation, payload, hlc_timestamp, created_at
|
|
814
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
815
|
+
`);
|
|
816
|
+
const info = stmt.run(row.project_key, row.origin_device_id, row.origin_sequence, row.entity_type, row.entity_uuid, row.operation, row.payload, row.hlc_timestamp, row.created_at);
|
|
817
|
+
return {
|
|
818
|
+
id: Number(info.lastInsertRowid),
|
|
819
|
+
...row,
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
findSyncChange(originDeviceId, originSequence) {
|
|
823
|
+
const stmt = this.db.prepare(`
|
|
824
|
+
SELECT * FROM sync_changes
|
|
825
|
+
WHERE origin_device_id = ? AND origin_sequence = ?
|
|
826
|
+
`);
|
|
827
|
+
return stmt.get(originDeviceId, originSequence);
|
|
828
|
+
}
|
|
829
|
+
listSyncChangesByProject(projectKey) {
|
|
830
|
+
const stmt = this.db.prepare('SELECT * FROM sync_changes WHERE project_key = ? ORDER BY id ASC');
|
|
831
|
+
return stmt.all(projectKey);
|
|
832
|
+
}
|
|
833
|
+
countSyncChangesByProject(projectKey) {
|
|
834
|
+
const stmt = this.getPreparedStatement('SELECT COUNT(*) as count FROM sync_changes WHERE project_key = ?');
|
|
835
|
+
const row = stmt.get(projectKey);
|
|
836
|
+
return Number(row?.count ?? 0);
|
|
837
|
+
}
|
|
838
|
+
listSyncChangesAfter(projectKey, originDeviceId, afterSequence) {
|
|
839
|
+
const stmt = this.db.prepare(`
|
|
840
|
+
SELECT * FROM sync_changes
|
|
841
|
+
WHERE project_key = ? AND origin_device_id = ? AND origin_sequence > ?
|
|
842
|
+
ORDER BY origin_sequence ASC
|
|
843
|
+
`);
|
|
844
|
+
return stmt.all(projectKey, originDeviceId, afterSequence);
|
|
845
|
+
}
|
|
846
|
+
createSyncDeferredChangeRow(row) {
|
|
847
|
+
const stmt = this.db.prepare(`
|
|
848
|
+
INSERT INTO sync_deferred_changes (
|
|
849
|
+
project_key, origin_device_id, origin_sequence, entity_type, entity_uuid,
|
|
850
|
+
missing_dependencies, payload, hlc_timestamp, created_at
|
|
851
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
852
|
+
`);
|
|
853
|
+
const info = stmt.run(row.project_key, row.origin_device_id, row.origin_sequence, row.entity_type, row.entity_uuid, row.missing_dependencies, row.payload, row.hlc_timestamp, row.created_at);
|
|
854
|
+
return {
|
|
855
|
+
id: Number(info.lastInsertRowid),
|
|
856
|
+
...row,
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
findSyncDeferredChange(originDeviceId, originSequence) {
|
|
860
|
+
const stmt = this.db.prepare(`
|
|
861
|
+
SELECT * FROM sync_deferred_changes
|
|
862
|
+
WHERE origin_device_id = ? AND origin_sequence = ?
|
|
863
|
+
`);
|
|
864
|
+
return stmt.get(originDeviceId, originSequence);
|
|
865
|
+
}
|
|
866
|
+
listSyncDeferredChangesByProject(projectKey) {
|
|
867
|
+
const stmt = this.db.prepare('SELECT * FROM sync_deferred_changes WHERE project_key = ? ORDER BY id ASC');
|
|
868
|
+
return stmt.all(projectKey);
|
|
869
|
+
}
|
|
870
|
+
countSyncDeferredChangesByProject(projectKey) {
|
|
871
|
+
const stmt = this.getPreparedStatement('SELECT COUNT(*) as count FROM sync_deferred_changes WHERE project_key = ?');
|
|
872
|
+
const row = stmt.get(projectKey);
|
|
873
|
+
return Number(row?.count ?? 0);
|
|
874
|
+
}
|
|
875
|
+
deleteSyncDeferredChange(originDeviceId, originSequence) {
|
|
876
|
+
const stmt = this.db.prepare(`
|
|
877
|
+
DELETE FROM sync_deferred_changes
|
|
878
|
+
WHERE origin_device_id = ? AND origin_sequence = ?
|
|
879
|
+
`);
|
|
880
|
+
stmt.run(originDeviceId, originSequence);
|
|
881
|
+
}
|
|
882
|
+
findLocalIdBySyncUuid(table, syncUuid) {
|
|
883
|
+
assertValidSyncTable(table);
|
|
884
|
+
const stmt = this.db.prepare(`SELECT id FROM ${table} WHERE sync_uuid = ?`);
|
|
885
|
+
const row = stmt.get(syncUuid);
|
|
886
|
+
return row?.id;
|
|
887
|
+
}
|
|
888
|
+
findSyncUuidByLocalId(table, id) {
|
|
889
|
+
assertValidSyncTable(table);
|
|
890
|
+
const stmt = this.db.prepare(`SELECT sync_uuid FROM ${table} WHERE id = ?`);
|
|
891
|
+
const row = stmt.get(id);
|
|
892
|
+
return row?.sync_uuid ?? undefined;
|
|
893
|
+
}
|
|
894
|
+
findEntityBySyncUuid(table, syncUuid) {
|
|
895
|
+
assertValidSyncTable(table);
|
|
896
|
+
const stmt = this.db.prepare(`SELECT * FROM ${table} WHERE sync_uuid = ?`);
|
|
897
|
+
return stmt.get(syncUuid);
|
|
898
|
+
}
|
|
899
|
+
updateEntitySyncMetadata(table, id, syncUuid, syncHlc, syncOriginDevice, isTombstone, syncVersion) {
|
|
900
|
+
assertValidSyncTable(table);
|
|
901
|
+
const stmt = this.db.prepare(`
|
|
902
|
+
UPDATE ${table}
|
|
903
|
+
SET sync_uuid = ?, sync_hlc = ?, sync_origin_device = ?, sync_is_tombstone = ?, sync_version = ?
|
|
904
|
+
WHERE id = ?
|
|
905
|
+
`);
|
|
906
|
+
stmt.run(syncUuid, syncHlc, syncOriginDevice, isTombstone, syncVersion, id);
|
|
907
|
+
}
|
|
908
|
+
upsertSyncProject(key, name, pathHint, createdAt, meta) {
|
|
909
|
+
const existing = this.getPreparedStatement('SELECT * FROM projects WHERE sync_uuid = ? OR key = ?').get(meta.syncUuid, key);
|
|
910
|
+
if (existing) {
|
|
911
|
+
return this.getPreparedStatement(`UPDATE projects
|
|
912
|
+
SET name = COALESCE(?, name),
|
|
913
|
+
path_hint = COALESCE(?, path_hint),
|
|
914
|
+
sync_uuid = ?,
|
|
915
|
+
sync_hlc = ?,
|
|
916
|
+
sync_origin_device = ?,
|
|
917
|
+
sync_is_tombstone = ?,
|
|
918
|
+
sync_version = sync_version + 1
|
|
919
|
+
WHERE id = ?
|
|
920
|
+
RETURNING *`)
|
|
921
|
+
.get(name, pathHint, meta.syncUuid, meta.syncHlc, meta.syncOriginDevice, meta.isTombstone, existing.id);
|
|
922
|
+
}
|
|
923
|
+
return this.getPreparedStatement(`INSERT INTO projects (key, name, path_hint, created_at, sync_uuid, sync_hlc, sync_origin_device, sync_is_tombstone, sync_version)
|
|
924
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1)
|
|
925
|
+
RETURNING *`)
|
|
926
|
+
.get(key, name, pathHint, createdAt, meta.syncUuid, meta.syncHlc, meta.syncOriginDevice, meta.isTombstone);
|
|
927
|
+
}
|
|
928
|
+
upsertSyncLineage(projectId, name, status, createdAt, lastActiveAt, meta) {
|
|
929
|
+
const existing = this.getPreparedStatement('SELECT * FROM lineages WHERE sync_uuid = ?').get(meta.syncUuid);
|
|
930
|
+
if (existing) {
|
|
931
|
+
return this.getPreparedStatement(`UPDATE lineages
|
|
932
|
+
SET name = ?,
|
|
933
|
+
status = ?,
|
|
934
|
+
last_active_at = ?,
|
|
935
|
+
sync_hlc = ?,
|
|
936
|
+
sync_origin_device = ?,
|
|
937
|
+
sync_is_tombstone = ?,
|
|
938
|
+
sync_version = sync_version + 1
|
|
939
|
+
WHERE id = ?
|
|
940
|
+
RETURNING *`)
|
|
941
|
+
.get(name, status, lastActiveAt, meta.syncHlc, meta.syncOriginDevice, meta.isTombstone, existing.id);
|
|
942
|
+
}
|
|
943
|
+
return this.getPreparedStatement(`INSERT INTO lineages (project_id, name, status, created_at, last_active_at, sync_uuid, sync_hlc, sync_origin_device, sync_is_tombstone, sync_version)
|
|
944
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 1)
|
|
945
|
+
RETURNING *`)
|
|
946
|
+
.get(projectId, name, status, createdAt, lastActiveAt, meta.syncUuid, meta.syncHlc, meta.syncOriginDevice, meta.isTombstone);
|
|
947
|
+
}
|
|
948
|
+
upsertSyncNode(lineageId, parentNodeId, tool, summary, filesTouched, nodeType, createdAt, meta) {
|
|
949
|
+
const existing = this.getPreparedStatement('SELECT * FROM nodes WHERE sync_uuid = ?').get(meta.syncUuid);
|
|
950
|
+
if (existing) {
|
|
951
|
+
return this.getPreparedStatement(`UPDATE nodes
|
|
952
|
+
SET lineage_id = ?,
|
|
953
|
+
parent_node_id = ?,
|
|
954
|
+
tool = ?,
|
|
955
|
+
summary = ?,
|
|
956
|
+
files_touched = ?,
|
|
957
|
+
node_type = ?,
|
|
958
|
+
sync_hlc = ?,
|
|
959
|
+
sync_origin_device = ?,
|
|
960
|
+
sync_is_tombstone = ?,
|
|
961
|
+
sync_version = sync_version + 1
|
|
962
|
+
WHERE id = ?
|
|
963
|
+
RETURNING *`)
|
|
964
|
+
.get(lineageId, parentNodeId, tool, summary, filesTouched, nodeType, meta.syncHlc, meta.syncOriginDevice, meta.isTombstone, existing.id);
|
|
965
|
+
}
|
|
966
|
+
return this.getPreparedStatement(`INSERT INTO nodes (lineage_id, parent_node_id, tool, summary, files_touched, node_type, created_at, sync_uuid, sync_hlc, sync_origin_device, sync_is_tombstone, sync_version)
|
|
967
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1)
|
|
968
|
+
RETURNING *`)
|
|
969
|
+
.get(lineageId, parentNodeId, tool, summary, filesTouched, nodeType, createdAt, meta.syncUuid, meta.syncHlc, meta.syncOriginDevice, meta.isTombstone);
|
|
970
|
+
}
|
|
971
|
+
upsertSyncTodo(projectId, lineageId, originNodeId, text, done, createdAt, doneAt, meta) {
|
|
972
|
+
const existing = this.getPreparedStatement('SELECT * FROM todos WHERE sync_uuid = ?').get(meta.syncUuid);
|
|
973
|
+
if (existing) {
|
|
974
|
+
return this.getPreparedStatement(`UPDATE todos
|
|
975
|
+
SET lineage_id = ?,
|
|
976
|
+
origin_node_id = ?,
|
|
977
|
+
text = ?,
|
|
978
|
+
done = ?,
|
|
979
|
+
done_at = ?,
|
|
980
|
+
sync_hlc = ?,
|
|
981
|
+
sync_origin_device = ?,
|
|
982
|
+
sync_is_tombstone = ?,
|
|
983
|
+
sync_version = sync_version + 1
|
|
984
|
+
WHERE id = ?
|
|
985
|
+
RETURNING *`)
|
|
986
|
+
.get(lineageId, originNodeId, text, done, doneAt, meta.syncHlc, meta.syncOriginDevice, meta.isTombstone, existing.id);
|
|
987
|
+
}
|
|
988
|
+
return this.getPreparedStatement(`INSERT INTO todos (project_id, lineage_id, origin_node_id, text, done, created_at, done_at, sync_uuid, sync_hlc, sync_origin_device, sync_is_tombstone, sync_version)
|
|
989
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1)
|
|
990
|
+
RETURNING *`)
|
|
991
|
+
.get(projectId, lineageId, originNodeId, text, done, createdAt, doneAt, meta.syncUuid, meta.syncHlc, meta.syncOriginDevice, meta.isTombstone);
|
|
992
|
+
}
|
|
993
|
+
upsertSyncKnowledge(projectId, category, fact, why, originNodeId, supersedesId, status, createdAt, lastReferencedAt, legacyReferenceCount, conflictedAt, conflictedReason, resolvedAt, resolvedBy, resolutionKnowledgeId, meta) {
|
|
994
|
+
const existing = this.getPreparedStatement('SELECT * FROM knowledge WHERE sync_uuid = ?').get(meta.syncUuid);
|
|
995
|
+
if (existing) {
|
|
996
|
+
return this.getPreparedStatement(`UPDATE knowledge
|
|
997
|
+
SET category = ?,
|
|
998
|
+
fact = ?,
|
|
999
|
+
why = ?,
|
|
1000
|
+
origin_node_id = ?,
|
|
1001
|
+
supersedes_id = ?,
|
|
1002
|
+
status = ?,
|
|
1003
|
+
last_referenced_at = ?,
|
|
1004
|
+
legacy_reference_count = ?,
|
|
1005
|
+
conflicted_at = ?,
|
|
1006
|
+
conflicted_reason = ?,
|
|
1007
|
+
resolved_at = ?,
|
|
1008
|
+
resolved_by = ?,
|
|
1009
|
+
resolution_knowledge_id = ?,
|
|
1010
|
+
sync_hlc = ?,
|
|
1011
|
+
sync_origin_device = ?,
|
|
1012
|
+
sync_is_tombstone = ?,
|
|
1013
|
+
sync_version = sync_version + 1
|
|
1014
|
+
WHERE id = ?
|
|
1015
|
+
RETURNING *`)
|
|
1016
|
+
.get(category, fact, why, originNodeId, supersedesId, status, lastReferencedAt, legacyReferenceCount, conflictedAt, conflictedReason, resolvedAt, resolvedBy, resolutionKnowledgeId, meta.syncHlc, meta.syncOriginDevice, meta.isTombstone, existing.id);
|
|
1017
|
+
}
|
|
1018
|
+
return this.getPreparedStatement(`INSERT INTO knowledge (project_id, category, fact, why, origin_node_id, supersedes_id, status, created_at, last_referenced_at, legacy_reference_count, conflicted_at, conflicted_reason, resolved_at, resolved_by, resolution_knowledge_id, sync_uuid, sync_hlc, sync_origin_device, sync_is_tombstone, sync_version)
|
|
1019
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1)
|
|
1020
|
+
RETURNING *`)
|
|
1021
|
+
.get(projectId, category, fact, why, originNodeId, supersedesId, status, createdAt, lastReferencedAt, legacyReferenceCount, conflictedAt, conflictedReason, resolvedAt, resolvedBy, resolutionKnowledgeId, meta.syncUuid, meta.syncHlc, meta.syncOriginDevice, meta.isTombstone);
|
|
1022
|
+
}
|
|
1023
|
+
upsertSyncConfirmation(knowledgeId, originNodeId, tool, confirmedAt, meta) {
|
|
1024
|
+
const existing = this.getPreparedStatement('SELECT * FROM knowledge_confirmations WHERE sync_uuid = ?').get(meta.syncUuid);
|
|
1025
|
+
if (existing) {
|
|
1026
|
+
return this.getPreparedStatement(`UPDATE knowledge_confirmations
|
|
1027
|
+
SET knowledge_id = ?,
|
|
1028
|
+
origin_node_id = ?,
|
|
1029
|
+
tool = ?,
|
|
1030
|
+
confirmed_at = ?,
|
|
1031
|
+
sync_hlc = ?,
|
|
1032
|
+
sync_origin_device = ?,
|
|
1033
|
+
sync_is_tombstone = ?,
|
|
1034
|
+
sync_version = sync_version + 1
|
|
1035
|
+
WHERE id = ?
|
|
1036
|
+
RETURNING *`)
|
|
1037
|
+
.get(knowledgeId, originNodeId, tool, confirmedAt, meta.syncHlc, meta.syncOriginDevice, meta.isTombstone, existing.id);
|
|
1038
|
+
}
|
|
1039
|
+
return this.getPreparedStatement(`INSERT INTO knowledge_confirmations (knowledge_id, origin_node_id, tool, confirmed_at, sync_uuid, sync_hlc, sync_origin_device, sync_is_tombstone, sync_version)
|
|
1040
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1)
|
|
1041
|
+
RETURNING *`)
|
|
1042
|
+
.get(knowledgeId, originNodeId, tool, confirmedAt, meta.syncUuid, meta.syncHlc, meta.syncOriginDevice, meta.isTombstone);
|
|
1043
|
+
}
|
|
1044
|
+
markTombstoneBySyncUuid(table, syncUuid, syncHlc, syncOriginDevice) {
|
|
1045
|
+
assertValidSyncTable(table);
|
|
1046
|
+
const stmt = this.db.prepare(`
|
|
1047
|
+
UPDATE ${table}
|
|
1048
|
+
SET sync_is_tombstone = 1, sync_hlc = ?, sync_origin_device = ?, sync_version = sync_version + 1
|
|
1049
|
+
WHERE sync_uuid = ?
|
|
1050
|
+
`);
|
|
1051
|
+
stmt.run(syncHlc, syncOriginDevice, syncUuid);
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
//# sourceMappingURL=store.js.map
|