mrplex 0.0.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.
Files changed (319) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +284 -0
  3. package/dist/cli/config.d.ts +28 -0
  4. package/dist/cli/config.js +48 -0
  5. package/dist/cli/config.js.map +1 -0
  6. package/dist/cli/exit-codes.d.ts +13 -0
  7. package/dist/cli/exit-codes.js +39 -0
  8. package/dist/cli/exit-codes.js.map +1 -0
  9. package/dist/cli/format.d.ts +22 -0
  10. package/dist/cli/format.js +148 -0
  11. package/dist/cli/format.js.map +1 -0
  12. package/dist/cli/main.d.ts +16 -0
  13. package/dist/cli/main.js +1518 -0
  14. package/dist/cli/main.js.map +1 -0
  15. package/dist/client/kernel-client.d.ts +97 -0
  16. package/dist/client/kernel-client.js +14 -0
  17. package/dist/client/kernel-client.js.map +1 -0
  18. package/dist/client/local.d.ts +26 -0
  19. package/dist/client/local.js +103 -0
  20. package/dist/client/local.js.map +1 -0
  21. package/dist/client/remote-mcp.d.ts +35 -0
  22. package/dist/client/remote-mcp.js +174 -0
  23. package/dist/client/remote-mcp.js.map +1 -0
  24. package/dist/embed/backfill.d.ts +24 -0
  25. package/dist/embed/backfill.js +33 -0
  26. package/dist/embed/backfill.js.map +1 -0
  27. package/dist/embed/chunker.d.ts +31 -0
  28. package/dist/embed/chunker.js +121 -0
  29. package/dist/embed/chunker.js.map +1 -0
  30. package/dist/embed/cmd-hook.d.ts +21 -0
  31. package/dist/embed/cmd-hook.js +100 -0
  32. package/dist/embed/cmd-hook.js.map +1 -0
  33. package/dist/embed/config.d.ts +61 -0
  34. package/dist/embed/config.js +109 -0
  35. package/dist/embed/config.js.map +1 -0
  36. package/dist/embed/hook.d.ts +38 -0
  37. package/dist/embed/hook.js +56 -0
  38. package/dist/embed/hook.js.map +1 -0
  39. package/dist/embed/http-hook.d.ts +13 -0
  40. package/dist/embed/http-hook.js +39 -0
  41. package/dist/embed/http-hook.js.map +1 -0
  42. package/dist/embed/worker.d.ts +62 -0
  43. package/dist/embed/worker.js +228 -0
  44. package/dist/embed/worker.js.map +1 -0
  45. package/dist/fixtures/hwe/characters/albion-ever.md +12 -0
  46. package/dist/fixtures/hwe/characters/cent.md +11 -0
  47. package/dist/fixtures/hwe/concepts/cent-demiurge-resonance.md +10 -0
  48. package/dist/fixtures/hwe/concepts/phase-looper.md +10 -0
  49. package/dist/fixtures/hwe/entities/demiurge.md +11 -0
  50. package/dist/fixtures/hwe/entities/monad.md +11 -0
  51. package/dist/fixtures/hwe/moc/globocorp-network.md +19 -0
  52. package/dist/fixtures/hwe/organizations/globocorp.md +11 -0
  53. package/dist/fixtures/hwe/readme.md +24 -0
  54. package/dist/fixtures/starship/crew/aria-okonkwo.md +14 -0
  55. package/dist/fixtures/starship/crew/bexley-orr.md +14 -0
  56. package/dist/fixtures/starship/crew/dax-thorne.md +14 -0
  57. package/dist/fixtures/starship/crew/isolde-marsh.md +16 -0
  58. package/dist/fixtures/starship/crew/kestrel-vance.md +15 -0
  59. package/dist/fixtures/starship/crew/quill-vasquez.md +14 -0
  60. package/dist/fixtures/starship/crew/soren-halloway.md +16 -0
  61. package/dist/fixtures/starship/encounters/the-drift-choir.md +14 -0
  62. package/dist/fixtures/starship/encounters/the-hollow-signal.md +16 -0
  63. package/dist/fixtures/starship/encounters/the-wandering-buoy.md +14 -0
  64. package/dist/fixtures/starship/equipment/coolant-loop-b.md +13 -0
  65. package/dist/fixtures/starship/equipment/emergency-ration-bars.md +12 -0
  66. package/dist/fixtures/starship/equipment/long-range-sensors.md +13 -0
  67. package/dist/fixtures/starship/equipment/plasma-manifold-3.md +15 -0
  68. package/dist/fixtures/starship/equipment/shuttle-corvid.md +13 -0
  69. package/dist/fixtures/starship/logs/marsh-4419-1.md +13 -0
  70. package/dist/fixtures/starship/logs/okonkwo-4415-1.md +13 -0
  71. package/dist/fixtures/starship/logs/orr-4413-1.md +13 -0
  72. package/dist/fixtures/starship/logs/orr-4420-1.md +12 -0
  73. package/dist/fixtures/starship/logs/thorne-4413-2.md +13 -0
  74. package/dist/fixtures/starship/logs/vance-4419-2.md +13 -0
  75. package/dist/fixtures/starship/misc/the-galley-ficus.md +11 -0
  76. package/dist/fixtures/starship/missions/the-cinder-run.md +17 -0
  77. package/dist/fixtures/starship/missions/the-drift-choir.md +17 -0
  78. package/dist/fixtures/starship/missions/the-hollow-signal.md +17 -0
  79. package/dist/fixtures/starship/missions/the-silent-beacon.md +17 -0
  80. package/dist/fixtures/starship/moc/crew.md +19 -0
  81. package/dist/fixtures/starship/moc/encounters.md +14 -0
  82. package/dist/fixtures/starship/moc/missions.md +15 -0
  83. package/dist/fixtures/starship/readme.md +60 -0
  84. package/dist/index.d.ts +1 -0
  85. package/dist/index.js +3 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/kernel/auth/glob.d.ts +46 -0
  88. package/dist/kernel/auth/glob.js +112 -0
  89. package/dist/kernel/auth/glob.js.map +1 -0
  90. package/dist/kernel/auth/scope.d.ts +53 -0
  91. package/dist/kernel/auth/scope.js +83 -0
  92. package/dist/kernel/auth/scope.js.map +1 -0
  93. package/dist/kernel/casefold.d.ts +37 -0
  94. package/dist/kernel/casefold.js +44 -0
  95. package/dist/kernel/casefold.js.map +1 -0
  96. package/dist/kernel/constants.d.ts +21 -0
  97. package/dist/kernel/constants.js +22 -0
  98. package/dist/kernel/constants.js.map +1 -0
  99. package/dist/kernel/context.d.ts +70 -0
  100. package/dist/kernel/context.js +114 -0
  101. package/dist/kernel/context.js.map +1 -0
  102. package/dist/kernel/deletion.d.ts +50 -0
  103. package/dist/kernel/deletion.js +83 -0
  104. package/dist/kernel/deletion.js.map +1 -0
  105. package/dist/kernel/diff.d.ts +36 -0
  106. package/dist/kernel/diff.js +61 -0
  107. package/dist/kernel/diff.js.map +1 -0
  108. package/dist/kernel/errors.d.ts +37 -0
  109. package/dist/kernel/errors.js +55 -0
  110. package/dist/kernel/errors.js.map +1 -0
  111. package/dist/kernel/frontmatter-input.d.ts +32 -0
  112. package/dist/kernel/frontmatter-input.js +85 -0
  113. package/dist/kernel/frontmatter-input.js.map +1 -0
  114. package/dist/kernel/graph.d.ts +34 -0
  115. package/dist/kernel/graph.js +559 -0
  116. package/dist/kernel/graph.js.map +1 -0
  117. package/dist/kernel/history.d.ts +74 -0
  118. package/dist/kernel/history.js +143 -0
  119. package/dist/kernel/history.js.map +1 -0
  120. package/dist/kernel/kernel.d.ts +162 -0
  121. package/dist/kernel/kernel.js +675 -0
  122. package/dist/kernel/kernel.js.map +1 -0
  123. package/dist/kernel/path-config.d.ts +101 -0
  124. package/dist/kernel/path-config.js +171 -0
  125. package/dist/kernel/path-config.js.map +1 -0
  126. package/dist/kernel/query/ast.d.ts +24 -0
  127. package/dist/kernel/query/ast.js +52 -0
  128. package/dist/kernel/query/ast.js.map +1 -0
  129. package/dist/kernel/query/cel-parse.d.ts +37 -0
  130. package/dist/kernel/query/cel-parse.js +88 -0
  131. package/dist/kernel/query/cel-parse.js.map +1 -0
  132. package/dist/kernel/query/degrees.d.ts +31 -0
  133. package/dist/kernel/query/degrees.js +135 -0
  134. package/dist/kernel/query/degrees.js.map +1 -0
  135. package/dist/kernel/query/graph-ast.d.ts +51 -0
  136. package/dist/kernel/query/graph-ast.js +139 -0
  137. package/dist/kernel/query/graph-ast.js.map +1 -0
  138. package/dist/kernel/query/query.d.ts +56 -0
  139. package/dist/kernel/query/query.js +276 -0
  140. package/dist/kernel/query/query.js.map +1 -0
  141. package/dist/kernel/validation.d.ts +64 -0
  142. package/dist/kernel/validation.js +183 -0
  143. package/dist/kernel/validation.js.map +1 -0
  144. package/dist/kernel/version-id.d.ts +10 -0
  145. package/dist/kernel/version-id.js +21 -0
  146. package/dist/kernel/version-id.js.map +1 -0
  147. package/dist/kernel/wire.d.ts +148 -0
  148. package/dist/kernel/wire.js +6 -0
  149. package/dist/kernel/wire.js.map +1 -0
  150. package/dist/links/backfill.d.ts +28 -0
  151. package/dist/links/backfill.js +33 -0
  152. package/dist/links/backfill.js.map +1 -0
  153. package/dist/links/extract.d.ts +29 -0
  154. package/dist/links/extract.js +233 -0
  155. package/dist/links/extract.js.map +1 -0
  156. package/dist/links/link-config.d.ts +70 -0
  157. package/dist/links/link-config.js +107 -0
  158. package/dist/links/link-config.js.map +1 -0
  159. package/dist/links/maintain.d.ts +37 -0
  160. package/dist/links/maintain.js +91 -0
  161. package/dist/links/maintain.js.map +1 -0
  162. package/dist/links/repair.d.ts +46 -0
  163. package/dist/links/repair.js +96 -0
  164. package/dist/links/repair.js.map +1 -0
  165. package/dist/links/resolve.d.ts +41 -0
  166. package/dist/links/resolve.js +121 -0
  167. package/dist/links/resolve.js.map +1 -0
  168. package/dist/links/stale.d.ts +32 -0
  169. package/dist/links/stale.js +73 -0
  170. package/dist/links/stale.js.map +1 -0
  171. package/dist/markdown/content-hash.d.ts +34 -0
  172. package/dist/markdown/content-hash.js +46 -0
  173. package/dist/markdown/content-hash.js.map +1 -0
  174. package/dist/markdown/frontmatter.d.ts +69 -0
  175. package/dist/markdown/frontmatter.js +147 -0
  176. package/dist/markdown/frontmatter.js.map +1 -0
  177. package/dist/markdown/hash-backfill.d.ts +22 -0
  178. package/dist/markdown/hash-backfill.js +43 -0
  179. package/dist/markdown/hash-backfill.js.map +1 -0
  180. package/dist/mcp/query-syntax.d.ts +20 -0
  181. package/dist/mcp/query-syntax.js +194 -0
  182. package/dist/mcp/query-syntax.js.map +1 -0
  183. package/dist/mcp/render.d.ts +31 -0
  184. package/dist/mcp/render.js +110 -0
  185. package/dist/mcp/render.js.map +1 -0
  186. package/dist/mcp/server.d.ts +60 -0
  187. package/dist/mcp/server.js +170 -0
  188. package/dist/mcp/server.js.map +1 -0
  189. package/dist/mcp/tools.d.ts +93 -0
  190. package/dist/mcp/tools.js +1218 -0
  191. package/dist/mcp/tools.js.map +1 -0
  192. package/dist/rest/conditional.d.ts +37 -0
  193. package/dist/rest/conditional.js +58 -0
  194. package/dist/rest/conditional.js.map +1 -0
  195. package/dist/rest/negotiate.d.ts +33 -0
  196. package/dist/rest/negotiate.js +54 -0
  197. package/dist/rest/negotiate.js.map +1 -0
  198. package/dist/rest/routes.d.ts +37 -0
  199. package/dist/rest/routes.js +744 -0
  200. package/dist/rest/routes.js.map +1 -0
  201. package/dist/seed/fixture-seed.d.ts +35 -0
  202. package/dist/seed/fixture-seed.js +75 -0
  203. package/dist/seed/fixture-seed.js.map +1 -0
  204. package/dist/seed/starship-config.d.ts +3 -0
  205. package/dist/seed/starship-config.js +5 -0
  206. package/dist/seed/starship-config.js.map +1 -0
  207. package/dist/server/headers.d.ts +36 -0
  208. package/dist/server/headers.js +30 -0
  209. package/dist/server/headers.js.map +1 -0
  210. package/dist/server/http-error.d.ts +53 -0
  211. package/dist/server/http-error.js +104 -0
  212. package/dist/server/http-error.js.map +1 -0
  213. package/dist/server/serve.d.ts +56 -0
  214. package/dist/server/serve.js +135 -0
  215. package/dist/server/serve.js.map +1 -0
  216. package/dist/shell/audit.d.ts +32 -0
  217. package/dist/shell/audit.js +28 -0
  218. package/dist/shell/audit.js.map +1 -0
  219. package/dist/shell/guard.d.ts +50 -0
  220. package/dist/shell/guard.js +176 -0
  221. package/dist/shell/guard.js.map +1 -0
  222. package/dist/shell/keys.d.ts +36 -0
  223. package/dist/shell/keys.js +64 -0
  224. package/dist/shell/keys.js.map +1 -0
  225. package/dist/shell/login.d.ts +56 -0
  226. package/dist/shell/login.js +130 -0
  227. package/dist/shell/login.js.map +1 -0
  228. package/dist/shell/oidc.d.ts +62 -0
  229. package/dist/shell/oidc.js +102 -0
  230. package/dist/shell/oidc.js.map +1 -0
  231. package/dist/shell/policy.d.ts +100 -0
  232. package/dist/shell/policy.js +232 -0
  233. package/dist/shell/policy.js.map +1 -0
  234. package/dist/shell/proxy-policy.d.ts +34 -0
  235. package/dist/shell/proxy-policy.js +120 -0
  236. package/dist/shell/proxy-policy.js.map +1 -0
  237. package/dist/shell/proxy.d.ts +47 -0
  238. package/dist/shell/proxy.js +253 -0
  239. package/dist/shell/proxy.js.map +1 -0
  240. package/dist/shell/serve.d.ts +86 -0
  241. package/dist/shell/serve.js +0 -0
  242. package/dist/shell/serve.js.map +1 -0
  243. package/dist/shell/stdio.d.ts +55 -0
  244. package/dist/shell/stdio.js +63 -0
  245. package/dist/shell/stdio.js.map +1 -0
  246. package/dist/storage/registry.d.ts +20 -0
  247. package/dist/storage/registry.js +38 -0
  248. package/dist/storage/registry.js.map +1 -0
  249. package/dist/storage/search-plan.d.ts +93 -0
  250. package/dist/storage/search-plan.js +15 -0
  251. package/dist/storage/search-plan.js.map +1 -0
  252. package/dist/storage/types.d.ts +448 -0
  253. package/dist/storage/types.js +14 -0
  254. package/dist/storage/types.js.map +1 -0
  255. package/dist/storage/versions-since.d.ts +72 -0
  256. package/dist/storage/versions-since.js +92 -0
  257. package/dist/storage/versions-since.js.map +1 -0
  258. package/dist/storage-postgres/adapter.d.ts +17 -0
  259. package/dist/storage-postgres/adapter.js +782 -0
  260. package/dist/storage-postgres/adapter.js.map +1 -0
  261. package/dist/storage-postgres/compile-postgres.d.ts +22 -0
  262. package/dist/storage-postgres/compile-postgres.js +830 -0
  263. package/dist/storage-postgres/compile-postgres.js.map +1 -0
  264. package/dist/storage-postgres/errors.d.ts +34 -0
  265. package/dist/storage-postgres/errors.js +50 -0
  266. package/dist/storage-postgres/errors.js.map +1 -0
  267. package/dist/storage-postgres/migrations/0001_init.sql +113 -0
  268. package/dist/storage-postgres/migrations/0002_content_hash.sql +7 -0
  269. package/dist/storage-postgres/migrations/index.d.ts +22 -0
  270. package/dist/storage-postgres/migrations/index.js +70 -0
  271. package/dist/storage-postgres/migrations/index.js.map +1 -0
  272. package/dist/storage-sqlite/adapter.d.ts +2 -0
  273. package/dist/storage-sqlite/adapter.js +688 -0
  274. package/dist/storage-sqlite/adapter.js.map +1 -0
  275. package/dist/storage-sqlite/compile-filter.d.ts +41 -0
  276. package/dist/storage-sqlite/compile-filter.js +881 -0
  277. package/dist/storage-sqlite/compile-filter.js.map +1 -0
  278. package/dist/storage-sqlite/compile-sqlite.d.ts +19 -0
  279. package/dist/storage-sqlite/compile-sqlite.js +176 -0
  280. package/dist/storage-sqlite/compile-sqlite.js.map +1 -0
  281. package/dist/storage-sqlite/migrations/0001_init.sql +123 -0
  282. package/dist/storage-sqlite/migrations/0002_content_hash.sql +7 -0
  283. package/dist/storage-sqlite/migrations/index.d.ts +6 -0
  284. package/dist/storage-sqlite/migrations/index.js +41 -0
  285. package/dist/storage-sqlite/migrations/index.js.map +1 -0
  286. package/dist/storage-sqlite/vec.d.ts +40 -0
  287. package/dist/storage-sqlite/vec.js +62 -0
  288. package/dist/storage-sqlite/vec.js.map +1 -0
  289. package/dist/sync/cursor.d.ts +36 -0
  290. package/dist/sync/cursor.js +66 -0
  291. package/dist/sync/cursor.js.map +1 -0
  292. package/dist/sync/daemon.d.ts +40 -0
  293. package/dist/sync/daemon.js +202 -0
  294. package/dist/sync/daemon.js.map +1 -0
  295. package/dist/sync/feed.d.ts +38 -0
  296. package/dist/sync/feed.js +125 -0
  297. package/dist/sync/feed.js.map +1 -0
  298. package/dist/sync/fs-store.d.ts +8 -0
  299. package/dist/sync/fs-store.js +76 -0
  300. package/dist/sync/fs-store.js.map +1 -0
  301. package/dist/sync/intrinsics.d.ts +52 -0
  302. package/dist/sync/intrinsics.js +76 -0
  303. package/dist/sync/intrinsics.js.map +1 -0
  304. package/dist/sync/paths.d.ts +38 -0
  305. package/dist/sync/paths.js +56 -0
  306. package/dist/sync/paths.js.map +1 -0
  307. package/dist/sync/push.d.ts +48 -0
  308. package/dist/sync/push.js +328 -0
  309. package/dist/sync/push.js.map +1 -0
  310. package/dist/sync/reconcile.d.ts +54 -0
  311. package/dist/sync/reconcile.js +252 -0
  312. package/dist/sync/reconcile.js.map +1 -0
  313. package/dist/sync/run.d.ts +27 -0
  314. package/dist/sync/run.js +46 -0
  315. package/dist/sync/run.js.map +1 -0
  316. package/dist/version.d.ts +2 -0
  317. package/dist/version.js +5 -0
  318. package/dist/version.js.map +1 -0
  319. package/package.json +80 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Brendan Baldwin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,284 @@
1
+ # mrplex
2
+
3
+ *Markdown Repos, plexed.*
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.
6
+
7
+ ## Install
8
+
9
+ Node ≥ 20.11:
10
+
11
+ ```bash
12
+ npm install -g mrplex
13
+ ```
14
+
15
+ Prefer not to install globally? `npx mrplex …` works the same way.
16
+
17
+ Point every command at a database and default repo once (the tour below uses `starship`):
18
+
19
+ ```bash
20
+ export MRPLEX_DATABASE=./demo.db
21
+ export MRPLEX_REPO=starship
22
+ ```
23
+
24
+ Or persist settings in `~/.config/mrplex/config.json`:
25
+
26
+ ```bash
27
+ mrplex config set-database ./demo.db
28
+ mrplex config set-repo starship
29
+ ```
30
+
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 …`.
34
+
35
+ ## A five-minute tour
36
+
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.
38
+
39
+ ### 1. Sync the sample corpus
40
+
41
+ Clone the repo (for the fixture files), install, and sync the folder into a fresh mrplex repo:
42
+
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
53
+ ```
54
+
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.
56
+
57
+ No bootstrap, no token — local mode is full-trust (whoever can run the binary owns the database).
58
+
59
+ ### 2. Query it like data
60
+
61
+ Frontmatter is queryable with [CEL](https://github.com/google/cel-spec) filters:
62
+
63
+ ```bash
64
+ # What's broken or offline right now?
65
+ mrplex query --filter 'status == "damaged" || status == "offline"'
66
+
67
+ # Who reports directly to the captain?
68
+ mrplex query --filter '$has_static("crew/kestrel-vance.md", "reports_to")'
69
+ ```
70
+
71
+ ```text
72
+ PATH STATUS
73
+ equipment/plasma-manifold-3.md damaged
74
+ equipment/shuttle-corvid.md offline
75
+
76
+
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:
84
+
85
+ ```bash
86
+ mrplex query --text 'manifold coolant'
87
+ mrplex query --filter 'type == "mission"' --text 'Halloway'
88
+ ```
89
+
90
+ ### 3. Follow the links as a graph
91
+
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:
93
+
94
+ ```bash
95
+ # Every mission indexed by the mission log MOC
96
+ mrplex query --filter '$in_static("moc/missions.md")'
97
+
98
+ # What touches the damaged plasma manifold? (maintainer field, body links, logs…)
99
+ mrplex query --filter '$has_static("equipment/plasma-manifold-3.md")'
100
+ ```
101
+
102
+ Explore *how* documents connect — neighborhood expansion from a root set:
103
+
104
+ ```bash
105
+ mrplex graph --roots missions/the-hollow-signal.md --degrees 2 --direction both --render summary
106
+ ```
107
+
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.
109
+
110
+ Mermaid for slides or docs:
111
+
112
+ ```bash
113
+ mrplex graph --roots crew/kestrel-vance.md --degrees 2 --direction out --render mermaid
114
+ ```
115
+
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:
119
+
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"
124
+
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
128
+ ```
129
+
130
+ History and unified diff between any two versions:
131
+
132
+ ```bash
133
+ mrplex docs history equipment/manifold-3.md
134
+ mrplex docs diff equipment/manifold-3.md --from v1 --to v2
135
+ ```
136
+
137
+ Deletion moves a document to a system-namespace path (`:deleted/…`); restore is a normal `docs put` back to user territory.
138
+
139
+ ### 5. Connect an agent
140
+
141
+ CLI, MCP, and REST are surfaces over the same model. Point Cursor (or any MCP client) at your local database:
142
+
143
+ ```json
144
+ {
145
+ "mcpServers": {
146
+ "mrplex": {
147
+ "command": "mrplex",
148
+ "args": ["mcp-stdio", "--unsafe", "--database", "./demo.db"],
149
+ "env": { "MRPLEX_REPO": "starship" }
150
+ }
151
+ }
152
+ }
153
+ ```
154
+
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.
156
+
157
+ Serve HTTP for remote clients or Streamable HTTP MCP:
158
+
159
+ ```bash
160
+ mrplex serve --unsafe --port 8321 &
161
+ mrplex --server http://127.0.0.1:8321 query --filter 'status == "missing"'
162
+ ```
163
+
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.
165
+
166
+ ## How it works
167
+
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
+ ```
231
+
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
+ ```
237
+
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).
239
+
240
+ ## Embeddings
241
+
242
+ mrplex never calls an embedding provider itself — wire one with `--embedder` (subprocess command or HTTP URL). For local CPU embeddings:
243
+
244
+ ```bash
245
+ npm install -g @mrplex/embedder
246
+ export MRPLEX_EMBEDDER=mrplex-embedder
247
+
248
+ mrplex serve --unsafe --embedder mrplex-embedder
249
+ mrplex embed backfill -r starship
250
+ mrplex query -r starship --semantic 'distress beacon star map'
251
+ ```
252
+
253
+ Resolution: **flag → `MRPLEX_EMBEDDER` → `mrplex config set-embedder` → unset**. See [packages/embedder/README.md](packages/embedder/README.md) for protocol details.
254
+
255
+ ## Development
256
+
257
+ ```bash
258
+ npm install
259
+ npm link
260
+ npm test
261
+ npm run typecheck
262
+ npm run lint
263
+ npm run build
264
+ ```
265
+
266
+ Seed the full dev fixture set (notes + starship):
267
+
268
+ ```bash
269
+ npm run seed -- --database ./mrplex.db
270
+ ```
271
+
272
+ 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`.
273
+
274
+ ### Postgres locally
275
+
276
+ ```bash
277
+ npm run pg:up
278
+ export MRPLEX_DATABASE=postgres://mrplex:mrplex@localhost:5432/mrplex
279
+ mrplex serve --unsafe
280
+ ```
281
+
282
+ ## License
283
+
284
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,28 @@
1
+ /**
2
+ * CLI config loading + saving — `~/.config/mrplex/config.json` (m1-plan §5
3
+ * said toml; we ship JSON in M1 for zero deps, and the format is trivial
4
+ * to migrate to toml later without breaking existing files).
5
+ *
6
+ * The config holds:
7
+ * • database — the URL used when --database is absent
8
+ * • token — the bearer token used when --token / MRPLEX_TOKEN absent
9
+ *
10
+ * File is chmod 600 on save (best-effort — Windows doesn't honor POSIX
11
+ * modes; the file will simply be user-readable there).
12
+ */
13
+ export type CliConfig = {
14
+ database?: string;
15
+ server?: string;
16
+ token?: string;
17
+ repo?: string;
18
+ author?: string;
19
+ /** Default --embedder (command or http(s):// URL). */
20
+ embedder?: string;
21
+ /** @deprecated Use `embedder`. */
22
+ embed_url?: string;
23
+ /** @deprecated Use `embedder`. */
24
+ embed_cmd?: string;
25
+ };
26
+ export declare function configPath(): string;
27
+ export declare function loadConfig(): CliConfig;
28
+ export declare function saveConfig(next: CliConfig): void;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * CLI config loading + saving — `~/.config/mrplex/config.json` (m1-plan §5
3
+ * said toml; we ship JSON in M1 for zero deps, and the format is trivial
4
+ * to migrate to toml later without breaking existing files).
5
+ *
6
+ * The config holds:
7
+ * • database — the URL used when --database is absent
8
+ * • token — the bearer token used when --token / MRPLEX_TOKEN absent
9
+ *
10
+ * File is chmod 600 on save (best-effort — Windows doesn't honor POSIX
11
+ * modes; the file will simply be user-readable there).
12
+ */
13
+ import { chmodSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
14
+ import { homedir } from "node:os";
15
+ import { dirname, join } from "node:path";
16
+ export function configPath() {
17
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
18
+ return join(xdgConfig, "mrplex", "config.json");
19
+ }
20
+ export function loadConfig() {
21
+ const path = configPath();
22
+ try {
23
+ const text = readFileSync(path, "utf8");
24
+ const parsed = JSON.parse(text);
25
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
26
+ return {};
27
+ }
28
+ return parsed;
29
+ }
30
+ catch (err) {
31
+ // File missing or malformed → empty config; the CLI treats this as normal.
32
+ if (err.code === "ENOENT")
33
+ return {};
34
+ return {};
35
+ }
36
+ }
37
+ export function saveConfig(next) {
38
+ const path = configPath();
39
+ mkdirSync(dirname(path), { recursive: true });
40
+ writeFileSync(path, `${JSON.stringify(next, null, 2)}\n`, { mode: 0o600 });
41
+ try {
42
+ chmodSync(path, 0o600);
43
+ }
44
+ catch {
45
+ // POSIX mode unsupported on this platform — best-effort.
46
+ }
47
+ }
48
+ //# sourceMappingURL=config.js.map
@@ -0,0 +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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * CLI exit-code families — design §7.3.
3
+ *
4
+ * 1 validation
5
+ * 2 concurrency / conflict (M1)
6
+ * 3 auth (M1)
7
+ * 4 not-found
8
+ * 10 network / transport (M3)
9
+ *
10
+ * Everything else exits 1.
11
+ */
12
+ import type { KernelErrorCode } from "../kernel/errors.js";
13
+ export declare function exitCodeForKernelError(code: KernelErrorCode): number;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * CLI exit-code families — design §7.3.
3
+ *
4
+ * 1 validation
5
+ * 2 concurrency / conflict (M1)
6
+ * 3 auth (M1)
7
+ * 4 not-found
8
+ * 10 network / transport (M3)
9
+ *
10
+ * Everything else exits 1.
11
+ */
12
+ export function exitCodeForKernelError(code) {
13
+ switch (code) {
14
+ case "repo_not_found":
15
+ case "doc_not_found":
16
+ case "version_not_found":
17
+ return 4;
18
+ case "stale_prev":
19
+ case "create_conflict":
20
+ case "path_taken":
21
+ case "slug_taken":
22
+ return 2;
23
+ case "forbidden":
24
+ return 3;
25
+ case "slug_invalid":
26
+ case "path_invalid":
27
+ case "frontmatter_invalid":
28
+ case "filter_invalid":
29
+ case "link_config_invalid":
30
+ case "version_not_in_document":
31
+ case "precondition_required":
32
+ case "payload_too_large":
33
+ case "semantic_unavailable":
34
+ return 1;
35
+ default:
36
+ return 1;
37
+ }
38
+ }
39
+ //# sourceMappingURL=exit-codes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exit-codes.js","sourceRoot":"","sources":["../../src/cli/exit-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,UAAU,sBAAsB,CAAC,IAAqB;IAC1D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,gBAAgB,CAAC;QACtB,KAAK,eAAe,CAAC;QACrB,KAAK,mBAAmB;YACtB,OAAO,CAAC,CAAC;QACX,KAAK,YAAY,CAAC;QAClB,KAAK,iBAAiB,CAAC;QACvB,KAAK,YAAY,CAAC;QAClB,KAAK,YAAY;YACf,OAAO,CAAC,CAAC;QACX,KAAK,WAAW;YACd,OAAO,CAAC,CAAC;QACX,KAAK,cAAc,CAAC;QACpB,KAAK,cAAc,CAAC;QACpB,KAAK,qBAAqB,CAAC;QAC3B,KAAK,gBAAgB,CAAC;QACtB,KAAK,qBAAqB,CAAC;QAC3B,KAAK,yBAAyB,CAAC;QAC/B,KAAK,uBAAuB,CAAC;QAC7B,KAAK,mBAAmB,CAAC;QACzB,KAAK,sBAAsB;YACzB,OAAO,CAAC,CAAC;QACX;YACE,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { GraphResult, QueryHit, Repo, Version } from "../kernel/wire.js";
2
+ /**
3
+ * Pretty-printers for CLI output. `--json` bypasses these entirely.
4
+ */
5
+ export declare function renderVersionAsMarkdown(v: Version): string;
6
+ export declare function renderReposTable(repos: Repo[]): string;
7
+ export declare function renderQueryTable(hits: QueryHit[]): string;
8
+ export declare function renderHistoryTable(versions: Version[]): string;
9
+ /**
10
+ * YAML dump of the structured payload — a better *reading* format than JSON
11
+ * for a human or LLM skimming a subgraph. Hand-rolled (the shape is flat and
12
+ * known) rather than pulling in a YAML serializer.
13
+ */
14
+ export declare function renderGraphYaml(result: GraphResult): string;
15
+ /**
16
+ * Mermaid flowchart — passthrough-renderable by most chat/markdown surfaces.
17
+ * The id-sanitization rule is load-bearing: generated ids (`d0`, `d1`, …) with
18
+ * the path only ever as a quoted label — a path as a mermaid id would break on
19
+ * slashes, dots, and colons. Roots (degrees 0) get a classDef; a trailing `%%`
20
+ * comment echoes truncation.
21
+ */
22
+ export declare function renderGraphMermaid(result: GraphResult): string;
@@ -0,0 +1,148 @@
1
+ import { join as joinFrontmatter } from "../markdown/frontmatter.js";
2
+ /**
3
+ * Pretty-printers for CLI output. `--json` bypasses these entirely.
4
+ */
5
+ export function renderVersionAsMarkdown(v) {
6
+ return joinFrontmatter({ frontmatter_raw: v.frontmatter_raw, body: v.body });
7
+ }
8
+ export function renderReposTable(repos) {
9
+ if (repos.length === 0)
10
+ return "(no repos)";
11
+ const rows = repos.map((r) => [r.repo, r.path_config ? "custom" : "default"]);
12
+ return renderTable(["REPO", "PATH CONFIG"], rows);
13
+ }
14
+ export function renderQueryTable(hits) {
15
+ if (hits.length === 0)
16
+ return "(no results)";
17
+ // Columns are the union of projected keys, in first-seen order across hits —
18
+ // `select` decides which fields are present, so the table follows suit.
19
+ const columns = [];
20
+ const seen = new Set();
21
+ for (const hit of hits) {
22
+ for (const key of Object.keys(hit)) {
23
+ if (!seen.has(key)) {
24
+ seen.add(key);
25
+ columns.push(key);
26
+ }
27
+ }
28
+ }
29
+ const rows = hits.map((hit) => columns.map((key) => renderCell(hit[key])));
30
+ return renderTable(columns, rows);
31
+ }
32
+ function renderCell(value) {
33
+ // A key absent from this hit (not selected, or missing frontmatter) is an
34
+ // empty cell; a present-but-null intrinsic (e.g. $next_version_id on the
35
+ // current version) renders as "null" to match the MCP text renderer.
36
+ if (value === undefined)
37
+ return "";
38
+ if (value === null)
39
+ return "null";
40
+ if (typeof value === "string")
41
+ return value;
42
+ return JSON.stringify(value);
43
+ }
44
+ export function renderHistoryTable(versions) {
45
+ if (versions.length === 0)
46
+ return "(no history)";
47
+ const rows = versions.map((v) => [
48
+ v.version_id,
49
+ v.created_at,
50
+ v.author,
51
+ v.next_version_id === null ? "current" : "",
52
+ ]);
53
+ return renderTable(["VERSION", "CREATED_AT", "AUTHOR", "STATE"], rows);
54
+ }
55
+ function renderTable(headers, rows) {
56
+ const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => (r[i] ?? "").length)));
57
+ const line = (cells) => cells
58
+ .map((c, i) => c.padEnd(widths[i] ?? 0))
59
+ .join(" ")
60
+ .trimEnd();
61
+ return [
62
+ line(headers),
63
+ line(headers.map((_, i) => "-".repeat(widths[i] ?? 0))),
64
+ ...rows.map(line),
65
+ ].join("\n");
66
+ }
67
+ // -----------------------------------------------------------------------------
68
+ // Graph renders (docs/graph-plan.md §2.3). CLI-only presentations of the
69
+ // structured GraphResult; the `summary` render is shared with the MCP text
70
+ // half (mcp/render.ts renderGraphSummary). These are pure functions of the
71
+ // result — presentation is a surface concern, never a call parameter.
72
+ // -----------------------------------------------------------------------------
73
+ /**
74
+ * YAML dump of the structured payload — a better *reading* format than JSON
75
+ * for a human or LLM skimming a subgraph. Hand-rolled (the shape is flat and
76
+ * known) rather than pulling in a YAML serializer.
77
+ */
78
+ export function renderGraphYaml(result) {
79
+ const lines = [];
80
+ lines.push("documents:");
81
+ if (result.documents.length === 0)
82
+ lines.push(" []");
83
+ for (const doc of result.documents) {
84
+ lines.push(` - $path: ${yamlScalar(doc.$path)}`);
85
+ lines.push(` $degrees: ${doc.$degrees}`);
86
+ lines.push(` $links: ${doc.$links}`);
87
+ lines.push(` $backlinks: ${doc.$backlinks}`);
88
+ for (const [key, value] of Object.entries(doc)) {
89
+ if (key === "$path" || key === "$degrees" || key === "$links" || key === "$backlinks") {
90
+ continue;
91
+ }
92
+ lines.push(` ${key}: ${yamlScalar(value)}`);
93
+ }
94
+ }
95
+ lines.push("links:");
96
+ if (result.links.length === 0)
97
+ lines.push(" []");
98
+ for (const l of result.links) {
99
+ lines.push(` - source: ${yamlScalar(l.source)}`);
100
+ lines.push(` target: ${yamlScalar(l.target)}`);
101
+ lines.push(` field: ${yamlScalar(l.field)}`);
102
+ }
103
+ lines.push(`frontier: [${result.frontier.map(yamlScalar).join(", ")}]`);
104
+ lines.push(`complete_degrees: ${result.complete_degrees}`);
105
+ lines.push(`truncated: ${result.truncated}`);
106
+ return lines.join("\n");
107
+ }
108
+ /** Quote a scalar for YAML when it isn't a safe bare token. */
109
+ function yamlScalar(v) {
110
+ if (typeof v === "number" || typeof v === "boolean")
111
+ return String(v);
112
+ const s = String(v);
113
+ if (s === "" || /[:#\-?\[\]{},&*!|>'"%@`]/.test(s) || /^\s|\s$/.test(s)) {
114
+ return JSON.stringify(s);
115
+ }
116
+ return s;
117
+ }
118
+ /**
119
+ * Mermaid flowchart — passthrough-renderable by most chat/markdown surfaces.
120
+ * The id-sanitization rule is load-bearing: generated ids (`d0`, `d1`, …) with
121
+ * the path only ever as a quoted label — a path as a mermaid id would break on
122
+ * slashes, dots, and colons. Roots (degrees 0) get a classDef; a trailing `%%`
123
+ * comment echoes truncation.
124
+ */
125
+ export function renderGraphMermaid(result) {
126
+ const lines = ["flowchart LR"];
127
+ const idByPath = new Map();
128
+ result.documents.forEach((doc, i) => {
129
+ const id = `d${i}`;
130
+ idByPath.set(doc.$path, id);
131
+ const rootClass = doc.$degrees === 0 ? ":::root" : "";
132
+ lines.push(` ${id}[${JSON.stringify(doc.$path)}]${rootClass}`);
133
+ });
134
+ for (const l of result.links) {
135
+ const s = idByPath.get(l.source);
136
+ const t = idByPath.get(l.target);
137
+ if (s === undefined || t === undefined)
138
+ continue;
139
+ lines.push(` ${s} -->|${JSON.stringify(l.field)}| ${t}`);
140
+ }
141
+ if (result.documents.some((d) => d.$degrees === 0)) {
142
+ lines.push(" classDef root stroke-width:3px");
143
+ }
144
+ const note = `complete through ${result.complete_degrees} degree${result.complete_degrees === 1 ? "" : "s"}${result.truncated ? " · truncated" : ""}`;
145
+ lines.push(` %% ${note}`);
146
+ return lines.join("\n");
147
+ }
148
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/cli/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * mrplex CLI — reads + writes + config + serve + remote mode.
4
+ *
5
+ * The CLI is a thin client over the MCP surface (§7.3). When `--server` is
6
+ * set, commands drive `tools/call` against `<server>/mcp`; otherwise the CLI
7
+ * opens the local SQLite file and calls the kernel in-process. The
8
+ * transport seam is `KernelClient` (`src/client/*`).
9
+ *
10
+ * No-auth (noauth plan): there is no bootstrap / tokens / users. Identity is
11
+ * one opaque `author` string (--author → MRPLEX_AUTHOR → config → "mrplex");
12
+ * `--scope <json>` narrows read visibility. In remote mode an optional --token
13
+ * is forwarded verbatim as a bearer for a shell fronting the server; mrplex
14
+ * itself ignores it. serve deliberately bypasses the seam — it IS the server.
15
+ */
16
+ export {};