oh-my-second-brain 0.2.0 → 0.6.1
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/.claude-plugin/marketplace.json +41 -0
- package/{adapters/claude-code/.claude-plugin → .claude-plugin}/plugin.json +7 -8
- package/{adapters/codex/.codex-plugin → .codex-plugin}/plugin.json +4 -4
- package/ACKNOWLEDGMENTS.md +162 -0
- package/CHANGELOG-assets.md +23 -0
- package/CHANGELOG-cli.md +24 -0
- package/CHANGELOG-kernel.md +48 -0
- package/CHANGELOG-mcp.md +36 -0
- package/CHANGELOG-vendors.md +26 -0
- package/CHANGELOG.md +51 -7
- package/README.ko.md +2 -2
- package/README.md +16 -16
- package/{adapters/claude-code → assets/claude}/CLAUDE.md +4 -4
- package/{adapters → assets}/codex/AGENTS.md +3 -3
- package/{adapters → assets}/codex/rules/oms.md +5 -5
- package/{adapters → assets}/hermes/README.md +1 -1
- package/{adapters → assets}/hermes/SOUL.md +3 -3
- package/{adapters/hermes/manifest.json → assets/hermes-manifest.json} +3 -4
- package/assets/skills/distill/SKILL.md +20 -0
- package/assets/skills/doctor/SKILL.md +23 -0
- package/assets/skills/link/SKILL.md +24 -0
- package/assets/skills/search/SKILL.md +25 -0
- package/assets/skills/status/SKILL.md +22 -0
- package/assets/skills/write/SKILL.md +30 -0
- package/core/ontology/schemas/README.md +20 -14
- package/dist/assets/shared-skills.d.ts +4 -0
- package/dist/assets/shared-skills.js +8 -0
- package/dist/assets/shared-skills.js.map +1 -0
- package/dist/cli/args.d.ts +3 -1
- package/dist/cli/args.js +14 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/audit.js +3 -3
- package/dist/cli/audit.js.map +1 -1
- package/dist/cli/claude-install-plan.js +2 -2
- package/dist/cli/claude-install-plan.js.map +1 -1
- package/dist/cli/doctor-lint.js +8 -8
- package/dist/cli/doctor-lint.js.map +1 -1
- package/dist/cli/global-writeback.js +1 -1
- package/dist/cli/global-writeback.js.map +1 -1
- package/dist/cli/host-commands.d.ts +1 -1
- package/dist/cli/host-commands.js +24 -5
- package/dist/cli/host-commands.js.map +1 -1
- package/dist/cli/link-command.d.ts +1 -1
- package/dist/cli/link-command.js +2 -2
- package/dist/cli/link-command.js.map +1 -1
- package/dist/cli/linkify.js +16 -71
- package/dist/cli/linkify.js.map +1 -1
- package/dist/cli/oms.d.ts +1 -1
- package/dist/cli/oms.js +45 -11
- package/dist/cli/oms.js.map +1 -1
- package/dist/cli/semantic-args.d.ts +1 -1
- package/dist/cli/semantic-args.js +102 -3
- package/dist/cli/semantic-args.js.map +1 -1
- package/dist/cli/semantic-http.js +3 -3
- package/dist/cli/semantic-http.js.map +1 -1
- package/dist/cli/semantic-usage.js +1 -1
- package/dist/cli/semantic-usage.js.map +1 -1
- package/dist/cli/semantic.js +31 -12
- package/dist/cli/semantic.js.map +1 -1
- package/dist/cli/setup-command.d.ts +17 -0
- package/dist/cli/setup-command.js +89 -145
- package/dist/cli/setup-command.js.map +1 -1
- package/dist/cli/update-notice.d.ts +1 -1
- package/dist/cli/update-notice.js +2 -2
- package/dist/cli/update-notice.js.map +1 -1
- package/dist/cli/usage.d.ts +1 -1
- package/dist/cli/usage.js +2 -2
- package/dist/cli/usage.js.map +1 -1
- package/dist/{capture → kernel/capture}/safe.d.ts +11 -1
- package/dist/{capture → kernel/capture}/safe.js +3 -3
- package/dist/kernel/capture/safe.js.map +1 -0
- package/dist/kernel/contracts/index.d.ts +144 -0
- package/dist/kernel/contracts/index.js +401 -0
- package/dist/kernel/contracts/index.js.map +1 -0
- package/dist/kernel/conventions/frontmatter.js.map +1 -0
- package/dist/kernel/conventions/lint.js.map +1 -0
- package/dist/kernel/conventions/report.js.map +1 -0
- package/dist/{conventions → kernel/conventions}/validate.d.ts +1 -1
- package/dist/kernel/conventions/validate.js.map +1 -0
- package/dist/kernel/conventions/vault-walk.js.map +1 -0
- package/dist/{conventions → kernel/conventions}/write-contract.d.ts +1 -1
- package/dist/kernel/conventions/write-contract.js.map +1 -0
- package/dist/kernel/conventions/write-protocol.js.map +1 -0
- package/dist/kernel/doctor/service.d.ts +71 -0
- package/dist/kernel/doctor/service.js +70 -0
- package/dist/kernel/doctor/service.js.map +1 -0
- package/dist/{engine → kernel/engine}/assemble.d.ts +46 -1
- package/dist/kernel/engine/assemble.js +483 -0
- package/dist/kernel/engine/assemble.js.map +1 -0
- package/dist/kernel/engine/axes/store.d.ts +90 -0
- package/dist/kernel/engine/axes/store.js +400 -0
- package/dist/kernel/engine/axes/store.js.map +1 -0
- package/dist/{engine → kernel/engine}/conventions/vault-lint.d.ts +1 -1
- package/dist/{engine → kernel/engine}/conventions/vault-lint.js +1 -1
- package/dist/kernel/engine/conventions/vault-lint.js.map +1 -0
- package/dist/kernel/engine/embed/chunker.js.map +1 -0
- package/dist/kernel/engine/embed/deferred.js.map +1 -0
- package/dist/{engine → kernel/engine}/embed/hash-stub.test-helper.d.ts +1 -1
- package/dist/{engine → kernel/engine}/embed/hash-stub.test-helper.js +1 -1
- package/dist/kernel/engine/embed/hash-stub.test-helper.js.map +1 -0
- package/dist/kernel/engine/embed/identity.d.ts +21 -0
- package/dist/kernel/engine/embed/identity.js +47 -0
- package/dist/kernel/engine/embed/identity.js.map +1 -0
- package/dist/kernel/engine/embed/model.d.ts +134 -0
- package/dist/kernel/engine/embed/model.js +302 -0
- package/dist/kernel/engine/embed/model.js.map +1 -0
- package/dist/{engine → kernel/engine}/embed/provider.d.ts +36 -5
- package/dist/kernel/engine/embed/provider.js +403 -0
- package/dist/kernel/engine/embed/provider.js.map +1 -0
- package/dist/{engine → kernel/engine}/embed/store.d.ts +13 -1
- package/dist/kernel/engine/embed/store.js +730 -0
- package/dist/kernel/engine/embed/store.js.map +1 -0
- package/dist/kernel/engine/embed/sync.d.ts +100 -0
- package/dist/kernel/engine/embed/sync.js +753 -0
- package/dist/kernel/engine/embed/sync.js.map +1 -0
- package/dist/{engine → kernel/engine}/graph/builder.d.ts +9 -5
- package/dist/{engine → kernel/engine}/graph/builder.js +213 -79
- package/dist/kernel/engine/graph/builder.js.map +1 -0
- package/dist/kernel/engine/graph/explore.js.map +1 -0
- package/dist/{engine → kernel/engine}/graph/node.d.ts +49 -1
- package/dist/kernel/engine/graph/node.js +315 -0
- package/dist/kernel/engine/graph/node.js.map +1 -0
- package/dist/kernel/engine/graph/resolver.js.map +1 -0
- package/dist/kernel/engine/graph/traverse.js.map +1 -0
- package/dist/kernel/engine/linkify/apply.js.map +1 -0
- package/dist/kernel/engine/linkify/josa.js.map +1 -0
- package/dist/kernel/engine/linkify/mask.js.map +1 -0
- package/dist/kernel/engine/linkify/suggest.js.map +1 -0
- package/dist/kernel/engine/linkify/types.js.map +1 -0
- package/dist/{engine → kernel/engine}/mcp/facade.d.ts +27 -1
- package/dist/kernel/engine/mcp/facade.js +1144 -0
- package/dist/kernel/engine/mcp/facade.js.map +1 -0
- package/dist/kernel/engine/mcp/op-mappers.js.map +1 -0
- package/dist/{engine → kernel/engine}/mcp/query-mapper.d.ts +27 -2
- package/dist/kernel/engine/mcp/query-mapper.js +247 -0
- package/dist/kernel/engine/mcp/query-mapper.js.map +1 -0
- package/dist/{engine → kernel/engine}/mcp/types.d.ts +69 -2
- package/dist/kernel/engine/mcp/types.js.map +1 -0
- package/dist/{engine → kernel/engine}/retrieval/dispatcher.d.ts +23 -1
- package/dist/{engine → kernel/engine}/retrieval/dispatcher.js +92 -14
- package/dist/kernel/engine/retrieval/dispatcher.js.map +1 -0
- package/dist/{engine → kernel/engine}/retrieval/index.d.ts +4 -1
- package/dist/{engine → kernel/engine}/retrieval/index.js +6 -3
- package/dist/kernel/engine/retrieval/index.js.map +1 -0
- package/dist/kernel/engine/retrieval/reranker.d.ts +124 -0
- package/dist/kernel/engine/retrieval/reranker.js +204 -0
- package/dist/kernel/engine/retrieval/reranker.js.map +1 -0
- package/dist/{engine → kernel/engine}/retrieval/rrf.d.ts +10 -2
- package/dist/kernel/engine/retrieval/rrf.js +77 -0
- package/dist/kernel/engine/retrieval/rrf.js.map +1 -0
- package/dist/{engine → kernel/engine}/tracer.d.ts +13 -0
- package/dist/{engine → kernel/engine}/tracer.js +63 -6
- package/dist/kernel/engine/tracer.js.map +1 -0
- package/dist/{engine → kernel/engine}/types.d.ts +4 -4
- package/dist/kernel/engine/types.js.map +1 -0
- package/dist/{graph → kernel/graph}/cache.d.ts +1 -1
- package/dist/{graph → kernel/graph}/cache.js +165 -21
- package/dist/kernel/graph/cache.js.map +1 -0
- package/dist/kernel/graph/explore.js.map +1 -0
- package/dist/{harness → kernel/harness}/surface-registry.d.ts +0 -1
- package/dist/kernel/harness/surface-registry.js +170 -0
- package/dist/kernel/harness/surface-registry.js.map +1 -0
- package/dist/{harness → kernel/harness}/validation.js +67 -4
- package/dist/kernel/harness/validation.js.map +1 -0
- package/dist/kernel/index.d.ts +13 -0
- package/dist/kernel/index.js +14 -0
- package/dist/kernel/index.js.map +1 -0
- package/dist/{install → kernel/install}/adapter-source.d.ts +10 -1
- package/dist/kernel/install/adapter-source.js +76 -0
- package/dist/kernel/install/adapter-source.js.map +1 -0
- package/dist/kernel/install/common.js.map +1 -0
- package/dist/{install → kernel/install}/hosts.d.ts +3 -3
- package/dist/{install → kernel/install}/hosts.js +3 -22
- package/dist/kernel/install/hosts.js.map +1 -0
- package/dist/{core/ontology → kernel/install}/types.js.map +1 -1
- package/dist/{link → kernel/link}/convention-note.js +2 -2
- package/dist/kernel/link/convention-note.js.map +1 -0
- package/dist/kernel/link/global-config.js.map +1 -0
- package/dist/kernel/link/link.js.map +1 -0
- package/dist/kernel/link/workflow.d.ts +55 -0
- package/dist/kernel/link/workflow.js +107 -0
- package/dist/kernel/link/workflow.js.map +1 -0
- package/dist/kernel/measurement/no-default-contract.d.ts +17 -0
- package/dist/kernel/measurement/no-default-contract.js +84 -0
- package/dist/kernel/measurement/no-default-contract.js.map +1 -0
- package/dist/{ontology → kernel/ontology}/active.d.ts +1 -1
- package/dist/{ontology → kernel/ontology}/active.js +2 -2
- package/dist/kernel/ontology/active.js.map +1 -0
- package/dist/kernel/ontology/loader.js.map +1 -0
- package/dist/kernel/ontology/resolver.js.map +1 -0
- package/dist/{install → kernel/ontology}/types.js.map +1 -1
- package/dist/kernel/plugin/index.d.ts +1 -0
- package/dist/kernel/plugin/index.js +2 -0
- package/dist/kernel/plugin/index.js.map +1 -0
- package/dist/{core → kernel}/runtime/assets.d.ts +2 -4
- package/dist/{core → kernel}/runtime/assets.js +1 -3
- package/dist/kernel/runtime/assets.js.map +1 -0
- package/dist/kernel/search/morning-test-fixtures.js.map +1 -0
- package/dist/{retrieve → kernel/search}/morning.d.ts +0 -1
- package/dist/kernel/search/morning.js.map +1 -0
- package/dist/kernel/search/semantic-contract.js.map +1 -0
- package/dist/kernel/searchbackend/engine-search-backend.d.ts +28 -0
- package/dist/kernel/searchbackend/engine-search-backend.js +153 -0
- package/dist/kernel/searchbackend/engine-search-backend.js.map +1 -0
- package/dist/kernel/searchbackend/index.d.ts +2 -0
- package/dist/kernel/searchbackend/index.js +2 -0
- package/dist/kernel/searchbackend/index.js.map +1 -0
- package/dist/kernel/searchbackend/search-backend.d.ts +57 -0
- package/dist/kernel/searchbackend/search-backend.js +110 -0
- package/dist/kernel/searchbackend/search-backend.js.map +1 -0
- package/dist/{mcp → kernel/semantic}/semantic-engine.d.ts +3 -2
- package/dist/kernel/semantic/semantic-engine.js +78 -0
- package/dist/kernel/semantic/semantic-engine.js.map +1 -0
- package/dist/{mcp → kernel/semantic}/semantic-retrieve-args.d.ts +20 -3
- package/dist/{mcp → kernel/semantic}/semantic-retrieve-args.js +81 -15
- package/dist/kernel/semantic/semantic-retrieve-args.js.map +1 -0
- package/dist/{mcp → kernel/semantic}/semantic-retrieve-schema.d.ts +0 -24
- package/dist/{mcp → kernel/semantic}/semantic-retrieve-schema.js +0 -8
- package/dist/kernel/semantic/semantic-retrieve-schema.js.map +1 -0
- package/dist/{mcp → kernel/semantic}/semantic-retrieve.js +5 -9
- package/dist/kernel/semantic/semantic-retrieve.js.map +1 -0
- package/dist/kernel/semantic/semantic-schemas.js.map +1 -0
- package/dist/{mcp → kernel/semantic}/semantic-tool-schemas.js +0 -28
- package/dist/kernel/semantic/semantic-tool-schemas.js.map +1 -0
- package/dist/{setup → kernel/setup}/axis.d.ts +1 -1
- package/dist/{setup → kernel/setup}/axis.js +1 -1
- package/dist/kernel/setup/axis.js.map +1 -0
- package/dist/{cli/setup-documents.d.ts → kernel/setup/documents.d.ts} +1 -1
- package/dist/{cli/setup-documents.js → kernel/setup/documents.js} +15 -49
- package/dist/kernel/setup/documents.js.map +1 -0
- package/dist/kernel/setup/service.d.ts +44 -0
- package/dist/kernel/setup/service.js +97 -0
- package/dist/kernel/setup/service.js.map +1 -0
- package/dist/{update → kernel/update}/update.d.ts +7 -0
- package/dist/{update → kernel/update}/update.js +106 -8
- package/dist/kernel/update/update.js.map +1 -0
- package/dist/mcp/engine-morning-backend.d.ts +4 -4
- package/dist/mcp/engine-morning-backend.js +4 -18
- package/dist/mcp/engine-morning-backend.js.map +1 -1
- package/dist/mcp/link-tools.d.ts +9 -56
- package/dist/mcp/link-tools.js +5 -129
- package/dist/mcp/link-tools.js.map +1 -1
- package/dist/mcp/server.d.ts +9 -2
- package/dist/mcp/server.js +373 -324
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/update-notice.d.ts +1 -1
- package/dist/mcp/update-notice.js +1 -1
- package/dist/mcp/update-notice.js.map +1 -1
- package/dist/{install → vendors/claude}/claude-hooks.d.ts +1 -1
- package/dist/{install → vendors/claude}/claude-hooks.js +1 -1
- package/dist/vendors/claude/claude-hooks.js.map +1 -0
- package/dist/{install → vendors/claude}/claude-marketplace.d.ts +3 -3
- package/dist/{install → vendors/claude}/claude-marketplace.js +6 -9
- package/dist/vendors/claude/claude-marketplace.js.map +1 -0
- package/dist/{install → vendors/claude}/claude.d.ts +2 -2
- package/dist/{install → vendors/claude}/claude.js +2 -2
- package/dist/vendors/claude/claude.js.map +1 -0
- package/dist/{hook → vendors/claude/hook}/post-tool-use.js +5 -5
- package/dist/vendors/claude/hook/post-tool-use.js.map +1 -0
- package/dist/vendors/claude/hook/pre-tool-use.js.map +1 -0
- package/dist/vendors/claude/hook/stdin.js.map +1 -0
- package/dist/vendors/codex/codex.d.ts +10 -0
- package/dist/{install → vendors/codex}/codex.js +19 -37
- package/dist/vendors/codex/codex.js.map +1 -0
- package/dist/{install → vendors/hermes}/hermes.d.ts +2 -2
- package/dist/{install → vendors/hermes}/hermes.js +15 -7
- package/dist/vendors/hermes/hermes.js.map +1 -0
- package/docs/adapters.md +15 -0
- package/docs/install.md +10 -11
- package/package.json +23 -10
- package/adapters/README.md +0 -99
- package/adapters/claude-code/skills/compile/SKILL.md +0 -27
- package/adapters/claude-code/skills/define/SKILL.md +0 -51
- package/adapters/claude-code/skills/distill/SKILL.md +0 -28
- package/adapters/claude-code/skills/doctor/SKILL.md +0 -58
- package/adapters/claude-code/skills/link/SKILL.md +0 -87
- package/adapters/claude-code/skills/retrieve/SKILL.md +0 -99
- package/adapters/claude-code/skills/setup/SKILL.md +0 -78
- package/adapters/claude-code/skills/uninstall/SKILL.md +0 -34
- package/adapters/claude-code/skills/update/SKILL.md +0 -45
- package/adapters/claude-code/skills/vault-decision-record/SKILL.md +0 -52
- package/adapters/claude-code/skills/vault-lint/SKILL.md +0 -47
- package/adapters/claude-code/skills/vault-scaffold/SKILL.md +0 -47
- package/adapters/claude-code/skills/wiki/SKILL.md +0 -82
- package/adapters/claude-code/skills/write/SKILL.md +0 -16
- package/adapters/codex/skills/oms-compile/SKILL.md +0 -16
- package/adapters/codex/skills/oms-distill/SKILL.md +0 -14
- package/adapters/codex/skills/oms-doctor/SKILL.md +0 -14
- package/adapters/codex/skills/oms-install/SKILL.md +0 -19
- package/adapters/codex/skills/oms-link/SKILL.md +0 -35
- package/adapters/codex/skills/oms-retrieve/SKILL.md +0 -32
- package/adapters/codex/skills/oms-setup/SKILL.md +0 -34
- package/adapters/codex/skills/oms-uninstall/SKILL.md +0 -20
- package/adapters/codex/skills/oms-update/SKILL.md +0 -22
- package/adapters/codex/skills/oms-vault-lint/SKILL.md +0 -19
- package/adapters/codex/skills/oms-wiki/SKILL.md +0 -39
- package/adapters/codex/skills/oms-write/SKILL.md +0 -10
- package/adapters/hermes/skills/compile/SKILL.md +0 -13
- package/adapters/hermes/skills/distill/SKILL.md +0 -10
- package/adapters/hermes/skills/doctor/SKILL.md +0 -14
- package/adapters/hermes/skills/install/SKILL.md +0 -19
- package/adapters/hermes/skills/link/SKILL.md +0 -18
- package/adapters/hermes/skills/retrieve/SKILL.md +0 -32
- package/adapters/hermes/skills/setup/SKILL.md +0 -37
- package/adapters/hermes/skills/uninstall/SKILL.md +0 -20
- package/adapters/hermes/skills/update/SKILL.md +0 -22
- package/adapters/hermes/skills/wiki/SKILL.md +0 -14
- package/adapters/hermes/skills/write/SKILL.md +0 -10
- package/core/agents/librarian.md +0 -44
- package/core/agents/retriever.md +0 -62
- package/core/skills/compile/CHANGELOG.md +0 -24
- package/core/skills/compile/SKILL.md +0 -57
- package/core/skills/define/SKILL.md +0 -59
- package/core/skills/distill/CHANGELOG.md +0 -39
- package/core/skills/distill/SKILL.md +0 -62
- package/core/skills/doctor/SKILL.md +0 -49
- package/core/skills/link/SKILL.md +0 -130
- package/core/skills/retrieve/SKILL.md +0 -78
- package/core/skills/setup/CHANGELOG.md +0 -49
- package/core/skills/setup/SKILL.md +0 -246
- package/core/skills/uninstall/SKILL.md +0 -34
- package/core/skills/vault-decision-record/CHANGELOG.md +0 -24
- package/core/skills/vault-decision-record/SKILL.md +0 -93
- package/core/skills/vault-lint/CHANGELOG.md +0 -35
- package/core/skills/vault-lint/SKILL.md +0 -58
- package/core/skills/vault-scaffold/CHANGELOG.md +0 -21
- package/core/skills/vault-scaffold/SKILL.md +0 -72
- package/core/skills/wiki/CHANGELOG.md +0 -23
- package/core/skills/wiki/SKILL.md +0 -159
- package/core/skills/write/SKILL.md +0 -15
- package/dist/capture/safe.js.map +0 -1
- package/dist/cli/setup-documents.js.map +0 -1
- package/dist/conventions/frontmatter.js.map +0 -1
- package/dist/conventions/lint.js.map +0 -1
- package/dist/conventions/report.js.map +0 -1
- package/dist/conventions/validate.js.map +0 -1
- package/dist/conventions/vault-walk.js.map +0 -1
- package/dist/conventions/write-contract.js.map +0 -1
- package/dist/conventions/write-protocol.js.map +0 -1
- package/dist/core/ontology/loader.js.map +0 -1
- package/dist/core/ontology/resolver.js.map +0 -1
- package/dist/core/runtime/assets.js.map +0 -1
- package/dist/engine/assemble.js +0 -162
- package/dist/engine/assemble.js.map +0 -1
- package/dist/engine/conventions/vault-lint.js.map +0 -1
- package/dist/engine/embed/chunker.js.map +0 -1
- package/dist/engine/embed/deferred.js.map +0 -1
- package/dist/engine/embed/hash-stub.test-helper.js.map +0 -1
- package/dist/engine/embed/identity.d.ts +0 -11
- package/dist/engine/embed/identity.js +0 -15
- package/dist/engine/embed/identity.js.map +0 -1
- package/dist/engine/embed/provider.js +0 -266
- package/dist/engine/embed/provider.js.map +0 -1
- package/dist/engine/embed/store.js +0 -416
- package/dist/engine/embed/store.js.map +0 -1
- package/dist/engine/embed/sync.d.ts +0 -45
- package/dist/engine/embed/sync.js +0 -321
- package/dist/engine/embed/sync.js.map +0 -1
- package/dist/engine/graph/builder.js.map +0 -1
- package/dist/engine/graph/explore.js.map +0 -1
- package/dist/engine/graph/node.js +0 -110
- package/dist/engine/graph/node.js.map +0 -1
- package/dist/engine/graph/resolver.js.map +0 -1
- package/dist/engine/graph/traverse.js.map +0 -1
- package/dist/engine/linkify/apply.js.map +0 -1
- package/dist/engine/linkify/josa.js.map +0 -1
- package/dist/engine/linkify/mask.js.map +0 -1
- package/dist/engine/linkify/suggest.js.map +0 -1
- package/dist/engine/linkify/types.js.map +0 -1
- package/dist/engine/mcp/facade.js +0 -628
- package/dist/engine/mcp/facade.js.map +0 -1
- package/dist/engine/mcp/op-mappers.js.map +0 -1
- package/dist/engine/mcp/query-mapper.js +0 -102
- package/dist/engine/mcp/query-mapper.js.map +0 -1
- package/dist/engine/mcp/types.js.map +0 -1
- package/dist/engine/retrieval/dispatcher.js.map +0 -1
- package/dist/engine/retrieval/index.js.map +0 -1
- package/dist/engine/retrieval/reranker.d.ts +0 -46
- package/dist/engine/retrieval/reranker.js +0 -29
- package/dist/engine/retrieval/reranker.js.map +0 -1
- package/dist/engine/retrieval/rrf.js +0 -54
- package/dist/engine/retrieval/rrf.js.map +0 -1
- package/dist/engine/tracer.js.map +0 -1
- package/dist/engine/types.js.map +0 -1
- package/dist/graph/cache.js.map +0 -1
- package/dist/graph/explore.js.map +0 -1
- package/dist/harness/surface-registry.js +0 -397
- package/dist/harness/surface-registry.js.map +0 -1
- package/dist/harness/validation.js.map +0 -1
- package/dist/hook/post-tool-use.js.map +0 -1
- package/dist/hook/pre-tool-use.js.map +0 -1
- package/dist/hook/stdin.js.map +0 -1
- package/dist/index.d.ts +0 -12
- package/dist/index.js +0 -13
- package/dist/index.js.map +0 -1
- package/dist/install/adapter-source.js +0 -45
- package/dist/install/adapter-source.js.map +0 -1
- package/dist/install/claude-hooks.js.map +0 -1
- package/dist/install/claude-marketplace.js.map +0 -1
- package/dist/install/claude.js.map +0 -1
- package/dist/install/codex.d.ts +0 -24
- package/dist/install/codex.js.map +0 -1
- package/dist/install/common.js.map +0 -1
- package/dist/install/hermes.js.map +0 -1
- package/dist/install/hosts.js.map +0 -1
- package/dist/link/convention-note.js.map +0 -1
- package/dist/link/global-config.js.map +0 -1
- package/dist/link/link.js.map +0 -1
- package/dist/mcp/semantic-engine.js +0 -52
- package/dist/mcp/semantic-engine.js.map +0 -1
- package/dist/mcp/semantic-retrieve-args.js.map +0 -1
- package/dist/mcp/semantic-retrieve-schema.js.map +0 -1
- package/dist/mcp/semantic-retrieve.js.map +0 -1
- package/dist/mcp/semantic-schemas.js.map +0 -1
- package/dist/mcp/semantic-tool-schemas.js.map +0 -1
- package/dist/ontology/active.js.map +0 -1
- package/dist/retrieve/morning-test-fixtures.js.map +0 -1
- package/dist/retrieve/morning.js.map +0 -1
- package/dist/retrieve/semantic-contract.js.map +0 -1
- package/dist/setup/axis.js.map +0 -1
- package/dist/update/update.js.map +0 -1
- package/docs/release.md +0 -188
- /package/{adapters/codex/.mcp.json → .mcp.codex.json} +0 -0
- /package/{adapters/claude-code/.mcp.json → .mcp.json} +0 -0
- /package/{adapters/claude-code → assets/claude}/hooks/oms-guard.mjs +0 -0
- /package/{adapters/claude-code → assets/claude}/hooks/oms-post-guard.mjs +0 -0
- /package/dist/{conventions → kernel/conventions}/frontmatter.d.ts +0 -0
- /package/dist/{conventions → kernel/conventions}/frontmatter.js +0 -0
- /package/dist/{conventions → kernel/conventions}/lint.d.ts +0 -0
- /package/dist/{conventions → kernel/conventions}/lint.js +0 -0
- /package/dist/{conventions → kernel/conventions}/report.d.ts +0 -0
- /package/dist/{conventions → kernel/conventions}/report.js +0 -0
- /package/dist/{conventions → kernel/conventions}/validate.js +0 -0
- /package/dist/{conventions → kernel/conventions}/vault-walk.d.ts +0 -0
- /package/dist/{conventions → kernel/conventions}/vault-walk.js +0 -0
- /package/dist/{conventions → kernel/conventions}/write-contract.js +0 -0
- /package/dist/{conventions → kernel/conventions}/write-protocol.d.ts +0 -0
- /package/dist/{conventions → kernel/conventions}/write-protocol.js +0 -0
- /package/dist/{engine → kernel/engine}/embed/chunker.d.ts +0 -0
- /package/dist/{engine → kernel/engine}/embed/chunker.js +0 -0
- /package/dist/{engine → kernel/engine}/embed/deferred.d.ts +0 -0
- /package/dist/{engine → kernel/engine}/embed/deferred.js +0 -0
- /package/dist/{engine → kernel/engine}/graph/explore.d.ts +0 -0
- /package/dist/{engine → kernel/engine}/graph/explore.js +0 -0
- /package/dist/{engine → kernel/engine}/graph/resolver.d.ts +0 -0
- /package/dist/{engine → kernel/engine}/graph/resolver.js +0 -0
- /package/dist/{engine → kernel/engine}/graph/traverse.d.ts +0 -0
- /package/dist/{engine → kernel/engine}/graph/traverse.js +0 -0
- /package/dist/{engine → kernel/engine}/linkify/apply.d.ts +0 -0
- /package/dist/{engine → kernel/engine}/linkify/apply.js +0 -0
- /package/dist/{engine → kernel/engine}/linkify/josa.d.ts +0 -0
- /package/dist/{engine → kernel/engine}/linkify/josa.js +0 -0
- /package/dist/{engine → kernel/engine}/linkify/mask.d.ts +0 -0
- /package/dist/{engine → kernel/engine}/linkify/mask.js +0 -0
- /package/dist/{engine → kernel/engine}/linkify/suggest.d.ts +0 -0
- /package/dist/{engine → kernel/engine}/linkify/suggest.js +0 -0
- /package/dist/{engine → kernel/engine}/linkify/types.d.ts +0 -0
- /package/dist/{engine → kernel/engine}/linkify/types.js +0 -0
- /package/dist/{engine → kernel/engine}/mcp/op-mappers.d.ts +0 -0
- /package/dist/{engine → kernel/engine}/mcp/op-mappers.js +0 -0
- /package/dist/{engine → kernel/engine}/mcp/types.js +0 -0
- /package/dist/{engine → kernel/engine}/types.js +0 -0
- /package/dist/{graph → kernel/graph}/explore.d.ts +0 -0
- /package/dist/{graph → kernel/graph}/explore.js +0 -0
- /package/dist/{harness → kernel/harness}/validation.d.ts +0 -0
- /package/dist/{install → kernel/install}/common.d.ts +0 -0
- /package/dist/{install → kernel/install}/common.js +0 -0
- /package/dist/{install → kernel/install}/types.d.ts +0 -0
- /package/dist/{core/ontology → kernel/install}/types.js +0 -0
- /package/dist/{link → kernel/link}/convention-note.d.ts +0 -0
- /package/dist/{link → kernel/link}/global-config.d.ts +0 -0
- /package/dist/{link → kernel/link}/global-config.js +0 -0
- /package/dist/{link → kernel/link}/link.d.ts +0 -0
- /package/dist/{link → kernel/link}/link.js +0 -0
- /package/dist/{core → kernel}/ontology/loader.d.ts +0 -0
- /package/dist/{core → kernel}/ontology/loader.js +0 -0
- /package/dist/{core → kernel}/ontology/resolver.d.ts +0 -0
- /package/dist/{core → kernel}/ontology/resolver.js +0 -0
- /package/dist/{core → kernel}/ontology/types.d.ts +0 -0
- /package/dist/{install → kernel/ontology}/types.js +0 -0
- /package/dist/{retrieve → kernel/search}/morning-test-fixtures.d.ts +0 -0
- /package/dist/{retrieve → kernel/search}/morning-test-fixtures.js +0 -0
- /package/dist/{retrieve → kernel/search}/morning.js +0 -0
- /package/dist/{retrieve → kernel/search}/semantic-contract.d.ts +0 -0
- /package/dist/{retrieve → kernel/search}/semantic-contract.js +0 -0
- /package/dist/{mcp → kernel/semantic}/semantic-retrieve.d.ts +0 -0
- /package/dist/{mcp → kernel/semantic}/semantic-schemas.d.ts +0 -0
- /package/dist/{mcp → kernel/semantic}/semantic-schemas.js +0 -0
- /package/dist/{mcp → kernel/semantic}/semantic-tool-schemas.d.ts +0 -0
- /package/dist/{hook → vendors/claude/hook}/post-tool-use.d.ts +0 -0
- /package/dist/{hook → vendors/claude/hook}/pre-tool-use.d.ts +0 -0
- /package/dist/{hook → vendors/claude/hook}/pre-tool-use.js +0 -0
- /package/dist/{hook → vendors/claude/hook}/stdin.d.ts +0 -0
- /package/dist/{hook → vendors/claude/hook}/stdin.js +0 -0
|
@@ -0,0 +1,753 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vault → engine store synchronisation.
|
|
3
|
+
*
|
|
4
|
+
* RALPLAN constraints (approved):
|
|
5
|
+
* - vec/HyDE require sqlite-vec + real embeddings; no fake/hash fallback.
|
|
6
|
+
* - embed=false is a lex-only sync: it MUST NOT fabricate vectors.
|
|
7
|
+
* - Fingerprint mismatch fails fast by default; destructive rebuild only with explicit force.
|
|
8
|
+
*/
|
|
9
|
+
import { closeSync, existsSync, fsyncSync, linkSync, mkdirSync, openSync, readFileSync, renameSync, unlinkSync, writeSync, } from "node:fs";
|
|
10
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { chunkDocument } from "./chunker.js";
|
|
13
|
+
import { requireRealEmbeddingProvider } from "./provider.js";
|
|
14
|
+
import { openEngineStore, openEngineStoreCore } from "./store.js";
|
|
15
|
+
import { makeEmbeddingIdentity } from "./identity.js";
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Internal vault walker
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
const SKIP_DIRS = new Set(["node_modules", ".git", ".oms"]);
|
|
20
|
+
function isEnoent(error) {
|
|
21
|
+
return typeof error === "object" && error !== null && "code" in error &&
|
|
22
|
+
error.code === "ENOENT";
|
|
23
|
+
}
|
|
24
|
+
export async function* walkMarkdown(dir, base) {
|
|
25
|
+
let entries;
|
|
26
|
+
try {
|
|
27
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
if (isEnoent(error))
|
|
31
|
+
return;
|
|
32
|
+
throw new Error(`Unable to scan vault directory "${dir}": ${error instanceof Error ? error.message : String(error)}`, {
|
|
33
|
+
cause: error,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
for (const entry of entries) {
|
|
37
|
+
if (SKIP_DIRS.has(entry.name))
|
|
38
|
+
continue;
|
|
39
|
+
const fullPath = path.join(dir, entry.name);
|
|
40
|
+
if (entry.isDirectory()) {
|
|
41
|
+
yield* walkMarkdown(fullPath, base);
|
|
42
|
+
}
|
|
43
|
+
else if (entry.isFile() && entry.name.toLowerCase().endsWith(".md")) {
|
|
44
|
+
yield path.relative(base, fullPath).replace(/\\/g, "/");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function explicitMarkdownFiles(vault, collectionRelative, files) {
|
|
49
|
+
const selected = new Set();
|
|
50
|
+
for (const value of files) {
|
|
51
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
52
|
+
throw new Error("Embedding sync files must contain non-empty vault-relative paths.");
|
|
53
|
+
}
|
|
54
|
+
const normalized = value.replace(/\\/g, "/");
|
|
55
|
+
if (path.isAbsolute(normalized)) {
|
|
56
|
+
throw new Error("Embedding sync files must stay inside the vault.");
|
|
57
|
+
}
|
|
58
|
+
const fullPath = path.resolve(vault, normalized);
|
|
59
|
+
const relPath = path.relative(vault, fullPath).replace(/\\/g, "/");
|
|
60
|
+
if (relPath === ".." || relPath.startsWith("../") || !relPath.toLowerCase().endsWith(".md")) {
|
|
61
|
+
throw new Error(`Embedding sync file must be a markdown path inside the vault: ${value}`);
|
|
62
|
+
}
|
|
63
|
+
if (relPath.split("/").some((segment) => SKIP_DIRS.has(segment))) {
|
|
64
|
+
throw new Error(`Embedding sync file is inside an ignored vault directory: ${value}`);
|
|
65
|
+
}
|
|
66
|
+
if (!isDocumentInCollection(relPath, collectionRelative))
|
|
67
|
+
continue;
|
|
68
|
+
selected.add(relPath);
|
|
69
|
+
}
|
|
70
|
+
return [...selected].sort((left, right) => left.localeCompare(right));
|
|
71
|
+
}
|
|
72
|
+
async function* selectedMarkdownFiles(vault, collectionRoot, collectionRelative, files) {
|
|
73
|
+
if (files === undefined) {
|
|
74
|
+
yield* walkMarkdown(collectionRoot, vault);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
for (const relPath of explicitMarkdownFiles(vault, collectionRelative, files)) {
|
|
78
|
+
yield relPath;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
// Identity helpers
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
function storeHasAnyChunks(store) {
|
|
85
|
+
return store.listDocPaths().length > 0;
|
|
86
|
+
}
|
|
87
|
+
function identityEquivalent(a, b) {
|
|
88
|
+
const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
|
|
89
|
+
for (const key of keys) {
|
|
90
|
+
if (a[key] !== b[key]) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
function providerIdentityMetadata(provider) {
|
|
97
|
+
return provider;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Acquire the writer lock without a dependency on a native locking package.
|
|
101
|
+
*
|
|
102
|
+
* A complete owner payload is published through a temporary O_EXCL inode and
|
|
103
|
+
* atomically claimed with a hard link. The file records the owner PID so a
|
|
104
|
+
* process killed between claim and release does not strand every future sync.
|
|
105
|
+
* A live owner is always rejected (rather than silently waiting), which keeps
|
|
106
|
+
* concurrent writers loud and bounded.
|
|
107
|
+
*/
|
|
108
|
+
export function acquireEngineStoreWriterLock(dbPath) {
|
|
109
|
+
const lockPath = `${dbPath}.lock`;
|
|
110
|
+
const lockDir = path.dirname(lockPath);
|
|
111
|
+
mkdirSync(lockDir, { recursive: true });
|
|
112
|
+
for (;;) {
|
|
113
|
+
// Publish the owner payload through a completed temporary inode, then
|
|
114
|
+
// claim the visible path with a hard link. Unlike open(..., "wx") followed
|
|
115
|
+
// by write(), this never exposes an empty/partial lock file for stale
|
|
116
|
+
// cleanup to mistake for a dead owner.
|
|
117
|
+
const tempPath = path.join(lockDir, `.${path.basename(lockPath)}.${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}.tmp`);
|
|
118
|
+
let tempFd;
|
|
119
|
+
const ownerText = `${process.pid}\n${Date.now()}-${Math.random().toString(16).slice(2)}\n`;
|
|
120
|
+
try {
|
|
121
|
+
tempFd = openSync(tempPath, "wx");
|
|
122
|
+
const owner = Buffer.from(ownerText, "utf8");
|
|
123
|
+
writeSync(tempFd, owner, 0, owner.length, 0);
|
|
124
|
+
fsyncSync(tempFd);
|
|
125
|
+
closeSync(tempFd);
|
|
126
|
+
tempFd = undefined;
|
|
127
|
+
linkSync(tempPath, lockPath);
|
|
128
|
+
unlinkSync(tempPath);
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
const code = err.code;
|
|
132
|
+
if (tempFd !== undefined) {
|
|
133
|
+
try {
|
|
134
|
+
closeSync(tempFd);
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
// Preserve the original claim/write error.
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
unlinkSync(tempPath);
|
|
142
|
+
}
|
|
143
|
+
catch (cleanupErr) {
|
|
144
|
+
if (cleanupErr.code !== "ENOENT")
|
|
145
|
+
throw cleanupErr;
|
|
146
|
+
}
|
|
147
|
+
if (code !== "EEXIST")
|
|
148
|
+
throw err;
|
|
149
|
+
let observedLockText;
|
|
150
|
+
let ownerPid;
|
|
151
|
+
try {
|
|
152
|
+
observedLockText = readFileSync(lockPath, "utf8");
|
|
153
|
+
const ownerText = observedLockText.trim().split(/\r?\n/, 1)[0] ?? "";
|
|
154
|
+
if (/^\d+$/.test(ownerText))
|
|
155
|
+
ownerPid = Number.parseInt(ownerText, 10);
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// An unreadable lock is treated as stale.
|
|
159
|
+
}
|
|
160
|
+
if (ownerPid !== undefined && Number.isInteger(ownerPid) && ownerPid > 0) {
|
|
161
|
+
try {
|
|
162
|
+
process.kill(ownerPid, 0);
|
|
163
|
+
throw new Error(`Embedding sync is already in progress (lock: ${lockPath}).`);
|
|
164
|
+
}
|
|
165
|
+
catch (probeErr) {
|
|
166
|
+
if (probeErr.code !== "ESRCH")
|
|
167
|
+
throw probeErr;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Remove exactly the stale inode that was inspected. Renaming it away
|
|
171
|
+
// first prevents a second stale cleaner from unlinking a newly claimed
|
|
172
|
+
// lock between its read and delete operations.
|
|
173
|
+
const stalePath = path.join(lockDir, `.${path.basename(lockPath)}.stale-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`);
|
|
174
|
+
try {
|
|
175
|
+
renameSync(lockPath, stalePath);
|
|
176
|
+
}
|
|
177
|
+
catch (renameErr) {
|
|
178
|
+
if (renameErr.code === "ENOENT")
|
|
179
|
+
continue;
|
|
180
|
+
throw renameErr;
|
|
181
|
+
}
|
|
182
|
+
// Another stale cleaner may have replaced the path between our read and
|
|
183
|
+
// rename. Compare the complete owner payload (which includes a nonce for
|
|
184
|
+
// locks created here) before deleting the moved inode.
|
|
185
|
+
let movedLockText;
|
|
186
|
+
try {
|
|
187
|
+
movedLockText = readFileSync(stalePath, "utf8");
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
// Treat an unreadable moved inode as a failed identity check.
|
|
191
|
+
}
|
|
192
|
+
if (observedLockText === undefined || movedLockText !== observedLockText) {
|
|
193
|
+
let restored = false;
|
|
194
|
+
try {
|
|
195
|
+
linkSync(stalePath, lockPath);
|
|
196
|
+
restored = true;
|
|
197
|
+
}
|
|
198
|
+
catch (restoreErr) {
|
|
199
|
+
const restoreCode = restoreErr.code;
|
|
200
|
+
if (restoreCode !== "EEXIST" && restoreCode !== "ENOENT")
|
|
201
|
+
throw restoreErr;
|
|
202
|
+
}
|
|
203
|
+
if (restored) {
|
|
204
|
+
try {
|
|
205
|
+
unlinkSync(stalePath);
|
|
206
|
+
}
|
|
207
|
+
catch (unlinkErr) {
|
|
208
|
+
if (unlinkErr.code !== "ENOENT")
|
|
209
|
+
throw unlinkErr;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
try {
|
|
215
|
+
unlinkSync(stalePath);
|
|
216
|
+
}
|
|
217
|
+
catch (unlinkErr) {
|
|
218
|
+
if (unlinkErr.code !== "ENOENT") {
|
|
219
|
+
// Keep the stale inode visible when cleanup fails, unless another
|
|
220
|
+
// writer already claimed the path after the atomic rename.
|
|
221
|
+
try {
|
|
222
|
+
linkSync(stalePath, lockPath);
|
|
223
|
+
}
|
|
224
|
+
catch (restoreErr) {
|
|
225
|
+
const restoreCode = restoreErr.code;
|
|
226
|
+
if (restoreCode !== "EEXIST" && restoreCode !== "ENOENT")
|
|
227
|
+
throw restoreErr;
|
|
228
|
+
}
|
|
229
|
+
throw unlinkErr;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
let released = false;
|
|
235
|
+
return () => {
|
|
236
|
+
if (released)
|
|
237
|
+
return;
|
|
238
|
+
released = true;
|
|
239
|
+
try {
|
|
240
|
+
if (readFileSync(lockPath, "utf8") !== ownerText)
|
|
241
|
+
return;
|
|
242
|
+
unlinkSync(lockPath);
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
if (err.code !== "ENOENT")
|
|
246
|
+
throw err;
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
function crashAt(point, expected) {
|
|
252
|
+
if (point === expected) {
|
|
253
|
+
throw new Error(`Injected generation swap crash at ${expected}.`);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function formatMismatchReason(args) {
|
|
257
|
+
const stored = args.stored;
|
|
258
|
+
const cfg = args.configured;
|
|
259
|
+
const storedText = stored
|
|
260
|
+
? `stored=${stored.provider}/${stored.model} dim=${stored.dimensions} fp=${stored.fingerprint.slice(0, 12)}`
|
|
261
|
+
: "stored=<none>";
|
|
262
|
+
const cfgText = cfg
|
|
263
|
+
? `configured=${cfg.provider}/${cfg.model} dim=${cfg.dimensions} fp=${cfg.fingerprint.slice(0, 12)}`
|
|
264
|
+
: "configured=<none>";
|
|
265
|
+
return (`Embedding identity mismatch (${storedText}; ${cfgText}). ` +
|
|
266
|
+
`Rebuild vectors with ${args.forceFlagName}.`);
|
|
267
|
+
}
|
|
268
|
+
function isDocumentInCollection(docPath, collectionRoot) {
|
|
269
|
+
return collectionRoot === "" ||
|
|
270
|
+
docPath === collectionRoot ||
|
|
271
|
+
docPath.startsWith(`${collectionRoot}/`);
|
|
272
|
+
}
|
|
273
|
+
async function syncDocument(opts) {
|
|
274
|
+
let content;
|
|
275
|
+
try {
|
|
276
|
+
content = await readFile(path.join(opts.vault, opts.relPath), "utf-8");
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
opts.counters.scanned++;
|
|
282
|
+
const chunks = chunkDocument(opts.relPath, content, opts.chunkerOpts);
|
|
283
|
+
const storedShas = opts.store.getShas(opts.relPath);
|
|
284
|
+
const chunkCountChanged = storedShas.size !== chunks.length;
|
|
285
|
+
const fullRewrite = opts.rebuildAllVectors || chunkCountChanged;
|
|
286
|
+
if (!opts.shouldEmbed) {
|
|
287
|
+
// Lex-only: update meta+FTS only.
|
|
288
|
+
// When the chunk-count changes we clear and reinsert to avoid orphaned extra chunks.
|
|
289
|
+
if (fullRewrite) {
|
|
290
|
+
opts.store.clearDocument(opts.relPath);
|
|
291
|
+
opts.store.upsertLex(chunks);
|
|
292
|
+
opts.counters.added += chunks.length;
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
const toUpsert = [];
|
|
296
|
+
for (const chunk of chunks) {
|
|
297
|
+
const storedSha = storedShas.get(chunk.ordinal);
|
|
298
|
+
if (storedSha === chunk.sha) {
|
|
299
|
+
opts.counters.skipped++;
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
toUpsert.push(chunk);
|
|
303
|
+
if (storedSha === undefined)
|
|
304
|
+
opts.counters.added++;
|
|
305
|
+
else
|
|
306
|
+
opts.counters.updated++;
|
|
307
|
+
}
|
|
308
|
+
if (toUpsert.length > 0)
|
|
309
|
+
opts.store.upsertLex(toUpsert);
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
if (!opts.provider) {
|
|
313
|
+
throw new Error("Internal error: shouldEmbed=true but provider is null.");
|
|
314
|
+
}
|
|
315
|
+
// Vector path
|
|
316
|
+
if (fullRewrite) {
|
|
317
|
+
opts.store.clearDocument(opts.relPath);
|
|
318
|
+
const toUpsert = [];
|
|
319
|
+
for (const chunk of chunks) {
|
|
320
|
+
const vector = await opts.provider.embed(chunk.text);
|
|
321
|
+
toUpsert.push({ ...chunk, vector });
|
|
322
|
+
opts.counters.added++;
|
|
323
|
+
}
|
|
324
|
+
if (toUpsert.length > 0)
|
|
325
|
+
opts.store.upsert(toUpsert);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
const toUpsert = [];
|
|
329
|
+
for (const chunk of chunks) {
|
|
330
|
+
const storedSha = storedShas.get(chunk.ordinal);
|
|
331
|
+
if (storedSha === chunk.sha) {
|
|
332
|
+
opts.counters.skipped++;
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
const vector = await opts.provider.embed(chunk.text);
|
|
336
|
+
toUpsert.push({ ...chunk, vector });
|
|
337
|
+
if (storedSha === undefined)
|
|
338
|
+
opts.counters.added++;
|
|
339
|
+
else
|
|
340
|
+
opts.counters.updated++;
|
|
341
|
+
}
|
|
342
|
+
if (toUpsert.length > 0)
|
|
343
|
+
opts.store.upsert(toUpsert);
|
|
344
|
+
}
|
|
345
|
+
async function rebuildGenerationAtomically(opts) {
|
|
346
|
+
if (opts.dbPath === ":memory:") {
|
|
347
|
+
throw new Error("Atomic generation swap requires a file-backed engine store.");
|
|
348
|
+
}
|
|
349
|
+
const directory = path.dirname(opts.dbPath);
|
|
350
|
+
const base = path.basename(opts.dbPath);
|
|
351
|
+
let shadowPath;
|
|
352
|
+
let shadow = null;
|
|
353
|
+
let swapped = false;
|
|
354
|
+
let swapPreparationStarted = false;
|
|
355
|
+
try {
|
|
356
|
+
// Keep the shadow in the same directory so rename(2) is one filesystem
|
|
357
|
+
// operation. The random suffix also prevents a previous crash from
|
|
358
|
+
// colliding with a future generation.
|
|
359
|
+
for (let attempt = 0; attempt < 10; attempt += 1) {
|
|
360
|
+
const candidate = path.join(directory, `.${base}.generation-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}.sqlite`);
|
|
361
|
+
if (!existsSync(candidate)) {
|
|
362
|
+
shadowPath = candidate;
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
if (!shadowPath)
|
|
367
|
+
throw new Error("Could not allocate a shadow embedding generation path.");
|
|
368
|
+
shadow = openEngineStore(shadowPath, opts.provider.dimensions);
|
|
369
|
+
if (!shadow.capabilities().vecAvailable) {
|
|
370
|
+
throw new Error("Vector layer unavailable while building the shadow generation.");
|
|
371
|
+
}
|
|
372
|
+
const expectedDocs = new Set();
|
|
373
|
+
for await (const relPath of selectedMarkdownFiles(opts.vault, opts.collectionRoot, opts.collectionRelative, opts.files)) {
|
|
374
|
+
expectedDocs.add(relPath);
|
|
375
|
+
await syncDocument({
|
|
376
|
+
relPath,
|
|
377
|
+
vault: opts.vault,
|
|
378
|
+
store: shadow,
|
|
379
|
+
provider: opts.provider,
|
|
380
|
+
shouldEmbed: true,
|
|
381
|
+
chunkerOpts: opts.chunkerOpts,
|
|
382
|
+
counters: opts.counters,
|
|
383
|
+
rebuildAllVectors: true,
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
crashAt(opts.crashPoint, "after-build");
|
|
387
|
+
// Identity is written only to the inactive generation. The live
|
|
388
|
+
// generation remains byte-for-byte unchanged until the rename below.
|
|
389
|
+
shadow.writeEmbeddingIdentity(opts.configuredIdentity);
|
|
390
|
+
const writtenIdentity = shadow.readEmbeddingIdentity();
|
|
391
|
+
if (writtenIdentity === null || !identityEquivalent(writtenIdentity, opts.configuredIdentity)) {
|
|
392
|
+
throw new Error("Shadow embedding generation failed identity validation.");
|
|
393
|
+
}
|
|
394
|
+
const actualDocs = new Set(shadow.listDocPaths());
|
|
395
|
+
if (actualDocs.size !== expectedDocs.size || [...expectedDocs].some((doc) => !actualDocs.has(doc))) {
|
|
396
|
+
throw new Error("Shadow embedding generation failed document validation.");
|
|
397
|
+
}
|
|
398
|
+
crashAt(opts.crashPoint, "after-validation");
|
|
399
|
+
// Keep the active handle open while building and validating the shadow.
|
|
400
|
+
// Closing it only here ensures no active bytes or identity can change
|
|
401
|
+
// before validation has completed. Any long-lived reader owned by the
|
|
402
|
+
// caller must close at the same boundary so its WAL/SHM descriptors do
|
|
403
|
+
// not survive the rename.
|
|
404
|
+
swapPreparationStarted = true;
|
|
405
|
+
opts.onGenerationSwapPrepare?.();
|
|
406
|
+
opts.closeActive();
|
|
407
|
+
// close() checkpoints WAL and releases every shadow descriptor before
|
|
408
|
+
// rename. The active sidecars are removed only after every known active
|
|
409
|
+
// handle has closed; stale files from an interrupted run are harmless.
|
|
410
|
+
unlinkStaleSidecars(opts.dbPath);
|
|
411
|
+
shadow.close();
|
|
412
|
+
shadow = null;
|
|
413
|
+
crashAt(opts.crashPoint, "before-swap");
|
|
414
|
+
// rename is atomic on the same filesystem: readers observe either the
|
|
415
|
+
// complete old database or the complete new one, never a partial build.
|
|
416
|
+
// Future EAV/axis state deliberately lives in its own database and is not
|
|
417
|
+
// copied into this embedding generation.
|
|
418
|
+
unlinkStaleSidecars(shadowPath);
|
|
419
|
+
renameGeneration(shadowPath, opts.dbPath);
|
|
420
|
+
swapped = true;
|
|
421
|
+
opts.onSwap?.();
|
|
422
|
+
opts.onGenerationSwapComplete?.(true);
|
|
423
|
+
crashAt(opts.crashPoint, "after-swap");
|
|
424
|
+
}
|
|
425
|
+
finally {
|
|
426
|
+
try {
|
|
427
|
+
shadow?.close();
|
|
428
|
+
if (shadowPath && !swapped) {
|
|
429
|
+
unlinkStaleSidecars(shadowPath);
|
|
430
|
+
try {
|
|
431
|
+
unlinkSync(shadowPath);
|
|
432
|
+
}
|
|
433
|
+
catch (err) {
|
|
434
|
+
if (err.code !== "ENOENT")
|
|
435
|
+
throw err;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
finally {
|
|
440
|
+
// A crash or validation failure after preparation still closed the
|
|
441
|
+
// caller's long-lived handle. Give it a chance to rebind to the intact
|
|
442
|
+
// old generation before releasing the cross-process writer lock.
|
|
443
|
+
if (swapPreparationStarted && !swapped) {
|
|
444
|
+
opts.onGenerationSwapComplete?.(false);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
function unlinkStaleSidecars(dbPath) {
|
|
450
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
451
|
+
try {
|
|
452
|
+
unlinkSync(`${dbPath}${suffix}`);
|
|
453
|
+
}
|
|
454
|
+
catch (err) {
|
|
455
|
+
if (err.code !== "ENOENT")
|
|
456
|
+
throw err;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
function renameGeneration(shadowPath, activePath) {
|
|
461
|
+
renameSync(shadowPath, activePath);
|
|
462
|
+
}
|
|
463
|
+
// ---------------------------------------------------------------------------
|
|
464
|
+
// Public entry point
|
|
465
|
+
// ---------------------------------------------------------------------------
|
|
466
|
+
export async function syncEngineStore(opts) {
|
|
467
|
+
const vault = path.resolve(opts.vault);
|
|
468
|
+
const collection = opts.collection ?? "vault";
|
|
469
|
+
const collectionRoot = opts.collectionPath ? path.resolve(vault, opts.collectionPath) : vault;
|
|
470
|
+
const collectionRelative = path.relative(vault, collectionRoot).replace(/\\/g, "/");
|
|
471
|
+
const invalidCollectionPath = path.isAbsolute(collectionRelative) ||
|
|
472
|
+
collectionRelative === ".." ||
|
|
473
|
+
collectionRelative.startsWith("../");
|
|
474
|
+
const dbPath = opts.dbPath ?? path.join(vault, ".oms", "engine-store.sqlite");
|
|
475
|
+
const shouldEmbed = opts.embed !== false;
|
|
476
|
+
const force = opts.force === true;
|
|
477
|
+
const persist = opts.persist !== false;
|
|
478
|
+
const warnings = [];
|
|
479
|
+
let provider = null;
|
|
480
|
+
let store = opts.store ?? null;
|
|
481
|
+
const ownsStore = opts.store === undefined;
|
|
482
|
+
let storedIdentity;
|
|
483
|
+
let configuredIdentity;
|
|
484
|
+
let generationSwapped = false;
|
|
485
|
+
let releaseLock = null;
|
|
486
|
+
try {
|
|
487
|
+
if (invalidCollectionPath) {
|
|
488
|
+
throw new Error("Embedding sync collectionPath must stay inside the vault.");
|
|
489
|
+
}
|
|
490
|
+
if (!shouldEmbed) {
|
|
491
|
+
// Lex-only path: no embedding provider required.
|
|
492
|
+
if (persist)
|
|
493
|
+
releaseLock = acquireEngineStoreWriterLock(dbPath);
|
|
494
|
+
store ??= openEngineStoreCore(dbPath);
|
|
495
|
+
warnings.push("embed=false: lexical index updated; no vectors generated");
|
|
496
|
+
const counters = { scanned: 0, added: 0, updated: 0, skipped: 0 };
|
|
497
|
+
for await (const relPath of selectedMarkdownFiles(vault, collectionRoot, collectionRelative, opts.files)) {
|
|
498
|
+
await syncDocument({
|
|
499
|
+
relPath,
|
|
500
|
+
vault,
|
|
501
|
+
store,
|
|
502
|
+
provider: null,
|
|
503
|
+
shouldEmbed: false,
|
|
504
|
+
chunkerOpts: opts.chunkerOpts,
|
|
505
|
+
counters,
|
|
506
|
+
rebuildAllVectors: false,
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
return {
|
|
510
|
+
available: true,
|
|
511
|
+
warnings,
|
|
512
|
+
collection,
|
|
513
|
+
dbPath,
|
|
514
|
+
scanned: counters.scanned,
|
|
515
|
+
added: counters.added,
|
|
516
|
+
updated: counters.updated,
|
|
517
|
+
skipped: counters.skipped,
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
const descriptor = opts.embeddingDescriptor;
|
|
521
|
+
const embeddingProvider = (opts.embeddingProvider ??
|
|
522
|
+
descriptor?.provider ??
|
|
523
|
+
"").trim();
|
|
524
|
+
const embeddingModel = (opts.embeddingModel ??
|
|
525
|
+
(descriptor?.path || descriptor?.modelPath) ??
|
|
526
|
+
descriptor?.model ??
|
|
527
|
+
"").trim();
|
|
528
|
+
const embeddingDimensions = opts.embeddingDimensions ?? descriptor?.dimensions;
|
|
529
|
+
const embeddingContext = opts.embeddingContext ?? descriptor?.context;
|
|
530
|
+
const embeddingContextLength = opts.embeddingContextLength ?? descriptor?.contextLength;
|
|
531
|
+
const embeddingContextTokens = opts.embeddingContextTokens ?? descriptor?.contextTokens;
|
|
532
|
+
const embeddingMrlDim = opts.embeddingMrlDim ?? descriptor?.mrlDim;
|
|
533
|
+
const embeddingNormalization = opts.embeddingNormalization ?? descriptor?.normalization;
|
|
534
|
+
const embeddingPrefixScheme = opts.embeddingPrefixScheme ?? descriptor?.prefixScheme;
|
|
535
|
+
if (descriptor !== undefined) {
|
|
536
|
+
const descriptorContext = embeddingContext ?? embeddingContextLength ?? embeddingContextTokens;
|
|
537
|
+
if (typeof embeddingDimensions !== "number" ||
|
|
538
|
+
typeof descriptorContext !== "number" ||
|
|
539
|
+
typeof embeddingMrlDim !== "number" ||
|
|
540
|
+
typeof embeddingNormalization !== "string" ||
|
|
541
|
+
!embeddingNormalization.trim() ||
|
|
542
|
+
typeof embeddingPrefixScheme !== "string" ||
|
|
543
|
+
!embeddingPrefixScheme.trim()) {
|
|
544
|
+
throw new Error("Embedding descriptor is incomplete. dimensions/context/mrlDim/normalization/prefixScheme are required.");
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
provider = requireRealEmbeddingProvider({
|
|
548
|
+
provider: embeddingProvider,
|
|
549
|
+
model: embeddingModel,
|
|
550
|
+
dimensions: embeddingDimensions,
|
|
551
|
+
context: embeddingContext,
|
|
552
|
+
contextLength: embeddingContextLength,
|
|
553
|
+
contextTokens: embeddingContextTokens,
|
|
554
|
+
mrlDim: embeddingMrlDim,
|
|
555
|
+
normalization: embeddingNormalization,
|
|
556
|
+
prefixScheme: embeddingPrefixScheme,
|
|
557
|
+
});
|
|
558
|
+
const metadata = providerIdentityMetadata(provider);
|
|
559
|
+
const contextLength = embeddingContext ??
|
|
560
|
+
embeddingContextLength ??
|
|
561
|
+
embeddingContextTokens ??
|
|
562
|
+
metadata.context ??
|
|
563
|
+
metadata.contextLength;
|
|
564
|
+
const mrlDim = embeddingMrlDim ?? metadata.mrlDim;
|
|
565
|
+
const normalization = embeddingNormalization ?? metadata.normalization;
|
|
566
|
+
const prefixScheme = embeddingPrefixScheme ?? metadata.prefixScheme;
|
|
567
|
+
if (contextLength === undefined || mrlDim === undefined || normalization === undefined || prefixScheme === undefined) {
|
|
568
|
+
throw new Error("Embedding descriptor is incomplete. dimensions/context/mrlDim/normalization/prefixScheme are required for vector sync.");
|
|
569
|
+
}
|
|
570
|
+
const identity = makeEmbeddingIdentity({
|
|
571
|
+
provider: embeddingProvider,
|
|
572
|
+
model: embeddingModel,
|
|
573
|
+
dimensions: provider.dimensions,
|
|
574
|
+
contextLength,
|
|
575
|
+
mrlDim,
|
|
576
|
+
normalization,
|
|
577
|
+
prefixScheme,
|
|
578
|
+
});
|
|
579
|
+
configuredIdentity = identity;
|
|
580
|
+
// Lock before opening the write handle so identity inspection and every
|
|
581
|
+
// subsequent write observe one writer generation.
|
|
582
|
+
if (persist)
|
|
583
|
+
releaseLock = acquireEngineStoreWriterLock(dbPath);
|
|
584
|
+
// A caller-owned handle is used as-is and is never closed by this
|
|
585
|
+
// function. Otherwise sync owns the handle it opens below.
|
|
586
|
+
store ??= openEngineStore(dbPath, provider.dimensions);
|
|
587
|
+
if (!store.capabilities().vecAvailable) {
|
|
588
|
+
warnings.push("Vector layer unavailable: sqlite-vec not loaded");
|
|
589
|
+
return {
|
|
590
|
+
available: false,
|
|
591
|
+
reason: "Vector layer unavailable: sqlite-vec not loaded.",
|
|
592
|
+
warnings,
|
|
593
|
+
collection,
|
|
594
|
+
dbPath,
|
|
595
|
+
scanned: 0,
|
|
596
|
+
added: 0,
|
|
597
|
+
updated: 0,
|
|
598
|
+
skipped: 0,
|
|
599
|
+
configuredIdentity,
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
try {
|
|
603
|
+
storedIdentity = store.readEmbeddingIdentity() ?? undefined;
|
|
604
|
+
}
|
|
605
|
+
catch (error) {
|
|
606
|
+
// A stale metadata version is intentionally not decoded as an identity.
|
|
607
|
+
// Force mode can still rebuild it through the atomic generation path;
|
|
608
|
+
// without force, preserve the loud rejection reason.
|
|
609
|
+
if (force && error instanceof Error && /metadata version/i.test(error.message)) {
|
|
610
|
+
storedIdentity = undefined;
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
throw error;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
// If there are indexed chunks on disk but no stored identity, treat as mismatch.
|
|
617
|
+
const hasStoredChunks = storeHasAnyChunks(store);
|
|
618
|
+
const missingStoredIdentity = storedIdentity === undefined;
|
|
619
|
+
const mismatch = (storedIdentity !== undefined &&
|
|
620
|
+
!identityEquivalent(storedIdentity, identity)) ||
|
|
621
|
+
(missingStoredIdentity && hasStoredChunks);
|
|
622
|
+
if (mismatch && !force) {
|
|
623
|
+
return {
|
|
624
|
+
available: false,
|
|
625
|
+
reason: formatMismatchReason({
|
|
626
|
+
stored: storedIdentity,
|
|
627
|
+
configured: configuredIdentity,
|
|
628
|
+
forceFlagName: "--force/force:true",
|
|
629
|
+
}),
|
|
630
|
+
warnings,
|
|
631
|
+
collection,
|
|
632
|
+
dbPath,
|
|
633
|
+
scanned: 0,
|
|
634
|
+
added: 0,
|
|
635
|
+
updated: 0,
|
|
636
|
+
skipped: 0,
|
|
637
|
+
storedIdentity,
|
|
638
|
+
configuredIdentity,
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
if (mismatch && force) {
|
|
642
|
+
if (!ownsStore) {
|
|
643
|
+
throw new Error("Force reindex requires an internally-owned store; close the caller-owned handle and retry without store.");
|
|
644
|
+
}
|
|
645
|
+
if (collectionRelative !== "") {
|
|
646
|
+
const outOfScope = store.listDocPaths().filter((docPath) => !isDocumentInCollection(docPath, collectionRelative));
|
|
647
|
+
if (outOfScope.length > 0) {
|
|
648
|
+
throw new Error(`Scoped force reindex refused: ${outOfScope.length} indexed document(s) fall outside "${collectionRelative}". ` +
|
|
649
|
+
"Run an unscoped force reindex to replace the complete generation.");
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
// Build a complete shadow generation before touching the active path.
|
|
653
|
+
// Caller-owned handles are rejected above rather than being closed or
|
|
654
|
+
// left pointing at a removed table.
|
|
655
|
+
const counters = { scanned: 0, added: 0, updated: 0, skipped: 0 };
|
|
656
|
+
await rebuildGenerationAtomically({
|
|
657
|
+
dbPath,
|
|
658
|
+
vault,
|
|
659
|
+
collectionRoot,
|
|
660
|
+
collectionRelative,
|
|
661
|
+
files: opts.files,
|
|
662
|
+
provider,
|
|
663
|
+
configuredIdentity: identity,
|
|
664
|
+
chunkerOpts: opts.chunkerOpts,
|
|
665
|
+
counters,
|
|
666
|
+
crashPoint: opts.crashPoint,
|
|
667
|
+
onGenerationSwapPrepare: opts.onGenerationSwapPrepare,
|
|
668
|
+
onGenerationSwapComplete: opts.onGenerationSwapComplete,
|
|
669
|
+
onSwap: () => {
|
|
670
|
+
generationSwapped = true;
|
|
671
|
+
},
|
|
672
|
+
closeActive: () => {
|
|
673
|
+
if (!store)
|
|
674
|
+
throw new Error("Internal error: active store is already closed.");
|
|
675
|
+
store.close();
|
|
676
|
+
store = null;
|
|
677
|
+
},
|
|
678
|
+
});
|
|
679
|
+
// The active handle was intentionally closed before the atomic rename.
|
|
680
|
+
// Reopen it so callers that inspect the owned handle after the swap do
|
|
681
|
+
// not retain prepared statements bound to the retired inode.
|
|
682
|
+
store = openEngineStore(dbPath, provider.dimensions);
|
|
683
|
+
return {
|
|
684
|
+
available: true,
|
|
685
|
+
warnings,
|
|
686
|
+
collection,
|
|
687
|
+
dbPath,
|
|
688
|
+
scanned: counters.scanned,
|
|
689
|
+
added: counters.added,
|
|
690
|
+
updated: counters.updated,
|
|
691
|
+
skipped: counters.skipped,
|
|
692
|
+
storedIdentity,
|
|
693
|
+
configuredIdentity,
|
|
694
|
+
generationSwapped,
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
if (!store)
|
|
698
|
+
throw new Error("Internal error: engine store is null after preparation.");
|
|
699
|
+
const counters = { scanned: 0, added: 0, updated: 0, skipped: 0 };
|
|
700
|
+
for await (const relPath of selectedMarkdownFiles(vault, collectionRoot, collectionRelative, opts.files)) {
|
|
701
|
+
await syncDocument({
|
|
702
|
+
relPath,
|
|
703
|
+
vault,
|
|
704
|
+
store,
|
|
705
|
+
provider,
|
|
706
|
+
shouldEmbed: true,
|
|
707
|
+
chunkerOpts: opts.chunkerOpts,
|
|
708
|
+
counters,
|
|
709
|
+
rebuildAllVectors: false,
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
// Persist configured embedding identity only after a successful embed=true
|
|
713
|
+
// incremental sync.
|
|
714
|
+
store.writeEmbeddingIdentity(identity);
|
|
715
|
+
return {
|
|
716
|
+
available: true,
|
|
717
|
+
warnings,
|
|
718
|
+
collection,
|
|
719
|
+
dbPath,
|
|
720
|
+
scanned: counters.scanned,
|
|
721
|
+
added: counters.added,
|
|
722
|
+
updated: counters.updated,
|
|
723
|
+
skipped: counters.skipped,
|
|
724
|
+
storedIdentity,
|
|
725
|
+
configuredIdentity,
|
|
726
|
+
generationSwapped,
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
catch (err) {
|
|
730
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
731
|
+
return {
|
|
732
|
+
available: false,
|
|
733
|
+
reason,
|
|
734
|
+
warnings,
|
|
735
|
+
collection,
|
|
736
|
+
dbPath,
|
|
737
|
+
scanned: 0,
|
|
738
|
+
added: 0,
|
|
739
|
+
updated: 0,
|
|
740
|
+
skipped: 0,
|
|
741
|
+
storedIdentity,
|
|
742
|
+
configuredIdentity,
|
|
743
|
+
generationSwapped,
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
finally {
|
|
747
|
+
await provider?.dispose().catch(() => undefined);
|
|
748
|
+
if (ownsStore)
|
|
749
|
+
store?.close();
|
|
750
|
+
releaseLock?.();
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
//# sourceMappingURL=sync.js.map
|