mrplex 0.0.3 → 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/README.md CHANGED
@@ -2,285 +2,247 @@
2
2
 
3
3
  *Markdown Repos, plexed.*
4
4
 
5
- **Turn ordinary Markdown folders into queryable, versioned, graph-aware knowledge stores — without giving up files.** Your notes stay plain `.md` on disk; agents and humans share the same repository, every write is versioned, and links survive renames.
5
+ mrplex turns a folder of Markdown files into a queryable, versioned knowledge store — without taking your files hostage. Your notes stay ordinary `.md` on disk, readable and editable by any tool you already use. On top of that folder mrplex adds four things a plain directory can't give you:
6
6
 
7
- ## Install
7
+ - **Search** over your YAML frontmatter — filter with a small expression language, run full-text search across bodies, and (optionally) rank by meaning.
8
+ - **Versions** — every write is kept, so you can see history, diff two points, and never lose an overwrite to a race.
9
+ - **A link graph** that tracks how your documents connect and survives renames, so moving a file doesn't break the links pointing at it.
10
+ - **One model over three surfaces** — the same store is reachable from the CLI, from an MCP server, and over REST.
8
11
 
9
- Node 20.11:
12
+ That last point is the reason mrplex exists: it gives an AI agent a way to *explore and maintain* a vault the way a person would — by asking precise questions and following relationships — instead of grepping around and guessing.
10
13
 
11
- ```bash
12
- npm install -g mrplex
13
- ```
14
-
15
- Prefer not to install globally? `npx mrplex …` works the same way.
14
+ ## Quickstart
16
15
 
17
- Point every command at a database and default repo once (the tour below uses `starship`):
16
+ Install it (Node 20.11 or newer):
18
17
 
19
- ```bash
20
- export MRPLEX_DATABASE=./demo.db
21
- export MRPLEX_REPO=starship
18
+ ```sh
19
+ $ npm install -g mrplex
22
20
  ```
23
21
 
24
- Or persist settings in `~/.config/mrplex/config.json`:
22
+ Point it at a folder of Markdown and start asking questions:
25
23
 
26
- ```bash
27
- mrplex config set-database ./demo.db
28
- mrplex config set-repo starship
24
+ ```sh
25
+ $ mrplex repos create notes
26
+ created repo notes
27
+ $ mrplex config set-repo notes # remember the default; no more -r on every command
28
+ config: repo set
29
+ $ mrplex sync ~/notes --once
30
+ sync notes @ ~/notes: through=v0 actions=128 feed=0
31
+ $ mrplex query --text 'that thing you half remember'
32
+ $path
33
+ ---------------------------
34
+ projects/roadmap.md
35
+ meeting-notes/2026-08-12.md
29
36
  ```
30
37
 
31
- Each setting resolves **flag env config file default**, so one-off overrides never require editing anything.
32
-
33
- > **From a git checkout?** Run `npm install && npm link` (or `npm run cli -- …`). Every `mrplex …` command below is equivalent to `npx mrplex …`.
38
+ That's the whole loop: create a repo, load a folder into it, then query. A repo is just a named collection of documents inside one database (which defaults to `./mrplex.db` — no configuration needed). Any folder of `.md` works, Obsidian vaults included.
34
39
 
35
- ## A five-minute tour
40
+ `sync` is two-way. With `--once` it reconciles the folder and the store a single time and exits; drop the flag and it keeps running, watching for changes on both sides. To do that it records a little bookkeeping — two keys, `$version` and `$content_hash` — in each file's frontmatter. That's how a file on disk remembers which stored version it came from, so edits made outside mrplex are matched up correctly on the next sync.
36
41
 
37
- This walkthrough uses the **USS Meridian** — a sample starship knowledge base in [`fixtures/starship/`](fixtures/starship/): crew files, mission records, officer logs, and equipment status, all ordinary Markdown with YAML frontmatter.
42
+ ## A guided tour: the USS Meridian
38
43
 
39
- ### 1. Sync the sample corpus
44
+ The repository ships a demo vault in `fixtures/starship/` — the crew, missions, logs, and equipment of a fictional survey starship, all short interlinked notes. It's the easiest way to see what the queries actually do.
40
45
 
41
- Clone the repo (for the fixture files), install, and sync the folder into a fresh mrplex repo:
46
+ First copy it out of the checkout and load it. (Copy rather than sync in place: `sync` writes those `$version` tracking keys into the files, and there's no reason to dirty the committed fixture.)
42
47
 
43
- ```bash
44
- git clone https://github.com/usergenic/mrplex
45
- cd mrplex
46
- npm install && npm link # skip if you installed globally above
47
-
48
- export MRPLEX_DATABASE=./demo.db
49
- export MRPLEX_REPO=starship
50
-
51
- mrplex repos create starship
52
- mrplex sync fixtures/starship --once -r starship
48
+ ```sh
49
+ $ git clone https://github.com/usergenic/mrplex
50
+ $ cp -r mrplex/fixtures/starship .
51
+ $ mrplex repos create starship
52
+ created repo starship
53
+ $ mrplex config set-repo starship
54
+ config: repo set
55
+ $ mrplex sync starship --once
56
+ sync starship @ starship: through=v0 actions=30 feed=0
53
57
  ```
54
58
 
55
- `sync` is the normal way to load a Markdown folder: it pushes local files into the repo, materializes version metadata, and keeps a cursor for two-way updates. Frontmatter values written as repo-root paths (`/crew/foo.md`) and embedded wikilinks/inline links are indexed automatically — no link-config setup step.
59
+ ### Ask about your frontmatter
56
60
 
57
- No bootstrap, no tokenlocal mode is full-trust (whoever can run the binary owns the database).
61
+ Filters are written in [CEL](https://cel.dev/) — a small, safe expression language and evaluated against each document's frontmatter, plus a few built-in fields like `$path` and `$body`. So "what equipment is broken right now?" is a plain boolean expression over the `status` field. Use `-s` (repeatable) to choose which fields come back in the table:
58
62
 
59
- ### 2. Query it like data
63
+ ```sh
64
+ $ mrplex query --filter 'status == "damaged" || status == "offline"' -s title -s status -s maintainer
65
+ title status maintainer
66
+ ---------------------------- ------- -------------------
67
+ Shuttle Corvid offline /crew/dax-thorne.md
68
+ Number Three Plasma Manifold damaged /crew/bexley-orr.md
69
+ ```
60
70
 
61
- Frontmatter is queryable with [CEL](https://github.com/google/cel-spec) filters:
71
+ ### Ask about the links between documents
62
72
 
63
- ```bash
64
- # What's broken or offline right now?
65
- mrplex query --filter 'status == "damaged" || status == "offline"'
73
+ Some questions are about *relationships* rather than fields — "who reports to the captain?" The frontmatter in each crew file has a `reports_to` link, and mrplex indexes those into a graph you can query directly. `$has(target, field)` means "which documents link to `target` through `field`":
66
74
 
67
- # Who reports directly to the captain?
68
- mrplex query --filter '$has_static("crew/kestrel-vance.md", "reports_to")'
75
+ ```sh
76
+ $ mrplex query --filter '$has("crew/kestrel-vance.md", "reports_to")'
77
+ $path
78
+ ---------------------
79
+ crew/quill-vasquez.md
80
+ crew/dax-thorne.md
81
+ crew/aria-okonkwo.md
69
82
  ```
70
83
 
71
- ```text
72
- PATH STATUS
73
- equipment/plasma-manifold-3.md damaged
74
- equipment/shuttle-corvid.md offline
75
-
84
+ ### Combine filters, text, and meaning
76
85
 
77
- PATH TITLE
78
- crew/aria-okonkwo.md Commander Aria Okonkwo
79
- crew/dax-thorne.md Lieutenant Commander Dax Thorne
80
- crew/quill-vasquez.md Doctor Quill Vasquez
81
- ```
82
-
83
- Compose with full-text search — filter, text, and semantic (when configured) all AND together:
86
+ A filter, a full-text search, and a semantic search can all be given at once; results must satisfy all of them (they combine with AND). Here: log entries — `type == "log"` — that also mention "coolant":
84
87
 
85
- ```bash
86
- mrplex query --text 'manifold coolant'
87
- mrplex query --filter 'type == "mission"' --text 'Halloway'
88
+ ```sh
89
+ $ mrplex query --filter 'type == "log"' --text 'coolant'
90
+ $path
91
+ ---------------------
92
+ logs/orr-4413-1.md
93
+ logs/thorne-4413-2.md
88
94
  ```
89
95
 
90
- ### 3. Follow the links as a graph
96
+ By default a query returns just the paths of the matches. You then fetch the full content of only the documents you actually need. This keeps result sets small — which matters a lot when the thing running the query is an agent paying by the token.
97
+
98
+ ### Rename a file without breaking its backlinks
91
99
 
92
- Markdown links, wikilinks, and frontmatter repo-root paths (`/crew/foo.md`) build a derived index bound to document *identity*, so backlinks survive renames. Query membership in CEL:
100
+ This is the payoff of tracking links as a graph. mrplex ties each link to a document's *identity*, not to the path string someone typed. Rename a document and everything that pointed at it still points at it.
93
101
 
94
- ```bash
95
- # Every mission indexed by the mission log MOC
96
- mrplex query --filter '$in_static("moc/missions.md")'
102
+ `docs mv` moves a document. The `--prev` flag is how mrplex prevents two writers from clobbering each other: you pass the version you're basing your change on, and the write is rejected if someone else moved first (more on that below).
97
103
 
98
- # What touches the damaged plasma manifold? (maintainer field, body links, logs…)
99
- mrplex query --filter '$has_static("equipment/plasma-manifold-3.md")'
104
+ ```sh
105
+ $ V=$(mrplex --json docs get equipment/plasma-manifold-3.md | jq -r .version_id)
106
+ $ mrplex docs mv equipment/manifold-3.md --prev "$V"
107
+ v31
108
+ wrote starship/equipment/manifold-3.md @ v31 (author: mrplex)
100
109
  ```
101
110
 
102
- Explore *how* documents connectneighborhood expansion from a root set:
111
+ Seven documents linked to the old path. Ask the graph who links to the *new* path, and all seven are already there the relationships followed the document:
103
112
 
104
- ```bash
105
- mrplex graph --roots missions/the-hollow-signal.md --degrees 2 --direction both --render summary
113
+ ```sh
114
+ $ mrplex query --filter '$has("equipment/manifold-3.md")'
115
+ $path
116
+ ---------------------------
117
+ missions/the-cinder-run.md
118
+ logs/thorne-4413-2.md
119
+ logs/orr-4420-1.md
120
+ logs/orr-4413-1.md
121
+ equipment/coolant-loop-b.md
122
+ crew/dax-thorne.md
123
+ crew/bexley-orr.md
106
124
  ```
107
125
 
108
- The missing officer, his mission, the encounter, and the logs that mention him appear as a connected neighborhood the kind of thread a flat file listing can't give you.
126
+ The graph is correct, but the *link text* those files still contain on disk (`equipment/plasma-manifold-3.md`) is now out of date. `links stale` shows you exactly where, and `links repair` rewrites it for you:
109
127
 
110
- Mermaid for slides or docs:
111
-
112
- ```bash
113
- mrplex graph --roots crew/kestrel-vance.md --degrees 2 --direction out --render mermaid
128
+ ```sh
129
+ $ mrplex links stale
130
+ crew/bexley-orr.md: "equipment/plasma-manifold-3.md" → "equipment/manifold-3.md"
131
+ crew/dax-thorne.md: "equipment/plasma-manifold-3.md" "equipment/manifold-3.md"
132
+ equipment/coolant-loop-b.md: "equipment/plasma-manifold-3.md" → "equipment/manifold-3.md"
133
+ logs/orr-4413-1.md: "equipment/plasma-manifold-3.md" → "equipment/manifold-3.md"
134
+ logs/orr-4420-1.md: "equipment/plasma-manifold-3.md" → "equipment/manifold-3.md"
135
+ logs/thorne-4413-2.md: "equipment/plasma-manifold-3.md" → "equipment/manifold-3.md"
136
+ missions/the-cinder-run.md: "equipment/plasma-manifold-3.md" → "equipment/manifold-3.md"
137
+ $ mrplex links repair
138
+ repaired 7 doc(s), skipped 0
114
139
  ```
115
140
 
116
- ### 4. Change something safely
117
-
118
- Every write inserts a new version; nothing is overwritten. Rename a document and the link graph follows its identity:
141
+ ### Explore a neighborhood
119
142
 
120
- ```bash
121
- # See current version id, then move the manifold note
122
- V=$(mrplex --json docs get equipment/plasma-manifold-3.md | jq -r .version_id)
123
- mrplex docs mv equipment/manifold-3.md --prev "$V"
143
+ `query` finds documents that match. `graph` shows you how a document connects — the links going out of it and coming into it, out to a chosen number of hops. `--render summary` prints it as an indented outline (`→` is a link out, `←` a link in, and the parenthetical is the field the link came from):
124
144
 
125
- # Backlinks still resolve — the graph never broke; link text may need repair
126
- mrplex query --filter '$has_static("equipment/manifold-3.md")'
127
- mrplex links stale
145
+ ```sh
146
+ $ mrplex graph --roots equipment/manifold-3.md --degrees 1 --render summary
147
+ equipment/manifold-3.md (0)
148
+ →($body) equipment/coolant-loop-b.md, missions/the-cinder-run.md
149
+ →(maintainer) crew/bexley-orr.md
150
+ →(related) equipment/coolant-loop-b.md
151
+ ←($body) crew/bexley-orr.md, crew/dax-thorne.md, equipment/coolant-loop-b.md, logs/orr-4413-1.md, ...
152
+ ... (each neighbor expands the same way, out to the requested degree)
128
153
  ```
129
154
 
130
- History and unified diff between any two versions:
155
+ Use `--render mermaid` instead to get a diagram you can paste into any Markdown renderer.
131
156
 
132
- ```bash
133
- mrplex docs history equipment/manifold-3.md
134
- mrplex docs diff equipment/manifold-3.md --from v1 --to v2
135
- ```
157
+ ### Versions, always
136
158
 
137
- Deletion moves a document to a system-namespace path (`:deleted/…`); restore is a normal `docs put` back to user territory.
159
+ Every write appends a new version rather than overwriting — so history is never lost. That's also what makes `--prev` work: it's *optimistic concurrency*. You tell a write which version you started from; if someone else has written in the meantime, yours is rejected and you're handed the current version to reconcile against, instead of silently clobbering their change. Deleting a document moves it aside to `:deleted/…` rather than erasing it, so a delete can be undone with an ordinary write. When you need the record, `docs history` lists a document's versions and `docs diff --from v1 --to v2` shows what changed.
138
160
 
139
- ### 5. Connect an agent
161
+ ## Connect an agent
140
162
 
141
- CLI, MCP, and REST are surfaces over the same model. Point Cursor (or any MCP client) at your local database:
163
+ The CLI, the MCP server, and the REST API are three doors into the same store. For a database only you touch, the quickest way to give an agent access is MCP over local stdio — for example, in a client's MCP configuration:
142
164
 
143
165
  ```json
144
166
  {
145
167
  "mcpServers": {
146
168
  "mrplex": {
147
169
  "command": "mrplex",
148
- "args": ["mcp-stdio", "--unsafe", "--database", "./demo.db"],
149
- "env": { "MRPLEX_REPO": "starship" }
170
+ "args": ["mcp-stdio", "--unsafe", "--database", "./mrplex.db"]
150
171
  }
151
172
  }
152
173
  }
153
174
  ```
154
175
 
155
- An agent can now ask relational questions*"What's broken on the ship, who maintains it, and which missions were affected?"* and recover structured answers through `query` and `graph` instead of reading every file into context.
176
+ `--unsafe` runs the store with no authenticationevery caller has full access. That's an acceptable choice for a private database file on your own machine, and the wrong choice for anything reachable over a network. The next section is what you use instead when more than one principal is involved, or when you want to guard against a destructive agent mishap.
156
177
 
157
- Serve HTTP for remote clients or Streamable HTTP MCP:
178
+ ## Access control
158
179
 
159
- ```bash
160
- mrplex serve --unsafe --port 8321 &
161
- mrplex --server http://127.0.0.1:8321 query --filter 'status == "missing"'
180
+ When you need real principals — say, an agent that may read and write documents, plus a separate admin identity that can create and delete repos — mrplex generates a starter policy and signing keys for you, so there's no YAML to write by hand:
181
+
182
+ ```sh
183
+ $ mrplex policy create policy.yaml --principal agent
184
+ wrote policy.yaml
185
+ $ mrplex key mint agent --policy policy.yaml # a day-to-day key for the agent
186
+ $ mrplex serve --policy policy.yaml --audit audit.jsonl
162
187
  ```
163
188
 
164
- For shared or networked deployments, run the authenticating shell instead see [Authentication](#authentication) below. Never expose the raw kernel (`serve --unsafe`) directly to an untrusted network.
189
+ `policy create` takes the filename to write and scaffolds two roles: a `maintainer` (the `--principal` you name) for everyday reads and writes, and an `operator` admin for repo management. `policy check` validates a policy and can print out exactly what a given principal is allowed to do.
165
190
 
166
- ## How it works
191
+ You can enforce that policy in three arrangements: embedded in the server (`serve --policy`), in front of the stdio launcher (`mcp-stdio --policy`), or as a standalone proxy ahead of an existing engine (`proxy --policy --upstream`). Edit the file and send the server `SIGHUP` (`kill -HUP`) to reload it without downtime; `mrplex login` signs in through an OIDC device flow. Full details are in [docs/archive/security.md](docs/archive/security.md).
167
192
 
168
- | Concept | What it means |
169
- |--------|----------------|
170
- | **Document** | One Markdown file with YAML frontmatter, addressed by repo-relative path |
171
- | **Version** | Every write appends; `prev_version_id` optimistic concurrency rejects stale writes |
172
- | **Query** | CEL filters over frontmatter + `$path` / `$body` / `$updated_at` intrinsics; composes with FTS and semantic search |
173
- | **Link graph** | Derived index over inline links, wikilinks, and frontmatter repo-root paths; `$in`, `$has`, `$backlinks`, `$links` in CEL |
174
- | **Graph** | BFS neighborhood expansion over the link index — *how* things connect, not just *which* match |
175
- | **Surfaces** | `mrplex` CLI (local or `--server`), MCP at `/mcp` or `mcp-stdio`, REST at `/repos/{repo}/…` |
176
-
177
- Two layers: a **full-trust kernel** (no in-engine auth) and an optional **access-and-identity shell** (API keys, OIDC, per-path write policy, audit log). See [docs/archive/security.md](docs/archive/security.md) for trust boundaries and deployment shapes.
178
-
179
- ## Features
180
-
181
- <details>
182
- <summary>Full feature list</summary>
183
-
184
- - **Versioned Markdown store** — every write inserts; `docs.put` handles in-place update and move; any past state is addressable
185
- - **Byte-exact frontmatter** — `frontmatter_raw` (verbatim YAML) or `frontmatter` (JSON); exactly one; round-trips are byte-exact via raw
186
- - **Optimistic concurrency** — stale `prev_version_id` → `stale_prev` with current version returned
187
- - **Deletion as move** — `:deleted/…` paths; idempotent delete; restore via `docs.put`
188
- - **Unified diff** — `docs.diff`, REST `/diff`, MCP `docs_diff`, CLI `mrplex docs diff`; `patch(1)`-applicable output
189
- - **CEL filter queries** — frontmatter fields + `$`-intrinsics; `list()` polymorphism for scalar-or-list fields
190
- - **Link graph** — inline, wikilink, and frontmatter path extraction (no per-field config); backlinks survive renames; set algebra (`$in("moc/**") && !$in("moc/draft.md")`); `$in_static` for link-only membership; `links stale` / `repair` / `backfill`
191
- - **Graph exploration** — BFS with direction lens, visibility filter, graph-only `$degrees` intrinsic; CLI `--render summary|yaml|mermaid|json`
192
- - **Full-text search** — SQLite FTS5 or Postgres `websearch_to_tsquery`; composes with filter via AND
193
- - **Semantic search** — pluggable `--embedder` hook; chunker + backlog worker; `$semantic_score` in `select`; no hook → `semantic_unavailable`
194
- - **HTTP surfaces** — MCP (Streamable HTTP + STDIO), REST with `If-Match` / content negotiation / `MOVE`
195
- - **CLI** — thin MCP client; `--database` local or `--server` remote; identical commands over both
196
- - **Storage** — SQLite (default) or Postgres+pgvector; same kernel test suite on both
197
- - **Path policy** — configurable sigils and disallowed chars; NFC + case-insensitive identity, case-preserved storage
198
- - **Canonical paths** — API responses use slashless repo-relative paths; leading `/` accepted as root alias on input only
199
-
200
- Prior design docs in [docs/archive/](docs/archive/) may be out of date where later work supersedes them.
201
-
202
- </details>
203
-
204
- ## Authentication
205
-
206
- For anything beyond single-user local use, run the **authenticating shell** — `serve --policy`. It reads declarative YAML (roles, principals, grants, key hashes, OIDC bindings), authenticates each request, and dispatches against a per-principal *guarded* kernel: read visibility narrowed, writes enforced per-path, author derived from the credential, every call audited.
207
-
208
- ```yaml
209
- # policy.yaml
210
- roles:
211
- editor:
212
- grants:
213
- - repo: notes
214
- read: "**"
215
- write: ["drafts/**", "inbox/**"]
216
- operator:
217
- grants:
218
- - { repo: "*", read: "**", write: "**" }
219
- destructive: true
220
-
221
- principals:
222
- brendan:
223
- author: Brendan Baldwin <brendan@example.com>
224
- roles: [operator]
225
- keys:
226
- - sha256:... # `mrplex key mint brendan --policy policy.yaml`
227
- ann:
228
- roles: [editor]
229
- oidc: { email: ann@example.com }
230
- ```
193
+ One rule worth repeating: never expose `serve --unsafe` to an untrusted network — it is, by definition, an open door.
231
194
 
232
- ```bash
233
- mrplex key mint brendan --policy policy.yaml
234
- mrplex serve --policy policy.yaml --audit audit.jsonl --port 8321 &
235
- curl -H "Authorization: Bearer $KEY" http://127.0.0.1:8321/repos
236
- ```
195
+ ## How it works
237
196
 
238
- Three deployment shapes **embedded** (`serve --policy`), **launcher** (`mcp-stdio --policy`), and **fronting proxy** (`proxy --policy --upstream`). Edit the policy and `kill -HUP` to reload grants without restart. OIDC device-flow login via `mrplex login`. Full details in [docs/archive/security.md](docs/archive/security.md).
197
+ mrplex is built from a few concepts:
239
198
 
240
- ## Embeddings
199
+ | Concept | What it is |
200
+ | -------------- | ------------------------------------------------------------------------------------------ |
201
+ | **Document** | One Markdown file with YAML frontmatter, addressed by its path within a repo |
202
+ | **Version** | Every write appends a new one; `--prev` rejects a write based on a stale version |
203
+ | **Query** | A CEL filter over frontmatter and `$path` / `$body` / `$updated_at`, combined with full-text and semantic search |
204
+ | **Link graph** | Links from Markdown syntax, wikilinks, and frontmatter paths, tracked by identity so renames don't break them |
205
+ | **Graph walk** | A breadth-first tour of that link graph — *how* documents connect, not just which ones match |
206
+ | **Surfaces** | The CLI, an MCP server, and a REST API, all over the same store |
241
207
 
242
- mrplex never calls an embedding provider itself — wire one with `--embedder` (subprocess command or HTTP URL). For local CPU embeddings:
208
+ Underneath, mrplex is two layers. The **kernel** is the store itself — documents, versions, queries, the graph and it is full-trust: it has no notion of users, so whoever holds the database file holds everything. Around it is an optional **access-and-identity shell** that adds keys, OIDC, per-path permissions, and an audit log when you need them. The store runs on SQLite by default, or Postgres with pgvector when you want it; the same test suite runs against both, so behavior matches.
243
209
 
244
- ```bash
245
- npm install -g @mrplex/embedder
246
- export MRPLEX_EMBEDDER=mrplex-embedder # or: mrplex config set-embedder mrplex-embedder
210
+ ## Semantic search
247
211
 
248
- mrplex serve --unsafe --embedder mrplex-embedder
249
- mrplex embed backfill -r starship
250
- mrplex query -r starship --semantic 'distress beacon star map' # uses env/config
251
- # or per-invocation in local (--database) mode:
252
- mrplex query -r starship --embedder mrplex-embedder --semantic 'distress beacon star map'
253
- ```
212
+ mrplex never calls an embedding provider on its own — you decide what does the embedding by wiring in a hook. The companion package `@mrplex/embedder` runs a small local model on CPU, which is enough to get started:
254
213
 
255
- Resolution: **flag → `MRPLEX_EMBEDDER` → `mrplex config set-embedder` → unset**. In local mode, `query --embedder` overrides for that call; with `--server`, configure the embedder on the host. See [packages/embedder/README.md](packages/embedder/README.md) for protocol details.
214
+ ```sh
215
+ $ npm install -g @mrplex/embedder
216
+ $ mrplex serve --unsafe --embedder mrplex-embedder
217
+ $ mrplex embed backfill # embed everything already in the repo
218
+ $ mrplex query --semantic 'distress beacon star map'
219
+ ```
256
220
 
257
- ## Development
221
+ Point `--embedder` at a command (like the one above) or at an `http(s)://` URL for a remote embedding service. If no hook is configured, a semantic query returns a clear `semantic_unavailable` error rather than silently ranking by nothing. And treat semantic results as a shortlist of candidates worth reading, not a final answer — skim the top hits before you rely on them. The hook protocol is documented in [packages/embedder/README.md](packages/embedder/README.md).
258
222
 
259
- ```bash
260
- npm install
261
- npm link
262
- npm test
263
- npm run typecheck
264
- npm run lint
265
- npm run build
266
- ```
223
+ ## Configuration
267
224
 
268
- Seed the full dev fixture set (notes + starship):
225
+ Every setting resolves in the same order: a command-line **flag**, then an **environment variable**, then the **config file**, then a built-in default. Save the defaults you're tired of typing:
269
226
 
270
- ```bash
271
- npm run seed -- --database ./mrplex.db
227
+ ```sh
228
+ $ mrplex config set-database ./mrplex.db
229
+ $ mrplex config set-author "Ada Lovelace <ada@example.com>"
272
230
  ```
273
231
 
274
- CI runs typecheck + lint + tests on Ubuntu & macOS × Node 20 & 22, plus Postgres+pgvector parity. If tests fail with a `NODE_MODULE_VERSION` error from `better-sqlite3`, run `npm rebuild better-sqlite3`.
232
+ The matching environment variables are `MRPLEX_DATABASE`, `MRPLEX_REPO`, `MRPLEX_AUTHOR`, and `MRPLEX_EMBEDDER`.
275
233
 
276
- ### Postgres locally
234
+ A note on repo scope: your default repo (from `config set-repo` or `MRPLEX_REPO`) applies to every command, `query` included. To search more than one repo, say so on that command: `query -r` can be repeated and accepts glob patterns, and `-r '*'` searches every repo in the database. The wildcard only works as an explicit flag — a saved default can never quietly widen a search to your whole database.
277
235
 
278
- ```bash
279
- npm run pg:up
280
- export MRPLEX_DATABASE=postgres://mrplex:mrplex@localhost:5432/mrplex
281
- mrplex serve --unsafe
236
+ ## Development
237
+
238
+ ```sh
239
+ $ npm install && npm link
240
+ $ npm test
241
+ $ npm run typecheck && npm run lint && npm run build
282
242
  ```
283
243
 
244
+ CI runs typecheck, lint, and tests on Ubuntu and macOS across Node 20 and 22, plus a Postgres + pgvector parity run (`npm run pg:up` starts a local instance). If `better-sqlite3` reports a `NODE_MODULE_VERSION` mismatch, rebuild it with `npm rebuild better-sqlite3`.
245
+
284
246
  ## License
285
247
 
286
248
  MIT — see [LICENSE](LICENSE).
@@ -18,10 +18,6 @@ export type CliConfig = {
18
18
  author?: string;
19
19
  /** Default --embedder (command or http(s):// URL). */
20
20
  embedder?: string;
21
- /** @deprecated Use `embedder`. */
22
- embed_url?: string;
23
- /** @deprecated Use `embedder`. */
24
- embed_cmd?: string;
25
21
  };
26
22
  export declare function configPath(): string;
27
23
  export declare function loadConfig(): CliConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAgB1C,MAAM,UAAU,UAAU;IACxB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IAC5E,OAAO,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;QAC3C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3E,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,MAAmB,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,2EAA2E;QAC3E,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QAChE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAe;IACxC,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3E,IAAI,CAAC;QACH,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;IAC3D,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAY1C,MAAM,UAAU,UAAU;IACxB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IAC5E,OAAO,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;QAC3C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3E,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,MAAmB,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,2EAA2E;QAC3E,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QAChE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAe;IACxC,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3E,IAAI,CAAC;QACH,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;IAC3D,CAAC;AACH,CAAC"}