oh-my-second-brain 0.1.8 → 0.2.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/CHANGELOG.md +89 -0
- package/README.ko.md +127 -0
- package/README.md +128 -0
- package/adapters/README.md +8 -8
- package/adapters/claude-code/.claude-plugin/plugin.json +3 -2
- package/adapters/claude-code/.mcp.json +8 -0
- package/adapters/claude-code/CLAUDE.md +5 -6
- package/adapters/claude-code/skills/compile/SKILL.md +10 -35
- package/adapters/claude-code/skills/distill/SKILL.md +6 -26
- package/adapters/claude-code/skills/link/SKILL.md +87 -0
- package/adapters/claude-code/skills/retrieve/SKILL.md +4 -7
- package/adapters/claude-code/skills/setup/SKILL.md +5 -6
- package/adapters/claude-code/skills/uninstall/SKILL.md +1 -1
- package/adapters/claude-code/skills/wiki/SKILL.md +49 -24
- package/adapters/claude-code/skills/write/SKILL.md +16 -0
- package/adapters/codex/.codex-plugin/plugin.json +1 -1
- package/adapters/codex/AGENTS.md +2 -2
- package/adapters/codex/rules/oms.md +1 -1
- package/adapters/codex/skills/oms-compile/SKILL.md +7 -9
- package/adapters/codex/skills/oms-distill/SKILL.md +4 -9
- package/adapters/codex/skills/oms-link/SKILL.md +35 -0
- package/adapters/codex/skills/oms-retrieve/SKILL.md +5 -6
- package/adapters/codex/skills/oms-wiki/SKILL.md +28 -8
- package/adapters/codex/skills/oms-write/SKILL.md +10 -0
- package/adapters/hermes/README.md +3 -1
- package/adapters/hermes/SOUL.md +2 -3
- package/adapters/hermes/manifest.json +1 -1
- package/adapters/hermes/skills/compile/SKILL.md +5 -7
- package/adapters/hermes/skills/distill/SKILL.md +1 -3
- package/adapters/hermes/skills/link/SKILL.md +18 -0
- package/adapters/hermes/skills/retrieve/SKILL.md +5 -6
- package/adapters/hermes/skills/setup/SKILL.md +5 -2
- package/adapters/hermes/skills/wiki/SKILL.md +4 -2
- package/adapters/hermes/skills/write/SKILL.md +10 -0
- package/core/AGENTS.md +4 -2
- package/core/agents/librarian.md +3 -2
- package/core/ontology/concepts/term.yaml +12 -0
- package/core/ontology/taxonomy.yaml +3 -0
- package/core/skills/compile/SKILL.md +19 -18
- package/core/skills/distill/SKILL.md +13 -24
- package/core/skills/link/SKILL.md +130 -0
- package/core/skills/retrieve/SKILL.md +0 -1
- package/core/skills/setup/SKILL.md +12 -14
- package/core/skills/vault-lint/SKILL.md +1 -1
- package/core/skills/wiki/SKILL.md +109 -30
- package/core/skills/write/SKILL.md +15 -0
- package/dist/capture/safe.d.ts +61 -1
- package/dist/capture/safe.js +489 -66
- package/dist/capture/safe.js.map +1 -1
- package/dist/cli/args.d.ts +29 -0
- package/dist/cli/args.js +156 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/audit.d.ts +6 -0
- package/dist/cli/audit.js +93 -0
- package/dist/cli/audit.js.map +1 -0
- package/dist/cli/claude-install-plan.d.ts +10 -0
- package/dist/cli/claude-install-plan.js +26 -0
- package/dist/cli/claude-install-plan.js.map +1 -0
- package/dist/cli/doctor-lint.d.ts +11 -0
- package/dist/cli/doctor-lint.js +86 -0
- package/dist/cli/doctor-lint.js.map +1 -0
- package/dist/cli/global-writeback.d.ts +31 -0
- package/dist/cli/global-writeback.js +73 -0
- package/dist/cli/global-writeback.js.map +1 -0
- package/dist/cli/host-commands.d.ts +30 -0
- package/dist/cli/host-commands.js +89 -0
- package/dist/cli/host-commands.js.map +1 -0
- package/dist/cli/link-command.d.ts +9 -0
- package/dist/cli/link-command.js +47 -0
- package/dist/cli/link-command.js.map +1 -0
- package/dist/cli/linkify.d.ts +23 -0
- package/dist/cli/linkify.js +118 -0
- package/dist/cli/linkify.js.map +1 -0
- package/dist/cli/oms.d.ts +8 -32
- package/dist/cli/oms.js +100 -703
- package/dist/cli/oms.js.map +1 -1
- package/dist/cli/semantic-args.d.ts +1 -2
- package/dist/cli/semantic-args.js +4 -7
- package/dist/cli/semantic-args.js.map +1 -1
- package/dist/cli/semantic-http.d.ts +0 -3
- package/dist/cli/semantic-http.js +40 -45
- package/dist/cli/semantic-http.js.map +1 -1
- package/dist/cli/semantic-usage.js +10 -9
- package/dist/cli/semantic-usage.js.map +1 -1
- package/dist/cli/semantic.js +99 -137
- package/dist/cli/semantic.js.map +1 -1
- package/dist/cli/setup-command.d.ts +11 -0
- package/dist/cli/setup-command.js +196 -0
- package/dist/cli/setup-command.js.map +1 -0
- package/dist/cli/setup-documents.d.ts +15 -0
- package/dist/cli/setup-documents.js +149 -0
- package/dist/cli/setup-documents.js.map +1 -0
- package/dist/cli/update-notice.d.ts +10 -0
- package/dist/cli/update-notice.js +42 -0
- package/dist/cli/update-notice.js.map +1 -0
- package/dist/cli/usage.d.ts +4 -0
- package/dist/cli/usage.js +102 -0
- package/dist/cli/usage.js.map +1 -0
- package/dist/conventions/lint.js +12 -33
- package/dist/conventions/lint.js.map +1 -1
- package/dist/conventions/report.d.ts +62 -0
- package/dist/conventions/report.js +217 -0
- package/dist/conventions/report.js.map +1 -0
- package/dist/conventions/validate.d.ts +1 -1
- package/dist/conventions/vault-walk.d.ts +38 -0
- package/dist/conventions/vault-walk.js +80 -0
- package/dist/conventions/vault-walk.js.map +1 -0
- package/dist/conventions/write-contract.d.ts +27 -0
- package/dist/conventions/write-contract.js +91 -0
- package/dist/conventions/write-contract.js.map +1 -0
- package/dist/conventions/write-protocol.d.ts +39 -0
- package/dist/conventions/write-protocol.js +44 -0
- package/dist/conventions/write-protocol.js.map +1 -0
- package/dist/core/ontology/loader.d.ts +2 -0
- package/dist/{ontology → core/ontology}/loader.js +11 -20
- package/dist/core/ontology/loader.js.map +1 -0
- package/dist/core/ontology/resolver.d.ts +2 -0
- package/dist/{ontology → core/ontology}/resolver.js +1 -15
- package/dist/core/ontology/resolver.js.map +1 -0
- package/dist/core/ontology/types.d.ts +47 -0
- package/dist/core/ontology/types.js +2 -0
- package/dist/core/ontology/types.js.map +1 -0
- package/dist/core/runtime/assets.d.ts +20 -0
- package/dist/core/runtime/assets.js +66 -0
- package/dist/core/runtime/assets.js.map +1 -0
- package/dist/engine/assemble.d.ts +28 -72
- package/dist/engine/assemble.js +77 -61
- package/dist/engine/assemble.js.map +1 -1
- package/dist/engine/conventions/vault-lint.d.ts +30 -2
- package/dist/engine/conventions/vault-lint.js +93 -97
- package/dist/engine/conventions/vault-lint.js.map +1 -1
- package/dist/engine/embed/deferred.d.ts +3 -4
- package/dist/engine/embed/deferred.js +10 -7
- package/dist/engine/embed/deferred.js.map +1 -1
- package/dist/engine/embed/identity.d.ts +11 -0
- package/dist/engine/embed/identity.js +15 -0
- package/dist/engine/embed/identity.js.map +1 -0
- package/dist/engine/embed/provider.d.ts +12 -13
- package/dist/engine/embed/provider.js +30 -27
- package/dist/engine/embed/provider.js.map +1 -1
- package/dist/engine/embed/store.d.ts +48 -27
- package/dist/engine/embed/store.js +281 -98
- package/dist/engine/embed/store.js.map +1 -1
- package/dist/engine/embed/sync.d.ts +17 -47
- package/dist/engine/embed/sync.js +233 -69
- package/dist/engine/embed/sync.js.map +1 -1
- package/dist/engine/graph/builder.d.ts +1 -1
- package/dist/engine/graph/builder.js +1 -1
- package/dist/engine/graph/explore.d.ts +2 -2
- package/dist/engine/graph/explore.js +0 -0
- package/dist/engine/graph/resolver.d.ts +17 -0
- package/dist/engine/graph/resolver.js +46 -11
- package/dist/engine/graph/resolver.js.map +1 -1
- package/dist/engine/linkify/apply.d.ts +56 -0
- package/dist/engine/linkify/apply.js +65 -0
- package/dist/engine/linkify/apply.js.map +1 -0
- package/dist/engine/linkify/josa.d.ts +58 -0
- package/dist/engine/linkify/josa.js +133 -0
- package/dist/engine/linkify/josa.js.map +1 -0
- package/dist/engine/linkify/mask.d.ts +29 -0
- package/dist/engine/linkify/mask.js +173 -0
- package/dist/engine/linkify/mask.js.map +1 -0
- package/dist/engine/linkify/suggest.d.ts +52 -0
- package/dist/engine/linkify/suggest.js +181 -0
- package/dist/engine/linkify/suggest.js.map +1 -0
- package/dist/engine/linkify/types.d.ts +68 -0
- package/dist/engine/linkify/types.js +12 -0
- package/dist/engine/linkify/types.js.map +1 -0
- package/dist/engine/mcp/facade.d.ts +12 -18
- package/dist/engine/mcp/facade.js +30 -80
- package/dist/engine/mcp/facade.js.map +1 -1
- package/dist/engine/mcp/op-mappers.d.ts +3 -9
- package/dist/engine/mcp/op-mappers.js +2 -30
- package/dist/engine/mcp/op-mappers.js.map +1 -1
- package/dist/engine/mcp/types.d.ts +5 -29
- package/dist/engine/tracer.js +6 -2
- package/dist/engine/tracer.js.map +1 -1
- package/dist/engine/types.d.ts +8 -3
- package/dist/graph/cache.d.ts +1 -11
- package/dist/graph/cache.js +1 -44
- package/dist/graph/cache.js.map +1 -1
- package/dist/graph/explore.js +88 -137
- package/dist/graph/explore.js.map +1 -1
- package/dist/harness/surface-registry.d.ts +56 -0
- package/dist/harness/surface-registry.js +397 -0
- package/dist/harness/surface-registry.js.map +1 -0
- package/dist/harness/validation.d.ts +9 -0
- package/dist/harness/validation.js +201 -0
- package/dist/harness/validation.js.map +1 -0
- package/dist/hook/post-tool-use.js +2 -2
- package/dist/hook/post-tool-use.js.map +1 -1
- package/dist/index.d.ts +7 -5
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/install/adapter-source.d.ts +14 -0
- package/dist/install/adapter-source.js +45 -0
- package/dist/install/adapter-source.js.map +1 -0
- package/dist/install/claude-hooks.d.ts +13 -0
- package/dist/install/claude-hooks.js +411 -0
- package/dist/install/claude-hooks.js.map +1 -0
- package/dist/install/claude-marketplace.d.ts +44 -0
- package/dist/install/claude-marketplace.js +89 -0
- package/dist/install/claude-marketplace.js.map +1 -0
- package/dist/install/claude.d.ts +4 -0
- package/dist/install/claude.js +216 -0
- package/dist/install/claude.js.map +1 -0
- package/dist/install/codex.d.ts +24 -0
- package/dist/install/codex.js +193 -0
- package/dist/install/codex.js.map +1 -0
- package/dist/install/common.d.ts +34 -0
- package/dist/install/common.js +122 -0
- package/dist/install/common.js.map +1 -0
- package/dist/install/hermes.d.ts +4 -0
- package/dist/install/hermes.js +78 -0
- package/dist/install/hermes.js.map +1 -0
- package/dist/install/hosts.d.ts +6 -56
- package/dist/install/hosts.js +65 -610
- package/dist/install/hosts.js.map +1 -1
- package/dist/install/types.d.ts +34 -0
- package/dist/install/types.js +2 -0
- package/dist/install/types.js.map +1 -0
- package/dist/link/convention-note.d.ts +10 -0
- package/dist/link/convention-note.js +59 -0
- package/dist/link/convention-note.js.map +1 -0
- package/dist/link/global-config.d.ts +22 -0
- package/dist/link/global-config.js +69 -0
- package/dist/link/global-config.js.map +1 -0
- package/dist/link/link.d.ts +101 -0
- package/dist/link/link.js +265 -0
- package/dist/link/link.js.map +1 -0
- package/dist/mcp/engine-morning-backend.d.ts +12 -17
- package/dist/mcp/engine-morning-backend.js +25 -131
- package/dist/mcp/engine-morning-backend.js.map +1 -1
- package/dist/mcp/link-tools.d.ts +81 -0
- package/dist/mcp/link-tools.js +157 -0
- package/dist/mcp/link-tools.js.map +1 -0
- package/dist/mcp/semantic-engine.d.ts +32 -0
- package/dist/mcp/semantic-engine.js +52 -0
- package/dist/mcp/semantic-engine.js.map +1 -0
- package/dist/mcp/semantic-retrieve-args.d.ts +1 -5
- package/dist/mcp/semantic-retrieve-args.js +1 -26
- package/dist/mcp/semantic-retrieve-args.js.map +1 -1
- package/dist/mcp/semantic-retrieve-schema.d.ts +0 -14
- package/dist/mcp/semantic-retrieve-schema.js +0 -5
- package/dist/mcp/semantic-retrieve-schema.js.map +1 -1
- package/dist/mcp/semantic-retrieve.d.ts +12 -18
- package/dist/mcp/semantic-retrieve.js +40 -71
- package/dist/mcp/semantic-retrieve.js.map +1 -1
- package/dist/mcp/semantic-tool-schemas.js +7 -24
- package/dist/mcp/semantic-tool-schemas.js.map +1 -1
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.js +224 -162
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/update-notice.d.ts +51 -0
- package/dist/mcp/update-notice.js +196 -0
- package/dist/mcp/update-notice.js.map +1 -0
- package/dist/ontology/active.d.ts +7 -0
- package/dist/ontology/active.js +41 -0
- package/dist/ontology/active.js.map +1 -0
- package/dist/retrieve/morning.d.ts +10 -18
- package/dist/retrieve/morning.js +2 -26
- package/dist/retrieve/morning.js.map +1 -1
- package/dist/retrieve/semantic-contract.d.ts +10 -0
- package/dist/retrieve/semantic-contract.js +2 -0
- package/dist/retrieve/semantic-contract.js.map +1 -0
- package/dist/setup/axis.d.ts +22 -3
- package/dist/setup/axis.js +82 -35
- package/dist/setup/axis.js.map +1 -1
- package/dist/update/update.d.ts +12 -0
- package/dist/update/update.js +2 -2
- package/dist/update/update.js.map +1 -1
- package/docs/install.md +43 -7
- package/docs/release.md +109 -17
- package/package.json +11 -3
- package/scripts/install.sh +1 -1
- package/adapters/claude-code/skills/capture/SKILL.md +0 -50
- package/adapters/codex/skills/oms-capture/SKILL.md +0 -16
- package/adapters/hermes/skills/capture/SKILL.md +0 -16
- package/core/skills/capture/SKILL.md +0 -50
- package/dist/adapt/HostAdapter.d.ts +0 -21
- package/dist/adapt/HostAdapter.js +0 -10
- package/dist/adapt/HostAdapter.js.map +0 -1
- package/dist/adapt/claudeCode.d.ts +0 -9
- package/dist/adapt/claudeCode.js +0 -15
- package/dist/adapt/claudeCode.js.map +0 -1
- package/dist/adapt/codex.d.ts +0 -9
- package/dist/adapt/codex.js +0 -15
- package/dist/adapt/codex.js.map +0 -1
- package/dist/adapt/hermes.d.ts +0 -9
- package/dist/adapt/hermes.js +0 -15
- package/dist/adapt/hermes.js.map +0 -1
- package/dist/cli/semantic-metadata-commands.d.ts +0 -3
- package/dist/cli/semantic-metadata-commands.js +0 -115
- package/dist/cli/semantic-metadata-commands.js.map +0 -1
- package/dist/engine/compile/cascade.d.ts +0 -35
- package/dist/engine/compile/cascade.js +0 -59
- package/dist/engine/compile/cascade.js.map +0 -1
- package/dist/engine/compile/cot.d.ts +0 -30
- package/dist/engine/compile/cot.js +0 -153
- package/dist/engine/compile/cot.js.map +0 -1
- package/dist/engine/compile/phases.d.ts +0 -47
- package/dist/engine/compile/phases.js +0 -101
- package/dist/engine/compile/phases.js.map +0 -1
- package/dist/engine/compile/provenance.d.ts +0 -45
- package/dist/engine/compile/provenance.js +0 -103
- package/dist/engine/compile/provenance.js.map +0 -1
- package/dist/engine/compile/sha-cache.d.ts +0 -42
- package/dist/engine/compile/sha-cache.js +0 -86
- package/dist/engine/compile/sha-cache.js.map +0 -1
- package/dist/engine/compile/types.d.ts +0 -71
- package/dist/engine/compile/types.js +0 -9
- package/dist/engine/compile/types.js.map +0 -1
- package/dist/engine/compile/worker.d.ts +0 -47
- package/dist/engine/compile/worker.js +0 -75
- package/dist/engine/compile/worker.js.map +0 -1
- package/dist/engine/distill/analyzer.d.ts +0 -51
- package/dist/engine/distill/analyzer.js +0 -279
- package/dist/engine/distill/analyzer.js.map +0 -1
- package/dist/engine/distill/clean-room.d.ts +0 -46
- package/dist/engine/distill/clean-room.js +0 -131
- package/dist/engine/distill/clean-room.js.map +0 -1
- package/dist/engine/distill/report.d.ts +0 -23
- package/dist/engine/distill/report.js +0 -107
- package/dist/engine/distill/report.js.map +0 -1
- package/dist/engine/distill/types.d.ts +0 -89
- package/dist/engine/distill/types.js +0 -9
- package/dist/engine/distill/types.js.map +0 -1
- package/dist/engine/embed/pull.d.ts +0 -51
- package/dist/engine/embed/pull.js +0 -90
- package/dist/engine/embed/pull.js.map +0 -1
- package/dist/engine/graph/community.d.ts +0 -38
- package/dist/engine/graph/community.js +0 -122
- package/dist/engine/graph/community.js.map +0 -1
- package/dist/engine/index.d.ts +0 -5
- package/dist/engine/index.js +0 -2
- package/dist/engine/index.js.map +0 -1
- package/dist/engine/mcp/index.d.ts +0 -15
- package/dist/engine/mcp/index.js +0 -19
- package/dist/engine/mcp/index.js.map +0 -1
- package/dist/engine/mcp/retrieve-mapper.d.ts +0 -38
- package/dist/engine/mcp/retrieve-mapper.js +0 -96
- package/dist/engine/mcp/retrieve-mapper.js.map +0 -1
- package/dist/engine/setup/ambiguity.d.ts +0 -39
- package/dist/engine/setup/ambiguity.js +0 -50
- package/dist/engine/setup/ambiguity.js.map +0 -1
- package/dist/engine/setup/types.d.ts +0 -71
- package/dist/engine/setup/types.js +0 -22
- package/dist/engine/setup/types.js.map +0 -1
- package/dist/engine/setup/writer.d.ts +0 -32
- package/dist/engine/setup/writer.js +0 -77
- package/dist/engine/setup/writer.js.map +0 -1
- package/dist/engine/wiki/collection.d.ts +0 -91
- package/dist/engine/wiki/collection.js +0 -188
- package/dist/engine/wiki/collection.js.map +0 -1
- package/dist/engine/wiki/ledger.d.ts +0 -59
- package/dist/engine/wiki/ledger.js +0 -130
- package/dist/engine/wiki/ledger.js.map +0 -1
- package/dist/engine/wiki/lint.d.ts +0 -38
- package/dist/engine/wiki/lint.js +0 -186
- package/dist/engine/wiki/lint.js.map +0 -1
- package/dist/engine/wiki/navigation.d.ts +0 -40
- package/dist/engine/wiki/navigation.js +0 -83
- package/dist/engine/wiki/navigation.js.map +0 -1
- package/dist/engine/wiki/types.d.ts +0 -54
- package/dist/engine/wiki/types.js +0 -7
- package/dist/engine/wiki/types.js.map +0 -1
- package/dist/ontology/loader.d.ts +0 -13
- package/dist/ontology/loader.js.map +0 -1
- package/dist/ontology/resolver.d.ts +0 -13
- package/dist/ontology/resolver.js.map +0 -1
- package/dist/ontology/types.d.ts +0 -72
- package/dist/ontology/types.js +0 -12
- package/dist/ontology/types.js.map +0 -1
- package/dist/retrieve/embedding-sync.d.ts +0 -3
- package/dist/retrieve/embedding-sync.js +0 -21
- package/dist/retrieve/embedding-sync.js.map +0 -1
- package/dist/runtime/assets.d.ts +0 -7
- package/dist/runtime/assets.js +0 -13
- package/dist/runtime/assets.js.map +0 -1
- package/dist/search/semantic-collections.d.ts +0 -32
- package/dist/search/semantic-collections.js +0 -68
- package/dist/search/semantic-collections.js.map +0 -1
- package/dist/search/semantic-contexts.d.ts +0 -21
- package/dist/search/semantic-contexts.js +0 -28
- package/dist/search/semantic-contexts.js.map +0 -1
- package/dist/search/semantic-diagnostics.d.ts +0 -16
- package/dist/search/semantic-diagnostics.js +0 -110
- package/dist/search/semantic-diagnostics.js.map +0 -1
- package/dist/search/semantic-documents.d.ts +0 -3
- package/dist/search/semantic-documents.js +0 -150
- package/dist/search/semantic-documents.js.map +0 -1
- package/dist/search/semantic-embedding-hash.d.ts +0 -3
- package/dist/search/semantic-embedding-hash.js +0 -30
- package/dist/search/semantic-embedding-hash.js.map +0 -1
- package/dist/search/semantic-embedding-provider.d.ts +0 -9
- package/dist/search/semantic-embedding-provider.js +0 -58
- package/dist/search/semantic-embedding-provider.js.map +0 -1
- package/dist/search/semantic-index-build.d.ts +0 -13
- package/dist/search/semantic-index-build.js +0 -101
- package/dist/search/semantic-index-build.js.map +0 -1
- package/dist/search/semantic-index-core.d.ts +0 -21
- package/dist/search/semantic-index-core.js +0 -106
- package/dist/search/semantic-index-core.js.map +0 -1
- package/dist/search/semantic-index-io.d.ts +0 -19
- package/dist/search/semantic-index-io.js +0 -214
- package/dist/search/semantic-index-io.js.map +0 -1
- package/dist/search/semantic-index-types.d.ts +0 -50
- package/dist/search/semantic-index-types.js +0 -2
- package/dist/search/semantic-index-types.js.map +0 -1
- package/dist/search/semantic-index.d.ts +0 -4
- package/dist/search/semantic-index.js +0 -4
- package/dist/search/semantic-index.js.map +0 -1
- package/dist/search/semantic-listing.d.ts +0 -12
- package/dist/search/semantic-listing.js +0 -64
- package/dist/search/semantic-listing.js.map +0 -1
- package/dist/search/semantic-maintenance-shared.d.ts +0 -15
- package/dist/search/semantic-maintenance-shared.js +0 -43
- package/dist/search/semantic-maintenance-shared.js.map +0 -1
- package/dist/search/semantic-maintenance-types.d.ts +0 -103
- package/dist/search/semantic-maintenance-types.js +0 -2
- package/dist/search/semantic-maintenance-types.js.map +0 -1
- package/dist/search/semantic-maintenance.d.ts +0 -4
- package/dist/search/semantic-maintenance.js +0 -5
- package/dist/search/semantic-maintenance.js.map +0 -1
- package/dist/search/semantic-provider-types.d.ts +0 -34
- package/dist/search/semantic-provider-types.js +0 -2
- package/dist/search/semantic-provider-types.js.map +0 -1
- package/dist/search/semantic-query-types.d.ts +0 -83
- package/dist/search/semantic-query-types.js +0 -2
- package/dist/search/semantic-query-types.js.map +0 -1
- package/dist/search/semantic-query.d.ts +0 -2
- package/dist/search/semantic-query.js +0 -188
- package/dist/search/semantic-query.js.map +0 -1
- package/dist/search/semantic-sqlite-db.d.ts +0 -18
- package/dist/search/semantic-sqlite-db.js +0 -87
- package/dist/search/semantic-sqlite-db.js.map +0 -1
- package/dist/search/semantic-sqlite-query.d.ts +0 -2
- package/dist/search/semantic-sqlite-query.js +0 -128
- package/dist/search/semantic-sqlite-query.js.map +0 -1
- package/dist/search/semantic-sqlite-read.d.ts +0 -5
- package/dist/search/semantic-sqlite-read.js +0 -104
- package/dist/search/semantic-sqlite-read.js.map +0 -1
- package/dist/search/semantic-sqlite-write.d.ts +0 -7
- package/dist/search/semantic-sqlite-write.js +0 -66
- package/dist/search/semantic-sqlite-write.js.map +0 -1
- package/dist/search/semantic-store.d.ts +0 -15
- package/dist/search/semantic-store.js +0 -17
- package/dist/search/semantic-store.js.map +0 -1
- package/dist/search/semantic-sync-types.d.ts +0 -47
- package/dist/search/semantic-sync-types.js +0 -2
- package/dist/search/semantic-sync-types.js.map +0 -1
- package/dist/search/semantic-sync.d.ts +0 -13
- package/dist/search/semantic-sync.js +0 -131
- package/dist/search/semantic-sync.js.map +0 -1
- package/dist/search/semantic-test-fixtures.d.ts +0 -1
- package/dist/search/semantic-test-fixtures.js +0 -38
- package/dist/search/semantic-test-fixtures.js.map +0 -1
- package/dist/search/semantic-token.d.ts +0 -25
- package/dist/search/semantic-token.js +0 -114
- package/dist/search/semantic-token.js.map +0 -1
- package/dist/search/semantic-types.d.ts +0 -5
- package/dist/search/semantic-types.js +0 -2
- package/dist/search/semantic-types.js.map +0 -1
- package/dist/search/semantic.d.ts +0 -6
- package/dist/search/semantic.js +0 -6
- package/dist/search/semantic.js.map +0 -1
package/dist/cli/oms.js
CHANGED
|
@@ -1,731 +1,111 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { realpathSync } from "node:fs";
|
|
3
|
-
import { readFile, readdir, mkdir, copyFile, writeFile } from "node:fs/promises";
|
|
4
3
|
import path from "node:path";
|
|
5
4
|
import { fileURLToPath } from "node:url";
|
|
6
|
-
import { createInterface } from "node:readline/promises";
|
|
7
|
-
import { stringify as yamlStringify, parse as yamlParse } from "yaml";
|
|
8
|
-
import { loadOntology } from "../ontology/loader.js";
|
|
9
|
-
import { resolveConcept } from "../ontology/resolver.js";
|
|
10
|
-
import { parseNote } from "../conventions/frontmatter.js";
|
|
11
|
-
import { validateFrontmatter } from "../conventions/validate.js";
|
|
12
|
-
import { detectLinkIssues } from "../conventions/lint.js";
|
|
13
|
-
import { runMcpServer } from "../mcp/server.js";
|
|
14
|
-
import { runPreToolUse } from "../hook/pre-tool-use.js";
|
|
15
5
|
import { runPostToolUse } from "../hook/post-tool-use.js";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
6
|
+
import { runPreToolUse } from "../hook/pre-tool-use.js";
|
|
7
|
+
import { resolveEffectiveVault } from "../link/link.js";
|
|
8
|
+
import { runMcpServer } from "../mcp/server.js";
|
|
9
|
+
import { resolveBundledAssetPaths } from "../core/runtime/assets.js";
|
|
10
|
+
import { parseCliArgs } from "./args.js";
|
|
11
|
+
import { runAudit } from "./audit.js";
|
|
12
|
+
import { runDoctor, runLint } from "./doctor-lint.js";
|
|
13
|
+
import { runInstallOrUninstall, runUpdateCommand, runUpdateReconcile, } from "./host-commands.js";
|
|
14
|
+
import { nonFatalGlobalWriteback, registerGlobalVault } from "./global-writeback.js";
|
|
15
|
+
import { runLink } from "./link-command.js";
|
|
16
|
+
import { runLinkify } from "./linkify.js";
|
|
20
17
|
import { isSemanticCliCommand, runSemanticCli } from "./semantic.js";
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
import { runSetup } from "./setup-command.js";
|
|
19
|
+
import { maybePrintUpdateNotice } from "./update-notice.js";
|
|
20
|
+
import { printUsage } from "./usage.js";
|
|
21
|
+
export { buildClaudeInstallPlan } from "./claude-install-plan.js";
|
|
22
|
+
export { runDoctor, runLint } from "./doctor-lint.js";
|
|
23
|
+
export { runAudit } from "./audit.js";
|
|
24
|
+
export { formatLinkResult, runLink, } from "./link-command.js";
|
|
25
|
+
export { runLinkify } from "./linkify.js";
|
|
26
|
+
export { runSetup, } from "./setup-command.js";
|
|
27
|
+
export { maybePrintUpdateNotice } from "./update-notice.js";
|
|
24
28
|
const bundledAssets = resolveBundledAssetPaths();
|
|
25
|
-
function
|
|
26
|
-
return
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
// ---------------------------------------------------------------------------
|
|
35
|
-
// Helpers
|
|
36
|
-
// ---------------------------------------------------------------------------
|
|
37
|
-
/** Humanize a folder name: "references" → "References". */
|
|
38
|
-
function humanize(name) {
|
|
39
|
-
return name.charAt(0).toUpperCase() + name.slice(1);
|
|
40
|
-
}
|
|
41
|
-
/** Quote a value for copy/pasteable POSIX shell commands. */
|
|
42
|
-
function shellQuote(value) {
|
|
43
|
-
if (/^[A-Za-z0-9_/:=.,@%+-]+$/.test(value)) {
|
|
44
|
-
return value;
|
|
45
|
-
}
|
|
46
|
-
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
29
|
+
function shouldResolveBridgeVault(command, vaultExplicit) {
|
|
30
|
+
return (!vaultExplicit &&
|
|
31
|
+
(command === "audit" ||
|
|
32
|
+
command === "linkify" ||
|
|
33
|
+
command === "doctor" ||
|
|
34
|
+
command === "lint" ||
|
|
35
|
+
command === "mcp" ||
|
|
36
|
+
isSemanticCliCommand(command)));
|
|
47
37
|
}
|
|
48
|
-
function
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
? packageJson["version"]
|
|
55
|
-
: null;
|
|
56
|
-
}
|
|
57
|
-
function updateNoticeDisabled(env) {
|
|
58
|
-
return env["OMS_UPDATE_NOTICE"] === "0" || env["OMS_NO_UPDATE_NOTICE"] === "1";
|
|
59
|
-
}
|
|
60
|
-
function parseUpdateNoticeTimeout(env) {
|
|
61
|
-
const raw = env["OMS_UPDATE_NOTICE_TIMEOUT_MS"];
|
|
62
|
-
if (raw === undefined)
|
|
63
|
-
return undefined;
|
|
64
|
-
const parsed = Number.parseInt(raw, 10);
|
|
65
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
|
|
66
|
-
}
|
|
67
|
-
export async function maybePrintUpdateNotice(options = {}) {
|
|
68
|
-
const env = options.env ?? process.env;
|
|
69
|
-
if (updateNoticeDisabled(env))
|
|
70
|
-
return;
|
|
71
|
-
const currentVersion = options.currentVersion ?? await readCurrentPackageVersion();
|
|
72
|
-
const notice = await checkUpdateNotice({
|
|
73
|
-
currentVersion,
|
|
74
|
-
latestVersion: options.latestVersion ?? env["OMS_UPDATE_LATEST_VERSION"],
|
|
75
|
-
timeoutMs: options.timeoutMs ?? parseUpdateNoticeTimeout(env),
|
|
76
|
-
runner: options.runner,
|
|
77
|
-
});
|
|
78
|
-
const formatted = formatUpdateNotice(notice);
|
|
79
|
-
if (formatted.length === 0)
|
|
38
|
+
async function main() {
|
|
39
|
+
const argv = process.argv.slice(2);
|
|
40
|
+
const parsedArgs = parseCliArgs(argv);
|
|
41
|
+
if (parsedArgs.error !== undefined) {
|
|
42
|
+
console.error(parsedArgs.error.message);
|
|
43
|
+
process.exitCode = 1;
|
|
80
44
|
return;
|
|
81
|
-
const write = options.write ?? ((message) => console.error(message));
|
|
82
|
-
write(`\n${formatted}`);
|
|
83
|
-
}
|
|
84
|
-
function parseConceptRef(value) {
|
|
85
|
-
if (value === null || value === undefined)
|
|
86
|
-
return null;
|
|
87
|
-
if (typeof value === "string")
|
|
88
|
-
return value;
|
|
89
|
-
if (Array.isArray(value) && value.every((item) => typeof item === "string"))
|
|
90
|
-
return value;
|
|
91
|
-
return null;
|
|
92
|
-
}
|
|
93
|
-
function parseFolderBinding(value) {
|
|
94
|
-
if (!isRecord(value))
|
|
95
|
-
return null;
|
|
96
|
-
const rawIntent = value["intent"];
|
|
97
|
-
return {
|
|
98
|
-
intent: typeof rawIntent === "string" && rawIntent.trim() ? rawIntent : "",
|
|
99
|
-
concept: parseConceptRef(value["concept"]),
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
function parseConceptDocument(filePath, parsed) {
|
|
103
|
-
const concept = {
|
|
104
|
-
concept: typeof parsed["concept"] === "string" ? parsed["concept"] : path.basename(filePath, path.extname(filePath)),
|
|
105
|
-
intent: typeof parsed["intent"] === "string" ? parsed["intent"] : "",
|
|
106
|
-
folder: typeof parsed["folder"] === "string" ? parsed["folder"] : "",
|
|
107
|
-
fields: Array.isArray(parsed["fields"]) ? parsed["fields"] : [],
|
|
108
|
-
lenses: Array.isArray(parsed["lenses"]) ? parsed["lenses"] : [],
|
|
109
|
-
};
|
|
110
|
-
return { filePath, raw: parsed, concept };
|
|
111
|
-
}
|
|
112
|
-
async function readConceptDocuments(omsDir) {
|
|
113
|
-
const documents = new Map();
|
|
114
|
-
const conceptsDir = path.join(omsDir, "concepts");
|
|
115
|
-
let entries;
|
|
116
|
-
try {
|
|
117
|
-
entries = await readdir(conceptsDir);
|
|
118
45
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
46
|
+
let { command, vault, vaultExplicit, yes, apply, installClaude, suggestFields, runtime, dryRun, executeExternal, checkUpdate, timeoutMs, agentVault, verbose, json, maxPerConcept, folders, conventionNote, unknownFlags, } = parsedArgs;
|
|
47
|
+
// `mcp` keeps the FULL resolution result: the write surface trusts every
|
|
48
|
+
// source except `cwd`, so the server needs the source, not just the path.
|
|
49
|
+
let mcpTarget;
|
|
50
|
+
if (command === "mcp") {
|
|
51
|
+
mcpTarget = vaultExplicit
|
|
52
|
+
? { vault, scope: null, source: "explicit" }
|
|
53
|
+
: await resolveEffectiveVault(process.cwd(), process.env);
|
|
54
|
+
vault = mcpTarget.vault;
|
|
123
55
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
continue;
|
|
127
|
-
const filePath = path.join(conceptsDir, file);
|
|
128
|
-
const parsed = yamlParse(await readFile(filePath, "utf-8"));
|
|
129
|
-
if (!isRecord(parsed))
|
|
130
|
-
continue;
|
|
131
|
-
const document = parseConceptDocument(filePath, parsed);
|
|
132
|
-
documents.set(document.concept.concept, document);
|
|
56
|
+
else if (shouldResolveBridgeVault(command, vaultExplicit)) {
|
|
57
|
+
vault = (await resolveEffectiveVault(process.cwd(), process.env)).vault;
|
|
133
58
|
}
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
for (const [name, document] of localDocuments) {
|
|
139
|
-
concepts.set(name, document.concept);
|
|
59
|
+
if (command === "setup") {
|
|
60
|
+
await runSetup({ vault, yes, installClaude, suggestFields });
|
|
61
|
+
await nonFatalGlobalWriteback(() => registerGlobalVault({ vault: path.resolve(vault), homeDir: undefined, overwrite: true }));
|
|
62
|
+
await maybePrintUpdateNotice();
|
|
140
63
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const parsed = yamlParse(raw);
|
|
147
|
-
if (!isRecord(parsed))
|
|
148
|
-
return null;
|
|
149
|
-
const rawFolders = parsed["folders"];
|
|
150
|
-
const folders = {};
|
|
151
|
-
if (isRecord(rawFolders)) {
|
|
152
|
-
for (const [folder, binding] of Object.entries(rawFolders)) {
|
|
153
|
-
const parsedBinding = parseFolderBinding(binding);
|
|
154
|
-
if (parsedBinding !== null) {
|
|
155
|
-
folders[folder] = parsedBinding;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return {
|
|
160
|
-
version: typeof parsed["version"] === "number" ? parsed["version"] : 0,
|
|
64
|
+
else if (command === "link") {
|
|
65
|
+
process.exitCode = await runLink({
|
|
66
|
+
cwd: process.cwd(),
|
|
67
|
+
vault,
|
|
68
|
+
vaultExplicit,
|
|
161
69
|
folders,
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (error instanceof Error)
|
|
166
|
-
return null;
|
|
167
|
-
throw error;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
function defaultConceptForFolder(concepts, folder) {
|
|
171
|
-
for (const [name, concept] of concepts) {
|
|
172
|
-
if (concept.folder === folder)
|
|
173
|
-
return name;
|
|
174
|
-
}
|
|
175
|
-
return null;
|
|
176
|
-
}
|
|
177
|
-
function conceptRefToPromptDefault(concept) {
|
|
178
|
-
if (Array.isArray(concept))
|
|
179
|
-
return concept[0] ?? null;
|
|
180
|
-
return concept;
|
|
181
|
-
}
|
|
182
|
-
function isFieldType(value) {
|
|
183
|
-
switch (value) {
|
|
184
|
-
case "string":
|
|
185
|
-
case "url":
|
|
186
|
-
case "date":
|
|
187
|
-
case "list":
|
|
188
|
-
case "number":
|
|
189
|
-
case "boolean":
|
|
190
|
-
return true;
|
|
191
|
-
default:
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
function mergeAdditionalFields(concept, fields) {
|
|
196
|
-
const existing = new Set(concept.fields.map((field) => field.name));
|
|
197
|
-
const additions = fields.filter((field) => !existing.has(field.name));
|
|
198
|
-
return {
|
|
199
|
-
...concept,
|
|
200
|
-
fields: [...concept.fields, ...additions],
|
|
201
|
-
lenses: concept.lenses ?? [],
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
function mergeAdditionalLenses(concept, lenses) {
|
|
205
|
-
const existing = new Set((concept.lenses ?? []).map((lens) => lens.name));
|
|
206
|
-
const additions = lenses.filter((lens) => !existing.has(lens.name));
|
|
207
|
-
return {
|
|
208
|
-
...concept,
|
|
209
|
-
fields: concept.fields,
|
|
210
|
-
lenses: [...(concept.lenses ?? []), ...additions],
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
async function writeConcept(omsDir, concept, existingDocument) {
|
|
214
|
-
const conceptsOutDir = path.join(omsDir, "concepts");
|
|
215
|
-
await mkdir(conceptsOutDir, { recursive: true });
|
|
216
|
-
const document = {
|
|
217
|
-
...(existingDocument?.raw ?? {}),
|
|
218
|
-
concept: concept.concept,
|
|
219
|
-
intent: concept.intent,
|
|
220
|
-
folder: concept.folder,
|
|
221
|
-
fields: concept.fields,
|
|
222
|
-
lenses: concept.lenses ?? [],
|
|
223
|
-
};
|
|
224
|
-
await writeFile(existingDocument?.filePath ?? path.join(conceptsOutDir, `${concept.concept}.yaml`), yamlStringify(document), "utf-8");
|
|
225
|
-
}
|
|
226
|
-
export function buildClaudeInstallPlan(opts) {
|
|
227
|
-
const pluginPath = bundledClaudeAdapterDir();
|
|
228
|
-
return {
|
|
229
|
-
pluginPath,
|
|
230
|
-
pluginInstallCommand: `claude plugin install ${shellQuote(pluginPath)}`,
|
|
231
|
-
mcpRegistrationCommand: `claude mcp add oms -- oms mcp --vault ${shellQuote(opts.vault)}`,
|
|
232
|
-
mcpRuntimeStatus: "read-status-runtime",
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
function printClaudeInstallPlan(plan) {
|
|
236
|
-
console.log("Claude Code harness install plan (dry-run).");
|
|
237
|
-
console.log(` Plugin path: ${plan.pluginPath}`);
|
|
238
|
-
console.log(` Plugin command: ${plan.pluginInstallCommand}`);
|
|
239
|
-
console.log(` MCP command: ${plan.mcpRegistrationCommand}`);
|
|
240
|
-
console.log(" MCP status: status/read/cache/retrieval plus safe capture; commit is gated by vault confinement and contract validation.");
|
|
241
|
-
}
|
|
242
|
-
/** Walk a directory recursively, yielding relative paths for all .md files. */
|
|
243
|
-
async function* walkMarkdown(dir, base, skipDirs) {
|
|
244
|
-
let entries;
|
|
245
|
-
try {
|
|
246
|
-
entries = await readdir(dir, { withFileTypes: true });
|
|
247
|
-
}
|
|
248
|
-
catch {
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
for (const entry of entries) {
|
|
252
|
-
if (entry.name.startsWith("."))
|
|
253
|
-
continue;
|
|
254
|
-
if (skipDirs.has(entry.name))
|
|
255
|
-
continue;
|
|
256
|
-
const full = path.join(dir, entry.name);
|
|
257
|
-
if (entry.isDirectory()) {
|
|
258
|
-
yield* walkMarkdown(full, base, skipDirs);
|
|
259
|
-
}
|
|
260
|
-
else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
261
|
-
yield path.relative(base, full).replace(/\\/g, "/");
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
// ---------------------------------------------------------------------------
|
|
266
|
-
// runSetup
|
|
267
|
-
// ---------------------------------------------------------------------------
|
|
268
|
-
export async function runSetup(opts) {
|
|
269
|
-
const { vault, yes, installClaude = false, suggestFields = false } = opts;
|
|
270
|
-
const nonInteractive = yes || process.env["OMS_NON_INTERACTIVE"] === "1";
|
|
271
|
-
const ontologyDir = bundledOntologyDir();
|
|
272
|
-
// Load shipped concepts so we can offer meaningful defaults.
|
|
273
|
-
const ontology = await loadOntology(ontologyDir);
|
|
274
|
-
const observedSummaries = await collectObservedFields({ vault });
|
|
275
|
-
const observedByFolder = new Map(observedSummaries.map((summary) => [summary.folder, summary]));
|
|
276
|
-
// Scan vault top-level directories (skip dotfiles).
|
|
277
|
-
const topEntries = await readdir(vault, { withFileTypes: true });
|
|
278
|
-
const folders = topEntries
|
|
279
|
-
.filter((e) => e.isDirectory() && !e.name.startsWith("."))
|
|
280
|
-
.map((e) => e.name);
|
|
281
|
-
const omsDir = path.join(vault, ".oms");
|
|
282
|
-
const existingTaxonomy = await readExistingTaxonomy(omsDir);
|
|
283
|
-
const existingConceptDocuments = await readConceptDocuments(omsDir);
|
|
284
|
-
const promptConcepts = buildPromptConcepts(ontology.concepts, existingConceptDocuments);
|
|
285
|
-
const folderBindings = { ...(existingTaxonomy?.folders ?? {}) };
|
|
286
|
-
const observedFieldsByConcept = new Map();
|
|
287
|
-
const interactiveFieldsByConcept = new Map();
|
|
288
|
-
const interactiveLensesByConcept = new Map();
|
|
289
|
-
if (nonInteractive) {
|
|
290
|
-
// Non-interactive: use defaults without readline.
|
|
291
|
-
for (const folder of folders) {
|
|
292
|
-
const existing = folderBindings[folder];
|
|
293
|
-
const conceptName = conceptRefToPromptDefault(existing?.concept ?? null) ??
|
|
294
|
-
defaultConceptForFolder(promptConcepts, folder);
|
|
295
|
-
folderBindings[folder] = {
|
|
296
|
-
intent: existing?.intent || humanize(folder),
|
|
297
|
-
concept: conceptName,
|
|
298
|
-
};
|
|
299
|
-
if (suggestFields && conceptName !== null) {
|
|
300
|
-
const summary = observedByFolder.get(folder);
|
|
301
|
-
if (summary !== undefined) {
|
|
302
|
-
observedFieldsByConcept.set(conceptName, [
|
|
303
|
-
...(observedFieldsByConcept.get(conceptName) ?? []),
|
|
304
|
-
...summary.fields,
|
|
305
|
-
]);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
else {
|
|
311
|
-
// Interactive: ask intent and concept for each folder.
|
|
312
|
-
const rl = opts.prompt ??
|
|
313
|
-
createInterface({
|
|
314
|
-
input: process.stdin,
|
|
315
|
-
output: process.stdout,
|
|
316
|
-
});
|
|
317
|
-
const conceptNames = Array.from(promptConcepts.keys());
|
|
318
|
-
try {
|
|
319
|
-
console.log("\nOh My Second Brain Setup — adopting existing vault folders.\n");
|
|
320
|
-
console.log(`Available concepts: ${conceptNames.join(", ") || "(none)"}\n`);
|
|
321
|
-
for (const folder of folders) {
|
|
322
|
-
const existing = folderBindings[folder];
|
|
323
|
-
const defaultIntent = existing?.intent || humanize(folder);
|
|
324
|
-
const rawIntent = await rl.question(`Folder "${folder}" — intent [${defaultIntent}]: `);
|
|
325
|
-
const intent = rawIntent.trim() || defaultIntent;
|
|
326
|
-
// Find default concept
|
|
327
|
-
const defaultConcept = conceptRefToPromptDefault(existing?.concept ?? null) ??
|
|
328
|
-
defaultConceptForFolder(promptConcepts, folder);
|
|
329
|
-
const conceptPrompt = defaultConcept
|
|
330
|
-
? ` Bind concept [${defaultConcept}] (blank = ${defaultConcept}, "null" = none): `
|
|
331
|
-
: ` Bind concept (${conceptNames.join("/") || "none"}, blank = none): `;
|
|
332
|
-
const rawConcept = await rl.question(conceptPrompt);
|
|
333
|
-
const trimmed = rawConcept.trim();
|
|
334
|
-
let conceptName;
|
|
335
|
-
if (trimmed === "null" || trimmed === "") {
|
|
336
|
-
conceptName = trimmed === "null" ? null : (defaultConcept ?? null);
|
|
337
|
-
}
|
|
338
|
-
else if (promptConcepts.has(trimmed)) {
|
|
339
|
-
conceptName = trimmed;
|
|
340
|
-
}
|
|
341
|
-
else {
|
|
342
|
-
console.warn(` Unknown concept "${trimmed}"; binding as null.`);
|
|
343
|
-
conceptName = null;
|
|
344
|
-
}
|
|
345
|
-
folderBindings[folder] = { intent, concept: conceptName };
|
|
346
|
-
const summary = observedByFolder.get(folder);
|
|
347
|
-
if (summary !== undefined && summary.fields.length > 0 && conceptName !== null) {
|
|
348
|
-
const observedNames = summary.fields.map((field) => `${field.name}:${field.type}`).join(", ");
|
|
349
|
-
console.log(` Observed fields: ${observedNames}`);
|
|
350
|
-
for (const warning of summary.warnings) {
|
|
351
|
-
console.warn(` Frontmatter warning: ${warning}`);
|
|
352
|
-
}
|
|
353
|
-
const rawFields = await rl.question(" Add observed fields (comma-separated names, blank = none): ");
|
|
354
|
-
const requested = new Set(rawFields
|
|
355
|
-
.split(",")
|
|
356
|
-
.map((field) => field.trim())
|
|
357
|
-
.filter((field) => field.length > 0));
|
|
358
|
-
const selected = [];
|
|
359
|
-
for (const observed of summary.fields) {
|
|
360
|
-
if (!requested.has(observed.name))
|
|
361
|
-
continue;
|
|
362
|
-
const rawType = await rl.question(` Field "${observed.name}" type [${observed.type}]: `);
|
|
363
|
-
const trimmedType = rawType.trim();
|
|
364
|
-
const fieldType = isFieldType(trimmedType) ? trimmedType : observed.type;
|
|
365
|
-
const rawRequired = await rl.question(` Field "${observed.name}" required? [n]: `);
|
|
366
|
-
const rawFieldIntent = await rl.question(` Field "${observed.name}" intent [Observed ${observed.name}]: `);
|
|
367
|
-
selected.push({
|
|
368
|
-
name: observed.name,
|
|
369
|
-
type: fieldType,
|
|
370
|
-
required: /^y(?:es)?$/i.test(rawRequired.trim()),
|
|
371
|
-
intent: rawFieldIntent.trim() || `Observed ${observed.name}`,
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
if (selected.length > 0) {
|
|
375
|
-
interactiveFieldsByConcept.set(conceptName, [
|
|
376
|
-
...(interactiveFieldsByConcept.get(conceptName) ?? []),
|
|
377
|
-
...selected,
|
|
378
|
-
]);
|
|
379
|
-
}
|
|
380
|
-
const knownFields = new Set([
|
|
381
|
-
...Array.from(promptConcepts.get(conceptName)?.fields ?? []).map((field) => field.name),
|
|
382
|
-
...selected.map((field) => field.name),
|
|
383
|
-
]);
|
|
384
|
-
const rawLenses = await rl.question(" Retrieval lenses (name:field1,field2; blank = none): ");
|
|
385
|
-
const lenses = parseLensDefinitions(rawLenses, knownFields);
|
|
386
|
-
if (lenses.length > 0) {
|
|
387
|
-
interactiveLensesByConcept.set(conceptName, [
|
|
388
|
-
...(interactiveLensesByConcept.get(conceptName) ?? []),
|
|
389
|
-
...lenses,
|
|
390
|
-
]);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
finally {
|
|
396
|
-
rl.close();
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
const taxonomy = { version: existingTaxonomy?.version ?? 0, folders: folderBindings };
|
|
400
|
-
// Write the vault-local ontology. ``.oms/` IS the ontology directory:
|
|
401
|
-
// `.oms/taxonomy.yaml` + `.oms/concepts/*.yaml`, matching loadOntology's
|
|
402
|
-
// contract so `oms doctor` can load it directly.
|
|
403
|
-
const conceptsOutDir = path.join(omsDir, "concepts");
|
|
404
|
-
await mkdir(conceptsOutDir, { recursive: true });
|
|
405
|
-
await writeFile(path.join(omsDir, "taxonomy.yaml"), yamlStringify(taxonomy), "utf-8");
|
|
406
|
-
// Copy shipped concept yaml files into vault/.oms/concepts/
|
|
407
|
-
const conceptsSourceDir = path.join(ontologyDir, "concepts");
|
|
408
|
-
let copiedFiles = [];
|
|
409
|
-
try {
|
|
410
|
-
const conceptFiles = await readdir(conceptsSourceDir);
|
|
411
|
-
for (const file of conceptFiles) {
|
|
412
|
-
if (file.endsWith(".yaml") || file.endsWith(".yml")) {
|
|
413
|
-
const target = path.join(conceptsOutDir, file);
|
|
414
|
-
try {
|
|
415
|
-
await readFile(target, "utf-8");
|
|
416
|
-
}
|
|
417
|
-
catch (error) {
|
|
418
|
-
if (!(error instanceof Error))
|
|
419
|
-
throw error;
|
|
420
|
-
await copyFile(path.join(conceptsSourceDir, file), target);
|
|
421
|
-
copiedFiles.push(file);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
catch (err) {
|
|
427
|
-
console.warn("[oms] Could not copy concept files:", err);
|
|
428
|
-
}
|
|
429
|
-
const localOntology = await loadOntology(omsDir);
|
|
430
|
-
const localConceptDocuments = await readConceptDocuments(omsDir);
|
|
431
|
-
const conceptNamesToUpdate = new Set([
|
|
432
|
-
...observedFieldsByConcept.keys(),
|
|
433
|
-
...interactiveFieldsByConcept.keys(),
|
|
434
|
-
...interactiveLensesByConcept.keys(),
|
|
435
|
-
]);
|
|
436
|
-
for (const conceptName of conceptNamesToUpdate) {
|
|
437
|
-
const concept = localOntology.concepts.get(conceptName);
|
|
438
|
-
if (concept === undefined)
|
|
439
|
-
continue;
|
|
440
|
-
const withObserved = mergeObservedFieldsIntoConcept(concept, observedFieldsByConcept.get(conceptName) ?? []);
|
|
441
|
-
const withInteractiveFields = mergeAdditionalFields(withObserved, interactiveFieldsByConcept.get(conceptName) ?? []);
|
|
442
|
-
const withLenses = mergeAdditionalLenses(withInteractiveFields, interactiveLensesByConcept.get(conceptName) ?? []);
|
|
443
|
-
await writeConcept(omsDir, withLenses, localConceptDocuments.get(conceptName));
|
|
444
|
-
}
|
|
445
|
-
// Summary
|
|
446
|
-
console.log(`\nOh My Second Brain setup complete.`);
|
|
447
|
-
console.log(` Vault: ${vault}`);
|
|
448
|
-
console.log(` Written: ${path.join(omsDir, "taxonomy.yaml")}`);
|
|
449
|
-
console.log(` Concepts: ${copiedFiles.join(", ") || "(none)"}`);
|
|
450
|
-
console.log(` Folders: ${Object.keys(folderBindings).join(", ") || "(none)"}`);
|
|
451
|
-
console.log(`\nRun "oh-my-second-brain doctor" to validate existing notes.\n`);
|
|
452
|
-
if (installClaude) {
|
|
453
|
-
printClaudeInstallPlan(buildClaudeInstallPlan({ vault }));
|
|
454
|
-
console.log("");
|
|
70
|
+
conventionNote,
|
|
71
|
+
});
|
|
72
|
+
await maybePrintUpdateNotice();
|
|
455
73
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
export async function runDoctor(opts) {
|
|
461
|
-
const { vault } = opts;
|
|
462
|
-
// Doctor is non-blocking (onViolation: warn). It must ALWAYS exit 0 in v0,
|
|
463
|
-
// even if the ontology is missing or unparseable — wrap the whole body so a
|
|
464
|
-
// failure surfaces as a warning, never a non-zero exit.
|
|
465
|
-
try {
|
|
466
|
-
// Load ontology: prefer the vault-local `.oms/` ontology, fall back to the
|
|
467
|
-
// bundled defaults. The vault-local layout is `.oms/taxonomy.yaml` +
|
|
468
|
-
// `.oms/concepts/`, so `.oms/` itself is the ontology dir.
|
|
469
|
-
const localOntologyDir = path.join(vault, ".oms");
|
|
470
|
-
let ontologyDir;
|
|
471
|
-
try {
|
|
472
|
-
await readdir(path.join(localOntologyDir, "concepts"));
|
|
473
|
-
ontologyDir = localOntologyDir;
|
|
474
|
-
}
|
|
475
|
-
catch {
|
|
476
|
-
ontologyDir = bundledOntologyDir();
|
|
477
|
-
}
|
|
478
|
-
const ontology = await loadOntology(ontologyDir);
|
|
479
|
-
const skipDirs = new Set(["node_modules"]);
|
|
480
|
-
let totalNotes = 0;
|
|
481
|
-
let totalViolations = 0;
|
|
482
|
-
let notesWithViolations = 0;
|
|
483
|
-
for await (const relPath of walkMarkdown(vault, vault, skipDirs)) {
|
|
484
|
-
const concept = resolveConcept(ontology, relPath);
|
|
485
|
-
if (!concept)
|
|
486
|
-
continue;
|
|
487
|
-
totalNotes++;
|
|
488
|
-
const fullPath = path.join(vault, relPath);
|
|
489
|
-
let raw;
|
|
490
|
-
try {
|
|
491
|
-
raw = await readFile(fullPath, "utf-8");
|
|
492
|
-
}
|
|
493
|
-
catch {
|
|
494
|
-
console.warn(`[oms] Could not read ${relPath}`);
|
|
495
|
-
continue;
|
|
496
|
-
}
|
|
497
|
-
const { frontmatter } = parseNote(raw);
|
|
498
|
-
const result = validateFrontmatter(frontmatter, concept);
|
|
499
|
-
if (result.violations.length > 0) {
|
|
500
|
-
notesWithViolations++;
|
|
501
|
-
totalViolations += result.violations.length;
|
|
502
|
-
console.log(`\n ${relPath} [concept: ${concept.concept}]`);
|
|
503
|
-
for (const v of result.violations) {
|
|
504
|
-
console.log(` [${v.rule}] ${v.message}`);
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
console.log(`\nOh My Second Brain doctor: ${totalNotes} notes checked, ${notesWithViolations} with violations, ${totalViolations} total violations.`);
|
|
509
|
-
console.log("All violations are warnings (onViolation: warn). Exit 0.\n");
|
|
510
|
-
// Broken-link and orphan detection (C4 lint port).
|
|
511
|
-
try {
|
|
512
|
-
const lintResult = await detectLinkIssues(vault);
|
|
513
|
-
if (lintResult.brokenLinks.length > 0) {
|
|
514
|
-
console.log(`\n--- Broken wikilinks (${lintResult.brokenLinks.length}) ---`);
|
|
515
|
-
for (const { notePath, target } of lintResult.brokenLinks) {
|
|
516
|
-
console.log(` [broken-link] ${notePath} -> [[${target}]]`);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
else {
|
|
520
|
-
console.log("Broken wikilinks: 0");
|
|
521
|
-
}
|
|
522
|
-
const orphanCount = lintResult.orphanPaths.length;
|
|
523
|
-
if (orphanCount > 0) {
|
|
524
|
-
console.log(`\n--- Orphan notes (no incoming links): ${orphanCount} ---`);
|
|
525
|
-
for (const p of lintResult.orphanPaths.slice(0, 20)) {
|
|
526
|
-
console.log(` [orphan] ${p}`);
|
|
527
|
-
}
|
|
528
|
-
if (orphanCount > 20) {
|
|
529
|
-
console.log(` ... and ${orphanCount - 20} more`);
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
else {
|
|
533
|
-
console.log("Orphan notes: 0");
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
catch (lintErr) {
|
|
537
|
-
console.warn("[oms] lint detection could not complete:", lintErr);
|
|
538
|
-
}
|
|
74
|
+
else if (command === "install" || command === "uninstall") {
|
|
75
|
+
process.exitCode = await runInstallOrUninstall(command, hostContext());
|
|
76
|
+
if (process.exitCode === 0)
|
|
77
|
+
await maybePrintUpdateNotice();
|
|
539
78
|
}
|
|
540
|
-
|
|
541
|
-
|
|
79
|
+
else if (command === "update") {
|
|
80
|
+
process.exitCode = await runUpdateCommand(hostContext());
|
|
542
81
|
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
}
|
|
546
|
-
// ---------------------------------------------------------------------------
|
|
547
|
-
// main
|
|
548
|
-
// ---------------------------------------------------------------------------
|
|
549
|
-
function printUsage() {
|
|
550
|
-
console.log(`
|
|
551
|
-
oh-my-second-brain — Oh My Second Brain convention layer for Obsidian vaults
|
|
552
|
-
|
|
553
|
-
Usage:
|
|
554
|
-
oh-my-second-brain setup [--vault <path>] [--yes] [--suggest-fields] [--install-claude]
|
|
555
|
-
oh-my-second-brain install [--vault <path>] [--runtime <auto|all|claude|codex|hermes>] [--dry-run] [--execute] [--yes]
|
|
556
|
-
oh-my-second-brain uninstall [--runtime <all|claude|codex|hermes>] [--dry-run] [--execute] [--yes]
|
|
557
|
-
oh-my-second-brain update [--check] [--dry-run] [--yes] [--runtime <auto|all|claude|codex|hermes>] [--vault <path>]
|
|
558
|
-
oh-my-second-brain doctor [--vault <path>]
|
|
559
|
-
oh-my-second-brain semantic <status|sync|query|search|vsearch|get|multi-get|collection> [options]
|
|
560
|
-
oh-my-second-brain mcp [--vault <path>]
|
|
561
|
-
oh-my-second-brain hook pre-tool-use [--vault <path>]
|
|
562
|
-
oh-my-second-brain hook post-tool-use [--vault <path>]
|
|
563
|
-
|
|
564
|
-
Compatibility alias: oms <command>
|
|
565
|
-
|
|
566
|
-
Commands:
|
|
567
|
-
setup Adopt an existing vault into the Oh My Second Brain convention.
|
|
568
|
-
install Install Oh My Second Brain host adapters and MCP registration.
|
|
569
|
-
uninstall Remove Oh My Second Brain host adapters and MCP registration.
|
|
570
|
-
update Check for or apply an explicit package update, then refresh host adapters.
|
|
571
|
-
doctor Validate vault notes against the active ontology (includes broken-link and orphan detection).
|
|
572
|
-
semantic Native markdown semantic index/search/get commands.
|
|
573
|
-
mcp Start the read/status MCP stdio server.
|
|
574
|
-
hook Vault guard hooks for Claude Code PreToolUse / PostToolUse events.
|
|
575
|
-
pre-tool-use Read PreToolUse JSON from stdin; block unregistered folder creation.
|
|
576
|
-
post-tool-use Read PostToolUse JSON from stdin; audit frontmatter + trigger graph build.
|
|
577
|
-
|
|
578
|
-
Options:
|
|
579
|
-
--vault <path> Path to the vault root (default: current directory).
|
|
580
|
-
--yes Non-interactive setup, uninstall confirmation, or update execution.
|
|
581
|
-
--suggest-fields During setup --yes, add conservative observed frontmatter fields to concepts.
|
|
582
|
-
--install-claude Print Claude Code plugin install and MCP registration commands (dry-run).
|
|
583
|
-
--runtime <name> Select host runtime (default: auto for install, all for uninstall).
|
|
584
|
-
--dry-run Preview host config changes without writing files.
|
|
585
|
-
--execute Allow external host CLIs such as \`claude\` to run when available.
|
|
586
|
-
`);
|
|
587
|
-
}
|
|
588
|
-
async function main() {
|
|
589
|
-
const argv = process.argv.slice(2);
|
|
590
|
-
const command = argv[0];
|
|
591
|
-
// Parse shared flags.
|
|
592
|
-
let vault = process.cwd();
|
|
593
|
-
let yes = false;
|
|
594
|
-
let installClaude = false;
|
|
595
|
-
let suggestFields = false;
|
|
596
|
-
let runtime;
|
|
597
|
-
let dryRun = false;
|
|
598
|
-
let executeExternal = false;
|
|
599
|
-
let checkUpdate = false;
|
|
600
|
-
let timeoutMs;
|
|
601
|
-
let agentVault;
|
|
602
|
-
const unknownFlags = [];
|
|
603
|
-
for (let i = 1; i < argv.length; i++) {
|
|
604
|
-
if (argv[i] === "--vault" && argv[i + 1]) {
|
|
605
|
-
vault = path.resolve(argv[i + 1]);
|
|
606
|
-
i++;
|
|
607
|
-
}
|
|
608
|
-
else if (argv[i] === "--yes") {
|
|
609
|
-
yes = true;
|
|
610
|
-
}
|
|
611
|
-
else if (argv[i] === "--install-claude") {
|
|
612
|
-
installClaude = true;
|
|
613
|
-
}
|
|
614
|
-
else if (argv[i] === "--suggest-fields") {
|
|
615
|
-
suggestFields = true;
|
|
616
|
-
}
|
|
617
|
-
else if (argv[i] === "--check") {
|
|
618
|
-
checkUpdate = true;
|
|
619
|
-
}
|
|
620
|
-
else if (argv[i] === "--timeout-ms" && argv[i + 1]) {
|
|
621
|
-
const parsed = Number.parseInt(argv[i + 1], 10);
|
|
622
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
623
|
-
console.error(`[oms] Unsupported timeout: ${argv[i + 1]}`);
|
|
624
|
-
process.exitCode = 1;
|
|
625
|
-
return;
|
|
626
|
-
}
|
|
627
|
-
timeoutMs = parsed;
|
|
628
|
-
i++;
|
|
629
|
-
}
|
|
630
|
-
else if (argv[i] === "--runtime" && argv[i + 1]) {
|
|
631
|
-
const rawRuntime = argv[i + 1];
|
|
632
|
-
if (rawRuntime === "auto" ||
|
|
633
|
-
rawRuntime === "all" ||
|
|
634
|
-
rawRuntime === "claude" ||
|
|
635
|
-
rawRuntime === "codex" ||
|
|
636
|
-
rawRuntime === "hermes") {
|
|
637
|
-
runtime = rawRuntime;
|
|
638
|
-
}
|
|
639
|
-
else {
|
|
640
|
-
console.error(`[oms] Unsupported runtime: ${rawRuntime}`);
|
|
641
|
-
process.exitCode = 1;
|
|
642
|
-
return;
|
|
643
|
-
}
|
|
644
|
-
i++;
|
|
645
|
-
}
|
|
646
|
-
else if (argv[i] === "--agent-vault" && argv[i + 1]) {
|
|
647
|
-
agentVault = path.resolve(argv[i + 1]);
|
|
648
|
-
i++;
|
|
649
|
-
}
|
|
650
|
-
else if (argv[i] === "--dry-run") {
|
|
651
|
-
dryRun = true;
|
|
652
|
-
}
|
|
653
|
-
else if (argv[i] === "--execute") {
|
|
654
|
-
executeExternal = true;
|
|
655
|
-
}
|
|
656
|
-
else {
|
|
657
|
-
unknownFlags.push(argv[i]);
|
|
658
|
-
}
|
|
82
|
+
else if (command === "update-reconcile") {
|
|
83
|
+
process.exitCode = await runUpdateReconcile(hostContext());
|
|
659
84
|
}
|
|
660
|
-
if (command === "
|
|
661
|
-
await
|
|
85
|
+
else if (command === "doctor") {
|
|
86
|
+
process.exitCode = await runDoctor({ vault, verbose, json, maxPerConcept });
|
|
662
87
|
await maybePrintUpdateNotice();
|
|
663
88
|
}
|
|
664
|
-
else if (command === "
|
|
665
|
-
|
|
666
|
-
if (command === "uninstall" && !yes && !dryRun && process.env["OMS_NON_INTERACTIVE"] !== "1") {
|
|
667
|
-
console.error("[oms] Refusing uninstall without --yes or --dry-run.");
|
|
668
|
-
process.exitCode = 1;
|
|
669
|
-
return;
|
|
670
|
-
}
|
|
671
|
-
const results = await runHostOperation({
|
|
672
|
-
action: command,
|
|
673
|
-
runtime: selectedRuntime,
|
|
89
|
+
else if (command === "audit") {
|
|
90
|
+
process.exitCode = await runAudit({
|
|
674
91
|
vault,
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
yes,
|
|
679
|
-
adapterRoot: bundledAdapterRoot(),
|
|
92
|
+
json,
|
|
93
|
+
folder: folders[0],
|
|
94
|
+
suggestFields,
|
|
680
95
|
});
|
|
681
|
-
console.log(formatHostOperationResults(results, dryRun));
|
|
682
96
|
await maybePrintUpdateNotice();
|
|
683
97
|
}
|
|
684
|
-
else if (command === "
|
|
685
|
-
|
|
686
|
-
console.error(`[oms] Unsupported update option: ${unknownFlags.join(", ")}`);
|
|
687
|
-
process.exitCode = 1;
|
|
688
|
-
return;
|
|
689
|
-
}
|
|
690
|
-
const currentVersion = await readCurrentPackageVersion();
|
|
691
|
-
const latestVersion = process.env["OMS_UPDATE_LATEST_VERSION"];
|
|
692
|
-
const result = await runUpdate({
|
|
693
|
-
currentVersion,
|
|
694
|
-
latestVersion,
|
|
695
|
-
runtime: runtime ?? "all",
|
|
98
|
+
else if (command === "linkify") {
|
|
99
|
+
process.exitCode = await runLinkify({
|
|
696
100
|
vault,
|
|
697
|
-
|
|
698
|
-
|
|
101
|
+
folder: folders[0],
|
|
102
|
+
apply,
|
|
699
103
|
yes,
|
|
700
|
-
executeExternal,
|
|
701
|
-
timeoutMs,
|
|
702
|
-
reconcileCommand: {
|
|
703
|
-
command: process.execPath,
|
|
704
|
-
argsPrefix: process.argv[1] === undefined ? [] : [process.argv[1]],
|
|
705
|
-
},
|
|
706
|
-
});
|
|
707
|
-
console.log(formatUpdateResult(result));
|
|
708
|
-
process.exitCode = result.success ? 0 : 1;
|
|
709
|
-
}
|
|
710
|
-
else if (command === "update-reconcile") {
|
|
711
|
-
if (process.env["OMS_UPDATE_RECONCILE"] !== "1" && !dryRun) {
|
|
712
|
-
console.error("[oms] update-reconcile is internal; run `oms update --yes` instead.");
|
|
713
|
-
process.exitCode = 1;
|
|
714
|
-
return;
|
|
715
|
-
}
|
|
716
|
-
const results = await runHostOperation({
|
|
717
|
-
action: "install",
|
|
718
|
-
runtime: runtime ?? "all",
|
|
719
|
-
vault,
|
|
720
|
-
dryRun,
|
|
721
|
-
executeExternal,
|
|
722
|
-
yes: true,
|
|
723
|
-
adapterRoot: bundledAdapterRoot(),
|
|
724
104
|
});
|
|
725
|
-
|
|
105
|
+
await maybePrintUpdateNotice();
|
|
726
106
|
}
|
|
727
|
-
else if (command === "
|
|
728
|
-
process.exitCode = await
|
|
107
|
+
else if (command === "lint") {
|
|
108
|
+
process.exitCode = await runLint({ vault, verbose, json });
|
|
729
109
|
await maybePrintUpdateNotice();
|
|
730
110
|
}
|
|
731
111
|
else if (isSemanticCliCommand(command)) {
|
|
@@ -736,7 +116,10 @@ async function main() {
|
|
|
736
116
|
await maybePrintUpdateNotice();
|
|
737
117
|
}
|
|
738
118
|
else if (command === "mcp") {
|
|
739
|
-
await runMcpServer({
|
|
119
|
+
await runMcpServer({
|
|
120
|
+
vault,
|
|
121
|
+
source: mcpTarget?.source ?? "explicit",
|
|
122
|
+
});
|
|
740
123
|
}
|
|
741
124
|
else if (command === "hook") {
|
|
742
125
|
const subcommand = argv[1];
|
|
@@ -756,9 +139,23 @@ async function main() {
|
|
|
756
139
|
printUsage();
|
|
757
140
|
process.exitCode = 0;
|
|
758
141
|
}
|
|
142
|
+
function hostContext() {
|
|
143
|
+
return {
|
|
144
|
+
vault,
|
|
145
|
+
vaultExplicit,
|
|
146
|
+
runtime,
|
|
147
|
+
agentVault,
|
|
148
|
+
dryRun,
|
|
149
|
+
executeExternal,
|
|
150
|
+
yes,
|
|
151
|
+
json,
|
|
152
|
+
checkUpdate,
|
|
153
|
+
timeoutMs,
|
|
154
|
+
unknownFlags,
|
|
155
|
+
adapterRoot: bundledAssets.adapterRoot,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
759
158
|
}
|
|
760
|
-
// Guard: only run main() when this file is the entry point.
|
|
761
|
-
// Works for both source (`src/cli/oms.ts`) and built (`dist/cli/oms.js`) paths.
|
|
762
159
|
const __filename = fileURLToPath(import.meta.url);
|
|
763
160
|
function sameEntrypoint(left, right) {
|
|
764
161
|
const resolvedLeft = path.resolve(left);
|