sensemaking 0.25.1 → 0.27.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.
Files changed (332) hide show
  1. package/README.md +48 -12
  2. package/dist/cjs/cli/index.d.cts +3 -3
  3. package/dist/cjs/cli/index.d.ts +3 -3
  4. package/dist/cjs/cli/index.js +3 -3
  5. package/dist/cjs/cli/index.js.map +1 -1
  6. package/dist/cjs/cli/path.js +5 -29
  7. package/dist/cjs/cli/path.js.map +1 -1
  8. package/dist/cjs/cli/peek.js +43 -2
  9. package/dist/cjs/cli/peek.js.map +1 -1
  10. package/dist/cjs/cli/related.js +4 -3
  11. package/dist/cjs/cli/related.js.map +1 -1
  12. package/dist/cjs/cli/search.js +38 -6
  13. package/dist/cjs/cli/search.js.map +1 -1
  14. package/dist/cjs/commands/index.d.cts +6 -3
  15. package/dist/cjs/commands/index.d.ts +6 -3
  16. package/dist/cjs/commands/index.js +4 -0
  17. package/dist/cjs/commands/index.js.map +1 -1
  18. package/dist/cjs/commands/map.d.cts +14 -5
  19. package/dist/cjs/commands/map.d.ts +14 -5
  20. package/dist/cjs/commands/map.js +42 -35
  21. package/dist/cjs/commands/map.js.map +1 -1
  22. package/dist/cjs/commands/path.d.cts +14 -0
  23. package/dist/cjs/commands/path.d.ts +14 -0
  24. package/dist/cjs/commands/path.js +209 -0
  25. package/dist/cjs/commands/path.js.map +1 -0
  26. package/dist/cjs/commands/peek.d.cts +25 -2
  27. package/dist/cjs/commands/peek.d.ts +25 -2
  28. package/dist/cjs/commands/peek.js +131 -50
  29. package/dist/cjs/commands/peek.js.map +1 -1
  30. package/dist/cjs/commands/related.d.cts +16 -3
  31. package/dist/cjs/commands/related.d.ts +16 -3
  32. package/dist/cjs/commands/related.js +131 -98
  33. package/dist/cjs/commands/related.js.map +1 -1
  34. package/dist/cjs/commands/scope.d.cts +1 -0
  35. package/dist/cjs/commands/scope.d.ts +1 -0
  36. package/dist/cjs/commands/scope.js +149 -0
  37. package/dist/cjs/commands/scope.js.map +1 -1
  38. package/dist/cjs/commands/search.d.cts +30 -3
  39. package/dist/cjs/commands/search.d.ts +30 -3
  40. package/dist/cjs/commands/search.js +240 -73
  41. package/dist/cjs/commands/search.js.map +1 -1
  42. package/dist/cjs/commands/signals.d.cts +22 -7
  43. package/dist/cjs/commands/signals.d.ts +22 -7
  44. package/dist/cjs/commands/signals.js +77 -15
  45. package/dist/cjs/commands/signals.js.map +1 -1
  46. package/dist/cjs/commands/snapshot.d.cts +3 -0
  47. package/dist/cjs/commands/snapshot.d.ts +3 -0
  48. package/dist/cjs/commands/snapshot.js +180 -0
  49. package/dist/cjs/commands/snapshot.js.map +1 -0
  50. package/dist/cjs/config/load.js +6 -0
  51. package/dist/cjs/config/load.js.map +1 -1
  52. package/dist/cjs/embed/cohere.js +41 -16
  53. package/dist/cjs/embed/cohere.js.map +1 -1
  54. package/dist/cjs/embed/endpoint.d.cts +2 -0
  55. package/dist/cjs/embed/endpoint.d.ts +2 -0
  56. package/dist/cjs/embed/endpoint.js +30 -0
  57. package/dist/cjs/embed/endpoint.js.map +1 -0
  58. package/dist/cjs/embed/handoff.d.cts +7 -2
  59. package/dist/cjs/embed/handoff.d.ts +7 -2
  60. package/dist/cjs/embed/handoff.js +10 -0
  61. package/dist/cjs/embed/handoff.js.map +1 -1
  62. package/dist/cjs/embed/http.d.cts +18 -1
  63. package/dist/cjs/embed/http.d.ts +18 -1
  64. package/dist/cjs/embed/http.js +239 -40
  65. package/dist/cjs/embed/http.js.map +1 -1
  66. package/dist/cjs/embed/openai.js +39 -17
  67. package/dist/cjs/embed/openai.js.map +1 -1
  68. package/dist/cjs/embed/query.d.cts +9 -3
  69. package/dist/cjs/embed/query.d.ts +9 -3
  70. package/dist/cjs/embed/query.js +257 -90
  71. package/dist/cjs/embed/query.js.map +1 -1
  72. package/dist/cjs/embed/registry.d.cts +2 -2
  73. package/dist/cjs/embed/registry.d.ts +2 -2
  74. package/dist/cjs/embed/registry.js +36 -4
  75. package/dist/cjs/embed/registry.js.map +1 -1
  76. package/dist/cjs/embed/static.js +6 -2
  77. package/dist/cjs/embed/static.js.map +1 -1
  78. package/dist/cjs/embed/store.js +42 -77
  79. package/dist/cjs/embed/store.js.map +1 -1
  80. package/dist/cjs/embed/types.d.cts +5 -2
  81. package/dist/cjs/embed/types.d.ts +5 -2
  82. package/dist/cjs/embed/types.js.map +1 -1
  83. package/dist/cjs/features/embed.js +290 -43
  84. package/dist/cjs/features/embed.js.map +1 -1
  85. package/dist/cjs/graph/traverse.d.cts +2 -2
  86. package/dist/cjs/graph/traverse.d.ts +2 -2
  87. package/dist/cjs/graph/traverse.js +15 -5
  88. package/dist/cjs/graph/traverse.js.map +1 -1
  89. package/dist/cjs/index.d.cts +2 -2
  90. package/dist/cjs/index.d.ts +2 -2
  91. package/dist/cjs/index.js +6 -0
  92. package/dist/cjs/index.js.map +1 -1
  93. package/dist/cjs/output/output.d.cts +4 -36
  94. package/dist/cjs/output/output.d.ts +4 -36
  95. package/dist/cjs/output/output.js +1 -2
  96. package/dist/cjs/output/output.js.map +1 -1
  97. package/dist/cjs/scan/pool.d.cts +2 -1
  98. package/dist/cjs/scan/pool.d.ts +2 -1
  99. package/dist/cjs/scan/pool.js +116 -27
  100. package/dist/cjs/scan/pool.js.map +1 -1
  101. package/dist/cjs/scan/reparse.d.cts +1 -0
  102. package/dist/cjs/scan/reparse.d.ts +1 -0
  103. package/dist/cjs/scan/reparse.js +75 -21
  104. package/dist/cjs/scan/reparse.js.map +1 -1
  105. package/dist/cjs/store/builder.d.cts +11 -21
  106. package/dist/cjs/store/builder.d.ts +11 -21
  107. package/dist/cjs/store/builder.js +1077 -438
  108. package/dist/cjs/store/builder.js.map +1 -1
  109. package/dist/cjs/store/duckdb/connection.js +16 -2
  110. package/dist/cjs/store/duckdb/connection.js.map +1 -1
  111. package/dist/cjs/store/duckdb/open.d.cts +1 -1
  112. package/dist/cjs/store/duckdb/open.d.ts +1 -1
  113. package/dist/cjs/store/duckdb/open.js +73 -65
  114. package/dist/cjs/store/duckdb/open.js.map +1 -1
  115. package/dist/cjs/store/duckdb/reconcile.js +533 -15
  116. package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
  117. package/dist/cjs/store/embed-scope.js +19 -9
  118. package/dist/cjs/store/embed-scope.js.map +1 -1
  119. package/dist/cjs/store/index.d.cts +6 -0
  120. package/dist/cjs/store/index.d.ts +6 -0
  121. package/dist/cjs/store/index.js +8 -4
  122. package/dist/cjs/store/index.js.map +1 -1
  123. package/dist/cjs/store/open.d.cts +6 -1
  124. package/dist/cjs/store/open.d.ts +6 -1
  125. package/dist/cjs/store/open.js +230 -307
  126. package/dist/cjs/store/open.js.map +1 -1
  127. package/dist/cjs/store/readiness.d.cts +5 -0
  128. package/dist/cjs/store/readiness.d.ts +5 -0
  129. package/dist/cjs/store/readiness.js +39 -0
  130. package/dist/cjs/store/readiness.js.map +1 -0
  131. package/dist/cjs/store/reconcile.d.cts +26 -1
  132. package/dist/cjs/store/reconcile.d.ts +26 -1
  133. package/dist/cjs/store/reconcile.js +670 -576
  134. package/dist/cjs/store/reconcile.js.map +1 -1
  135. package/dist/cjs/store/signature.d.cts +1 -0
  136. package/dist/cjs/store/signature.d.ts +1 -0
  137. package/dist/cjs/store/signature.js +9 -0
  138. package/dist/cjs/store/signature.js.map +1 -1
  139. package/dist/cjs/store/sqlite/open.d.cts +1 -1
  140. package/dist/cjs/store/sqlite/open.d.ts +1 -1
  141. package/dist/cjs/store/sqlite/open.js +84 -90
  142. package/dist/cjs/store/sqlite/open.js.map +1 -1
  143. package/dist/cjs/store/sqlite/reconcile.js.map +1 -1
  144. package/dist/cjs/store/sqlite/store.js +63 -60
  145. package/dist/cjs/store/sqlite/store.js.map +1 -1
  146. package/dist/cjs/store/sqlite/vectors.d.cts +2 -2
  147. package/dist/cjs/store/sqlite/vectors.d.ts +2 -2
  148. package/dist/cjs/store/sqlite/vectors.js +8 -4
  149. package/dist/cjs/store/sqlite/vectors.js.map +1 -1
  150. package/dist/cjs/store/stages.js.map +1 -1
  151. package/dist/cjs/store/turso/connection.d.cts +1 -0
  152. package/dist/cjs/store/turso/connection.d.ts +1 -0
  153. package/dist/cjs/store/turso/connection.js +319 -94
  154. package/dist/cjs/store/turso/connection.js.map +1 -1
  155. package/dist/cjs/store/turso/open.d.cts +1 -1
  156. package/dist/cjs/store/turso/open.d.ts +1 -1
  157. package/dist/cjs/store/turso/open.js +70 -74
  158. package/dist/cjs/store/turso/open.js.map +1 -1
  159. package/dist/cjs/store/turso/store.js +25 -23
  160. package/dist/cjs/store/turso/store.js.map +1 -1
  161. package/dist/cjs/store/turso/vectors.d.cts +2 -2
  162. package/dist/cjs/store/turso/vectors.d.ts +2 -2
  163. package/dist/cjs/store/turso/vectors.js +26 -16
  164. package/dist/cjs/store/turso/vectors.js.map +1 -1
  165. package/dist/cjs/store/types.d.cts +4 -1
  166. package/dist/cjs/store/types.d.ts +4 -1
  167. package/dist/cjs/store/types.js.map +1 -1
  168. package/dist/cjs/store/vectors.d.cts +14 -1
  169. package/dist/cjs/store/vectors.d.ts +14 -1
  170. package/dist/cjs/store/vectors.js +61 -0
  171. package/dist/cjs/store/vectors.js.map +1 -1
  172. package/dist/cjs/watch.d.cts +6 -0
  173. package/dist/cjs/watch.d.ts +6 -0
  174. package/dist/cjs/watch.js +42 -10
  175. package/dist/cjs/watch.js.map +1 -1
  176. package/dist/cjs/workers/parse.d.cts +4 -3
  177. package/dist/cjs/workers/parse.d.ts +4 -3
  178. package/dist/cjs/workers/parse.js +19 -17
  179. package/dist/cjs/workers/parse.js.map +1 -1
  180. package/dist/esm/cli/index.d.ts +3 -3
  181. package/dist/esm/cli/index.js +3 -3
  182. package/dist/esm/cli/index.js.map +1 -1
  183. package/dist/esm/cli/path.js +4 -10
  184. package/dist/esm/cli/path.js.map +1 -1
  185. package/dist/esm/cli/peek.js +20 -2
  186. package/dist/esm/cli/peek.js.map +1 -1
  187. package/dist/esm/cli/related.js +5 -3
  188. package/dist/esm/cli/related.js.map +1 -1
  189. package/dist/esm/cli/search.js +12 -2
  190. package/dist/esm/cli/search.js.map +1 -1
  191. package/dist/esm/commands/index.d.ts +6 -3
  192. package/dist/esm/commands/index.js +1 -0
  193. package/dist/esm/commands/index.js.map +1 -1
  194. package/dist/esm/commands/map.d.ts +14 -5
  195. package/dist/esm/commands/map.js +2 -0
  196. package/dist/esm/commands/map.js.map +1 -1
  197. package/dist/esm/commands/path.d.ts +14 -0
  198. package/dist/esm/commands/path.js +33 -0
  199. package/dist/esm/commands/path.js.map +1 -0
  200. package/dist/esm/commands/peek.d.ts +25 -2
  201. package/dist/esm/commands/peek.js +59 -19
  202. package/dist/esm/commands/peek.js.map +1 -1
  203. package/dist/esm/commands/related.d.ts +16 -3
  204. package/dist/esm/commands/related.js +45 -28
  205. package/dist/esm/commands/related.js.map +1 -1
  206. package/dist/esm/commands/scope.d.ts +1 -0
  207. package/dist/esm/commands/scope.js +58 -0
  208. package/dist/esm/commands/scope.js.map +1 -1
  209. package/dist/esm/commands/search.d.ts +30 -3
  210. package/dist/esm/commands/search.js +95 -20
  211. package/dist/esm/commands/search.js.map +1 -1
  212. package/dist/esm/commands/signals.d.ts +22 -7
  213. package/dist/esm/commands/signals.js +74 -17
  214. package/dist/esm/commands/signals.js.map +1 -1
  215. package/dist/esm/commands/snapshot.d.ts +3 -0
  216. package/dist/esm/commands/snapshot.js +25 -0
  217. package/dist/esm/commands/snapshot.js.map +1 -0
  218. package/dist/esm/config/load.js +6 -0
  219. package/dist/esm/config/load.js.map +1 -1
  220. package/dist/esm/embed/cohere.js +35 -10
  221. package/dist/esm/embed/cohere.js.map +1 -1
  222. package/dist/esm/embed/endpoint.d.ts +2 -0
  223. package/dist/esm/embed/endpoint.js +11 -0
  224. package/dist/esm/embed/endpoint.js.map +1 -0
  225. package/dist/esm/embed/handoff.d.ts +7 -2
  226. package/dist/esm/embed/handoff.js +7 -0
  227. package/dist/esm/embed/handoff.js.map +1 -1
  228. package/dist/esm/embed/http.d.ts +18 -1
  229. package/dist/esm/embed/http.js +137 -17
  230. package/dist/esm/embed/http.js.map +1 -1
  231. package/dist/esm/embed/openai.js +34 -12
  232. package/dist/esm/embed/openai.js.map +1 -1
  233. package/dist/esm/embed/query.d.ts +9 -3
  234. package/dist/esm/embed/query.js +98 -26
  235. package/dist/esm/embed/query.js.map +1 -1
  236. package/dist/esm/embed/registry.d.ts +2 -2
  237. package/dist/esm/embed/registry.js +34 -5
  238. package/dist/esm/embed/registry.js.map +1 -1
  239. package/dist/esm/embed/static.js +10 -2
  240. package/dist/esm/embed/static.js.map +1 -1
  241. package/dist/esm/embed/store.js +30 -21
  242. package/dist/esm/embed/store.js.map +1 -1
  243. package/dist/esm/embed/types.d.ts +5 -2
  244. package/dist/esm/embed/types.js.map +1 -1
  245. package/dist/esm/features/embed.js +82 -21
  246. package/dist/esm/features/embed.js.map +1 -1
  247. package/dist/esm/graph/traverse.d.ts +2 -2
  248. package/dist/esm/graph/traverse.js +4 -2
  249. package/dist/esm/graph/traverse.js.map +1 -1
  250. package/dist/esm/index.d.ts +2 -2
  251. package/dist/esm/index.js +1 -1
  252. package/dist/esm/index.js.map +1 -1
  253. package/dist/esm/output/output.d.ts +4 -36
  254. package/dist/esm/output/output.js +1 -2
  255. package/dist/esm/output/output.js.map +1 -1
  256. package/dist/esm/scan/pool.d.ts +2 -1
  257. package/dist/esm/scan/pool.js +80 -23
  258. package/dist/esm/scan/pool.js.map +1 -1
  259. package/dist/esm/scan/reparse.d.ts +1 -0
  260. package/dist/esm/scan/reparse.js +40 -12
  261. package/dist/esm/scan/reparse.js.map +1 -1
  262. package/dist/esm/store/builder.d.ts +11 -21
  263. package/dist/esm/store/builder.js +337 -133
  264. package/dist/esm/store/builder.js.map +1 -1
  265. package/dist/esm/store/duckdb/connection.js +9 -1
  266. package/dist/esm/store/duckdb/connection.js.map +1 -1
  267. package/dist/esm/store/duckdb/open.d.ts +1 -1
  268. package/dist/esm/store/duckdb/open.js +13 -9
  269. package/dist/esm/store/duckdb/open.js.map +1 -1
  270. package/dist/esm/store/duckdb/reconcile.js +145 -10
  271. package/dist/esm/store/duckdb/reconcile.js.map +1 -1
  272. package/dist/esm/store/embed-scope.js +16 -6
  273. package/dist/esm/store/embed-scope.js.map +1 -1
  274. package/dist/esm/store/index.d.ts +6 -0
  275. package/dist/esm/store/index.js +10 -4
  276. package/dist/esm/store/index.js.map +1 -1
  277. package/dist/esm/store/open.d.ts +6 -1
  278. package/dist/esm/store/open.js +77 -87
  279. package/dist/esm/store/open.js.map +1 -1
  280. package/dist/esm/store/readiness.d.ts +5 -0
  281. package/dist/esm/store/readiness.js +11 -0
  282. package/dist/esm/store/readiness.js.map +1 -0
  283. package/dist/esm/store/reconcile.d.ts +26 -1
  284. package/dist/esm/store/reconcile.js +142 -120
  285. package/dist/esm/store/reconcile.js.map +1 -1
  286. package/dist/esm/store/signature.d.ts +1 -0
  287. package/dist/esm/store/signature.js +8 -0
  288. package/dist/esm/store/signature.js.map +1 -1
  289. package/dist/esm/store/sqlite/open.d.ts +1 -1
  290. package/dist/esm/store/sqlite/open.js +12 -12
  291. package/dist/esm/store/sqlite/open.js.map +1 -1
  292. package/dist/esm/store/sqlite/reconcile.js +2 -2
  293. package/dist/esm/store/sqlite/reconcile.js.map +1 -1
  294. package/dist/esm/store/sqlite/store.js +21 -18
  295. package/dist/esm/store/sqlite/store.js.map +1 -1
  296. package/dist/esm/store/sqlite/vectors.d.ts +2 -2
  297. package/dist/esm/store/sqlite/vectors.js +7 -5
  298. package/dist/esm/store/sqlite/vectors.js.map +1 -1
  299. package/dist/esm/store/stages.js.map +1 -1
  300. package/dist/esm/store/turso/connection.d.ts +1 -0
  301. package/dist/esm/store/turso/connection.js +97 -28
  302. package/dist/esm/store/turso/connection.js.map +1 -1
  303. package/dist/esm/store/turso/open.d.ts +1 -1
  304. package/dist/esm/store/turso/open.js +9 -8
  305. package/dist/esm/store/turso/open.js.map +1 -1
  306. package/dist/esm/store/turso/store.js +16 -14
  307. package/dist/esm/store/turso/store.js.map +1 -1
  308. package/dist/esm/store/turso/vectors.d.ts +2 -2
  309. package/dist/esm/store/turso/vectors.js +27 -17
  310. package/dist/esm/store/turso/vectors.js.map +1 -1
  311. package/dist/esm/store/types.d.ts +4 -1
  312. package/dist/esm/store/types.js.map +1 -1
  313. package/dist/esm/store/vectors.d.ts +14 -1
  314. package/dist/esm/store/vectors.js +55 -0
  315. package/dist/esm/store/vectors.js.map +1 -1
  316. package/dist/esm/watch.d.ts +6 -0
  317. package/dist/esm/watch.js +40 -14
  318. package/dist/esm/watch.js.map +1 -1
  319. package/dist/esm/workers/parse.d.ts +4 -3
  320. package/dist/esm/workers/parse.js +19 -17
  321. package/dist/esm/workers/parse.js.map +1 -1
  322. package/package.json +1 -1
  323. package/skills/sense/EXAMPLES.md +3 -3
  324. package/skills/sense/SKILL.md +11 -3
  325. package/skills/sense/references/search.md +17 -1
  326. package/skills/sense/references/sql.md +1 -1
  327. package/skills/sense/references/stores/duckdb.md +1 -1
  328. package/skills/sense/references/terminology.md +32 -0
  329. package/skills/sense-setup/SKILL.md +2 -2
  330. package/skills/sense-setup/references/embeddings.md +1 -1
  331. package/skills/sense-setup/references/store-benchmarks.md +5 -5
  332. package/skills/sense-setup/references/stores/duckdb.md +1 -1
package/README.md CHANGED
@@ -36,15 +36,45 @@ pricing-decision.md …«pricing» decision … renewal «price»… match
36
36
 
37
37
  The row is illustrative. Actual paths, snippets and scores depend on the notes and configured search signals.
38
38
 
39
+ ## Library usage
40
+
41
+ Install the package locally in your Node.js project for imports; the global CLI installation above does not provide a project dependency:
42
+
43
+ ```bash
44
+ npm install sensemaking
45
+ ```
46
+
47
+ Start with an existing `your-notes/sense.config.json` pointing at your Markdown tree, created with `sense init` or written as shown under [Config](#config). `build` prepares every configured capability. Your embedding configuration governs model downloads and provider requests, including any service costs; see [Providers](#providers).
48
+
49
+ Save this as `search-notes.mjs` in your project and run `node search-notes.mjs`. Adjust the config path and search terms for your notes:
50
+
51
+ ```js
52
+ import { loadConfig, build, open, search } from 'sensemaking';
53
+
54
+ const config = loadConfig('./your-notes/sense.config.json');
55
+ await build(config);
56
+ const { store, cfg } = await open(config, { build: false });
57
+ try {
58
+ const results = await search(store, cfg, 'pricing', { k: 5 });
59
+ console.log(JSON.stringify(results, null, 2));
60
+ } finally {
61
+ await store.close();
62
+ }
63
+ ```
64
+
65
+ The handle uses the completed index prepared by `build`; the example awaits the search before closing it.
66
+
39
67
  ## What sense indexes
40
68
 
69
+ The [Sense terminology reference](skills/sense/references/terminology.md) defines notes, snippets, sections, chunks and links. A section is a span of the note; `peek` returns its description, not its prose. The ordered section descriptions form the outline.
70
+
41
71
  Every file becomes rows in these tables, plus whatever an enabled feature adds of its own:
42
72
 
43
73
  | table | holds | for |
44
74
  |---|---|---|
45
75
  | `frontmatter` | one column per key, plus `path`, `_mtime`, `_size`, `_rank`, `_parse_error` | filtering |
46
76
  | `content` | `title`, `summary`, `text`, `path` | text search and ranking |
47
- | `links` | `src`, `target` as written, `dst` resolved (`NULL` = dead link, but see the skill: a link to an attachment can never resolve) | graph |
77
+ | `links` | `src`, `target` as written, `dst` resolved (`NULL` = unresolved link, including attachments and targets outside the index) | graph |
48
78
  | `tags` | `path`, `tag`; frontmatter and inline `#tags` merged and deduplicated, nested tags stored full | tag filters |
49
79
  | `sections` | heading, `level`, `start_line`, `end_line`, `tokens` estimate | structure |
50
80
  | `preset_files` | `path`, `preset` | which presets cover which files; `sql --preset` binds these as a `scope` table to join, since `sql` is otherwise index-wide |
@@ -66,11 +96,11 @@ ORDER BY bm25(content, 10.0, 5.0, 1.0) LIMIT 10
66
96
  | command | does |
67
97
  |---|---|
68
98
  | `build [--force]` | incrementally update the derived index and prepare every configured search capability; `--force` recreates only `.sense/` |
69
- | `map` | doc count, frontmatter field coverage, top hubs by link rank, recent changes; hub/recent limits use bytewise path order on ties |
70
- | `search "<text>" [--preset name] [--include glob] [--exclude glob] [--no-exclude] [--where "<sql>"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n]` | words + links + vectors, one fused ranked list; `via` labels each row's evidence. `--k` bounds notes returned, `--snippet-char-limit` (default 80) each passage, `--snippet-count-limit` (default 1) passages per note |
71
- | `peek <path> [--preset name] [--where "<sql>"]` | frontmatter + heading outline (`[L143-162, ~380t]`) + links both ways (first 20 per list, each with its total) |
72
- | `path <a> <b> [--max-depth n] [--preset name] [--where "<sql>"]` | shortest link chain between two notes, or none within the bound |
73
- | `related <note> [--k n] [--preset name] [--where "<sql>"]` | notes similar in meaning that `<note>` does not yet link to; reads vectors, so semantic-search cost |
99
+ | `map [--preset name] [--include glob] [--exclude glob] [--no-exclude] [--where "<sql>"]` | doc count, frontmatter field coverage, top hubs by link rank, recent changes; hub/recent limits use bytewise path order on ties |
100
+ | `search "<text>" [--preset name] [--include glob] [--exclude glob] [--no-exclude] [--where "<sql>"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--explain]` | words + links + vectors, one fused ranked list; `via` labels each row's evidence. `--k` bounds notes returned, `--snippet-char-limit` (default 80) each passage, `--snippet-count-limit` (default 1) passages per note. `--explain` adds each participating signal's ranking contribution |
101
+ | `peek <path> [--preset name] [--include glob] [--exclude glob] [--no-exclude] [--where "<sql>"] [--section-count-limit n] [--link-count-limit n]` | frontmatter, section descriptions (`[L143-162, ~380t]`), outbound links, backlinks and unresolved links; `--section-count-limit` bounds section descriptions, and `--link-count-limit` bounds each link group independently (both default 20), with totals before truncation |
102
+ | `path <a> <b> [--max-depth n] [--preset name] [--include glob] [--exclude glob] [--no-exclude] [--where "<sql>"]` | shortest link chain between two notes, or none within the bound |
103
+ | `related <note> [--k n] [--preset name] [--include glob] [--exclude glob] [--no-exclude] [--where "<sql>"]` | notes similar in meaning that `<note>` does not yet link to; reads vectors, so semantic-search cost |
74
104
  | `sql "<statement>" [params...] [--preset name]` | ad-hoc SQL over all the tables; `?` binds positional args. Index-wide by default; `--preset` binds the preset's paths as a `scope` table the statement joins |
75
105
  | `<name> [params...]` | run a query saved in the config; `--list` names them |
76
106
  | `init` | write a starter `sense.config.json` |
@@ -78,16 +108,22 @@ ORDER BY bm25(content, 10.0, 5.0, 1.0) LIMIT 10
78
108
  | `download` | prefetch the embedding model named in the config; build, watch, or a default CLI vector query fetches it when needed otherwise |
79
109
  | `watch` | keep the index warm in the background (optional; see [watch coordination](https://github.com/kmalakoff/sensemaking/blob/master/DESIGN.md#watch-coordination)) |
80
110
 
111
+ Scope flags select from indexed notes; presets are not a security boundary. `peek` rejects an exact path outside the selected scope before trying a basename, resolves a basename only within that scope, and limits resolved outbound links and backlinks to it; unresolved targets remain as written. `path` resolves both endpoints across the indexed tree and applies scope to intermediate notes. `related` resolves its seed across the indexed tree and applies scope to result candidates.
112
+
81
113
  Query commands use the config's `"build": true` default to update the index first and prepare only what that operation needs. Core map, peek, path and SQL work do not prepare vectors. Set `"build": false` for a manual-build or watch workflow, or add `--no-build` for one query. These read the last completed generation without scanning source files or repairing missing readiness; they fail with a `sense build` instruction when the requested capability is not ready. This disables Sense index maintenance, not database access or arbitrary SQL.
82
114
 
83
- The completed generation stores the exact decoded source used for indexed snippets. A no-build query reads those stored sources and checks readiness for the capabilities it requests; it does not hydrate from newer live files. A default query incrementally scans the configured tree for the capabilities it needs; vector preparation is limited to its eligible scope. `sense build` prepares every configured capability, and `sense watch` keeps them prepared as changes arrive.
115
+ The completed generation stores the exact decoded source used for indexed snippets. A no-build query reads those stored sources and checks readiness for the capabilities it requests; it does not hydrate from newer live files. Public `search`, `mapTree`, `peek`, `findPath`, and `relatedNotes` calls assemble each result inside one committed database snapshot. Search completes provider and model preparation before its final snapshot and rejects an incomplete generation or one built for different feature settings instead of mixing generations. A default query incrementally scans the configured tree for the capabilities it needs; vector preparation is limited to its eligible scope. `sense build` prepares every configured capability, and `sense watch` keeps them prepared as changes arrive.
84
116
 
85
- Explicit `sense build` and `sense watch` prepare the index regardless of the config's `build` default. Watch builds before reporting ready, then processes edits; a no-build query can read the previous generation while an edit is being processed. Library callers choose preparation separately at `open`: `open(config)` prepares every configured capability, and `open(config, { build: false })` opens existing compatible state. The config's `build` setting controls CLI queries only. `build(config, { force: true })` recreates only the derived index. Public `search`, `mapTree`, and `peek` calls on one retained `Store` serialize with one another. Await those calls before running raw SQL, starting a transaction, or closing the handle.
117
+ Explicit `sense build` and `sense watch` prepare the index regardless of the config's `build` default. Watch builds before reporting ready, then processes edits; with SQLite, a no-build query can read the previous generation while an edit is being processed. DuckDB permits concurrent cross-process no-build readers only while every handle is observational and read-only; a build or watcher opens the cache read-write and excludes every other process. Turso no-build queries still require a query-capable, exclusive handle. Native contenders wait within a bounded lock budget, then raise `STORE_BUSY`, as described under Store choice. Library callers choose preparation separately at `open`: `open(config)` prepares every configured capability, and `open(config, { build: false })` opens existing compatible state. A build-enabled open repairs incomplete feature state and replaces an incompatible derived cache format; a no-build open reports the required build without rebuilding or repairing the Sense index. The config's `build` setting controls CLI queries only. `build(config, { force: true })` recreates only the derived index. Public `search`, `mapTree`, `peek`, `findPath`, and `relatedNotes` calls on one retained `Store` serialize with one another. Await those calls before running raw SQL, starting a transaction, or closing the handle.
86
118
 
87
- `search` runs one text through every engine its scope has: FTS5 word match (BM25-ranked, bare words AND-join, operators are yours on `sqlite`; on `duckdb` and `turso` the FTS5 operators are a named error, see Config), a personalized-PageRank walk over the link graph, and vector similarity, fused into one list. `via` labels each row's evidence (`match`, `link`, `vector`, combinations). Within the vector signal, candidates rank by the true cosine against the best-matching canonical chunk before `similarity` is rounded to three decimals for display; a zero-direction vector has similarity `0`, exact cosine ties use bytewise path order, and equal-scoring chunks choose the earliest authored chunk. The public search list ranks the combined word, link, and vector candidates by fused reciprocal-rank score. `lines` points at the section that earned the row (a direct read range). A `vector`-only row means the search words don't appear in that note; it showed up because the model judged it semantically related. `--preset` picks a named settings bundle from the config, `--where` filters on frontmatter. `--format json` on any reporting command returns structured output, and `--format csv` writes the row-returning commands one row per line, for redirecting a large result to a file instead of into context; `--version` and `--help` do what they say.
119
+ The root `search(store, config, terms, { signal })`, `open(config, { signal })`, and `build(config, { signal })` APIs accept an `AbortSignal`. Cancellation stops supported provider I/O and is checked between phases; synchronous native SQL or CPU work and resource cleanup finish before the promise settles. Cancellation checks preserve `signal.reason`, but a cleanup failure can surface instead or be combined with it in an `AggregateError`.
120
+
121
+ `search` runs one text through every engine its scope has: FTS5 word match (BM25-ranked, bare words AND-join, operators are yours on `sqlite`; on `duckdb` and `turso` the FTS5 operators are a named error, see Config), a personalized-PageRank walk over the link graph, and vector similarity, fused into one list. `via` labels each row's evidence (`match`, `link`, `vector`, combinations). Within the vector signal, candidates rank by the true cosine against the best-matching canonical chunk before `similarity` is rounded to three decimals for display; a zero-direction vector has similarity `0`, exact cosine ties use bytewise path order, and equal-scoring chunks choose the earliest authored chunk. The public search list ranks the combined word, link, and vector candidates by fused reciprocal-rank score. `lines` identifies a section or embedding chunk's line range in the indexed note. A `vector`-only row has vector evidence rather than a word match; it is not proof that the query words are absent. `--preset` picks a named settings bundle from the config, `--where` filters on frontmatter. `--format json` on any reporting command returns structured output, and `--format csv` writes the row-returning commands one row per line, for redirecting a large result to a file instead of into context; `--version` and `--help` do what they say.
88
122
 
89
123
  Search rows carry `snippets: string[]`. Each passage is generated around the matched words, marked with `«»`, and normally limited to 80 characters by default. A whole matched word is preserved, so a passage can exceed that limit when the word is longer. `--snippet-count-limit` returns more non-overlapping passages from a note, in document order. Link- and vector-only rows have `snippets: []`.
90
124
 
125
+ Use `search --explain --format json` to inspect the returned notes' word, link and vector contributions without changing their ranking. Each `explanation` entry contains the signal, its one-based rank, configured weight and unrounded contribution. This explains the returned candidates, not why an absent note was excluded. Library callers use `search(store, cfg, terms, { explain: true })`. For longer or shorter note outlines and link lists, use `peek(store, cfg, path, { sectionCountLimit: 40, linkCountLimit: 10 })` or the CLI's `--section-count-limit` and `--link-count-limit`. Each limit defaults to 20, must be a positive safe integer and does not change scope.
126
+
91
127
  Lexical words are case- and accent-insensitive. SQLite and DuckDB use their native English stem tokenizers; Turso's native Tantivy index has no stem tokenizer in the supported release, so it applies the shared Porter normalization to a derived field before native indexing. In every store, `run`, `running`, and `runs` match the same authored notes, while authored bytes are never rewritten. Quoted phrases require adjacent words, with punctuation treated as a separator, and punctuation-only input returns no lexical rows. SQLite's native caret and `NEAR(...)` expressions over unspaced text use original FTS5 tokens rather than sidecar substring semantics; use an ordinary quoted search when substring findability matters, at the cost of positional filtering.
92
128
 
93
129
  ## Config
@@ -126,11 +162,11 @@ Bare commands use the `default` preset; `--preset` names another; flags override
126
162
 
127
163
  ### Store choice
128
164
 
129
- Choose `sqlite` for the smallest setup, full FTS5 query syntax, and concurrent Sense commands. Choose `duckdb` when the cache should participate in DuckDB analytical work over large datasets or in local/cloud workflows. Choose `turso` for its embedded Rust engine and Tantivy text index. The DuckDB and Turso adapters are experimental, install their native package on first use, and currently serialize Sense commands that open the same cache.
165
+ Choose `sqlite` for the smallest setup, full FTS5 query syntax, and concurrent Sense commands. Choose `duckdb` when the cache should participate in DuckDB analytical work over large datasets or in local/cloud workflows. Choose `turso` for its embedded Rust engine and Tantivy text index. The DuckDB and Turso adapters are experimental and install their native package on first use.
130
166
 
131
- The commands and table names are shared. Raw SQL still follows the selected engine's dialect, and advanced FTS5 operators only work on `sqlite`. DuckDB and Turso hold their cache file for the life of a native handle, so Sense commands opening the same cache wait for the current command or watcher cycle to close; this is an adapter limitation, not a reader/writer coexistence guarantee.
167
+ The commands and table names are shared. Raw SQL still follows the selected engine's dialect, and advanced FTS5 operators only work on `sqlite`. Separate DuckDB processes may coexist only when every handle is observational and read-only. A DuckDB build-enabled open or watcher is read-write and excludes all other processes. Turso's observational path remains query-capable, so any Turso handle excludes other processes. Sense waits within a bounded lock budget for exclusive native access, then raises `STORE_BUSY`; neither adapter promises writer/reader coexistence. Public commands on one retained `Store` serialize separately, as described above.
132
168
 
133
- Vectors need a model. Naming a Hugging Face id in `embed.model` is consent to fetch it when `sense build`, `sense watch`, or a default CLI vector query first prepares vectors, with progress on stderr, into `~/.sense/models` (huggingface_hub's cache layout, one snapshot directory per resolved revision, shared by every tree, 124 MB, never in the package). `sense download` prefetches the same model ahead of time; it is idempotent and prints the resolved revision. `embed.model` is a Hugging Face id, or a path to a directory holding `model.safetensors` and `tokenizer.json`, which nothing fetches for you. A preset that asks for vectors when a local model path is missing those files is an error naming the fix, rather than a quieter result that would make the same search answer differently before and after; a preset whose `signals` exclude `vectors` never asks, so it is unaffected. An optional top-level `"embed": { "model", "provider", "url", "key" }` block points at any Model2Vec model, local path, or OpenAI-compatible endpoint (Ollama, LM Studio, hosted). Explicit builds and watch prepare all configured vectors. A default CLI vector query prepares only its eligible scope; `--no-build` requires that scope to be ready and never prepares it. Unrelated pending documents do not block either path.
169
+ Vectors need a model. Naming a Hugging Face id in `embed.model` is consent to fetch it when `sense build`, `sense watch`, or a default CLI vector query first prepares vectors, with progress on stderr, into `~/.sense/models` (huggingface_hub's cache layout, one snapshot directory per resolved revision, shared by every tree, 124 MB, never in the package). `sense download` prefetches the same model ahead of time; it is idempotent and prints the resolved revision. `embed.model` is a Hugging Face id, or a path to a directory holding `model.safetensors` and `tokenizer.json`, which nothing fetches for you. A preset that asks for vectors when a local model path is missing those files is an error naming the fix, rather than a quieter result that would make the same search answer differently before and after; a preset whose `signals` exclude `vectors` never asks, so it is unaffected. An optional top-level `"embed": { "model", "provider", "url", "key" }` block points at any Model2Vec model, local path, or OpenAI-compatible endpoint (Ollama, LM Studio, hosted). Changing the provider, model, or effective endpoint invalidates stale vectors; changing chunk size rebuilds the affected embedding rows. Explicit builds and watch prepare all configured vectors. A default CLI vector query prepares only its eligible scope; `--no-build` requires that scope to be ready and never prepares it. Unrelated pending documents do not block either path.
134
170
 
135
171
  Sense adds `has(field, value)` for array membership or string containment and `basename(path)` for path queries on every store. SQLite and DuckDB also provide `segment(terms)` for hand-written matching over text without word spaces. A frontmatter syntax error records `_parse_error` and leaves that file's discovered fields empty; the file's content still enters the index.
136
172
 
@@ -6,9 +6,9 @@ export declare const USAGE: {
6
6
  readonly status: "status [--format table|json] [--config path]";
7
7
  readonly download: "download [--config path]";
8
8
  readonly sql: "sql \"<statement>\" [params...] [--preset name] [--no-build] [--format table|json|csv] [--config path]";
9
- readonly search: "search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--no-build] [--format table|json|csv] [--config path]";
10
- readonly map: "map [--no-build] [--format table|json] [--config path]";
11
- readonly peek: "peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]";
9
+ readonly search: "search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--explain] [--no-build] [--format table|json|csv] [--config path]";
10
+ readonly map: "map [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]";
11
+ readonly peek: "peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--section-count-limit n] [--link-count-limit n] [--no-build] [--format table|json] [--config path]";
12
12
  readonly path: "path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--no-build] [--format table|json] [--config path]";
13
13
  readonly related: "related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--no-build] [--format table|json|csv] [--config path]";
14
14
  };
@@ -6,9 +6,9 @@ export declare const USAGE: {
6
6
  readonly status: "status [--format table|json] [--config path]";
7
7
  readonly download: "download [--config path]";
8
8
  readonly sql: "sql \"<statement>\" [params...] [--preset name] [--no-build] [--format table|json|csv] [--config path]";
9
- readonly search: "search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--no-build] [--format table|json|csv] [--config path]";
10
- readonly map: "map [--no-build] [--format table|json] [--config path]";
11
- readonly peek: "peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]";
9
+ readonly search: "search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--explain] [--no-build] [--format table|json|csv] [--config path]";
10
+ readonly map: "map [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]";
11
+ readonly peek: "peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--section-count-limit n] [--link-count-limit n] [--no-build] [--format table|json] [--config path]";
12
12
  readonly path: "path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--no-build] [--format table|json] [--config path]";
13
13
  readonly related: "related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--no-build] [--format table|json|csv] [--config path]";
14
14
  };
@@ -53,9 +53,9 @@ var USAGE = {
53
53
  status: 'status [--format table|json] [--config path]',
54
54
  download: 'download [--config path]',
55
55
  sql: 'sql "<statement>" [params...] [--preset name] [--no-build] [--format table|json|csv] [--config path]',
56
- search: 'search "<terms>" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--no-build] [--format table|json|csv] [--config path]',
57
- map: 'map [--no-build] [--format table|json] [--config path]',
58
- peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--no-build] [--format table|json] [--config path]',
56
+ search: 'search "<terms>" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--explain] [--no-build] [--format table|json|csv] [--config path]',
57
+ map: 'map [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--no-build] [--format table|json] [--config path]',
58
+ peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--section-count-limit n] [--link-count-limit n] [--no-build] [--format table|json] [--config path]',
59
59
  path: 'path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--max-depth n] [--no-build] [--format table|json] [--config path]',
60
60
  related: 'related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--k n] [--no-build] [--format table|json|csv] [--config path]'
61
61
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/index.ts"],"sourcesContent":["import type { Command } from './types.ts';\n\n// Each command's usage line, minus the leading \"usage: <name> \": shared by cli.ts's\n// usage() and the command's own parse() error/--help output so there is one copy, not two.\nexport const USAGE = {\n init: 'init [--model id-or-path] [--provider static|openai|cohere] [--url url]',\n build: 'build [--force] [--config path]',\n watch: 'watch [--force] [--config path]',\n status: 'status [--format table|json] [--config path]',\n download: 'download [--config path]',\n sql: 'sql \"<statement>\" [params...] [--preset name] [--no-build] [--format table|json|csv] [--config path]',\n search: 'search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--no-build] [--format table|json|csv] [--config path]',\n map: 'map [--no-build] [--format table|json] [--config path]',\n peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]',\n path: 'path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--no-build] [--format table|json] [--config path]',\n related: 'related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--no-build] [--format table|json|csv] [--config path]',\n} as const;\n\n// Lazy registry: a command's imports load only when it runs, so a heavy dependency in one\n// command never taxes the others (or --version/--help). These names are reserved from saved queries.\nexport const COMMANDS: Record<string, () => Promise<{ default: Command }>> = {\n init: () => import('./init.ts'),\n build: () => import('./build.ts'),\n watch: () => import('./watch.ts'),\n status: () => import('./status.ts'),\n download: () => import('./download.ts'),\n sql: () => import('./sql.ts'),\n search: () => import('./search.ts'),\n map: () => import('./map.ts'),\n peek: () => import('./peek.ts'),\n path: () => import('./path.ts'),\n related: () => import('./related.ts'),\n};\n\nexport type { Command, Ctx } from './types.ts';\n"],"names":["COMMANDS","USAGE","init","build","watch","status","download","sql","search","map","peek","path","related"],"mappings":";;;;;;;;;;;QAoBaA;eAAAA;;QAhBAC;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAN,IAAMA,QAAQ;IACnBC,MAAM;IACNC,OAAO;IACPC,OAAO;IACPC,QAAQ;IACRC,UAAU;IACVC,KAAK;IACLC,QAAQ;IACRC,KAAK;IACLC,MAAM;IACNC,MAAM;IACNC,SAAS;AACX;AAIO,IAAMZ,WAAgE;IAC3EE,MAAM,SAANA;eAAY;2DAAA,QAAO;;;IACnBC,OAAO,SAAPA;eAAa;2DAAA,QAAO;;;IACpBC,OAAO,SAAPA;eAAa;2DAAA,QAAO;;;IACpBC,QAAQ,SAARA;eAAc;2DAAA,QAAO;;;IACrBC,UAAU,SAAVA;eAAgB;2DAAA,QAAO;;;IACvBC,KAAK,SAALA;eAAW;2DAAA,QAAO;;;IAClBC,QAAQ,SAARA;eAAc;2DAAA,QAAO;;;IACrBC,KAAK,SAALA;eAAW;2DAAA,QAAO;;;IAClBC,MAAM,SAANA;eAAY;2DAAA,QAAO;;;IACnBC,MAAM,SAANA;eAAY;2DAAA,QAAO;;;IACnBC,SAAS,SAATA;eAAe;2DAAA,QAAO;;;AACxB"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/index.ts"],"sourcesContent":["import type { Command } from './types.ts';\n\n// Each command's usage line, minus the leading \"usage: <name> \": shared by cli.ts's\n// usage() and the command's own parse() error/--help output so there is one copy, not two.\nexport const USAGE = {\n init: 'init [--model id-or-path] [--provider static|openai|cohere] [--url url]',\n build: 'build [--force] [--config path]',\n watch: 'watch [--force] [--config path]',\n status: 'status [--format table|json] [--config path]',\n download: 'download [--config path]',\n sql: 'sql \"<statement>\" [params...] [--preset name] [--no-build] [--format table|json|csv] [--config path]',\n search: 'search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--explain] [--no-build] [--format table|json|csv] [--config path]',\n map: 'map [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]',\n peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--section-count-limit n] [--link-count-limit n] [--no-build] [--format table|json] [--config path]',\n path: 'path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--no-build] [--format table|json] [--config path]',\n related: 'related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--no-build] [--format table|json|csv] [--config path]',\n} as const;\n\n// Lazy registry: a command's imports load only when it runs, so a heavy dependency in one\n// command never taxes the others (or --version/--help). These names are reserved from saved queries.\nexport const COMMANDS: Record<string, () => Promise<{ default: Command }>> = {\n init: () => import('./init.ts'),\n build: () => import('./build.ts'),\n watch: () => import('./watch.ts'),\n status: () => import('./status.ts'),\n download: () => import('./download.ts'),\n sql: () => import('./sql.ts'),\n search: () => import('./search.ts'),\n map: () => import('./map.ts'),\n peek: () => import('./peek.ts'),\n path: () => import('./path.ts'),\n related: () => import('./related.ts'),\n};\n\nexport type { Command, Ctx } from './types.ts';\n"],"names":["COMMANDS","USAGE","init","build","watch","status","download","sql","search","map","peek","path","related"],"mappings":";;;;;;;;;;;QAoBaA;eAAAA;;QAhBAC;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAN,IAAMA,QAAQ;IACnBC,MAAM;IACNC,OAAO;IACPC,OAAO;IACPC,QAAQ;IACRC,UAAU;IACVC,KAAK;IACLC,QAAQ;IACRC,KAAK;IACLC,MAAM;IACNC,MAAM;IACNC,SAAS;AACX;AAIO,IAAMZ,WAAgE;IAC3EE,MAAM,SAANA;eAAY;2DAAA,QAAO;;;IACnBC,OAAO,SAAPA;eAAa;2DAAA,QAAO;;;IACpBC,OAAO,SAAPA;eAAa;2DAAA,QAAO;;;IACpBC,QAAQ,SAARA;eAAc;2DAAA,QAAO;;;IACrBC,UAAU,SAAVA;eAAgB;2DAAA,QAAO;;;IACvBC,KAAK,SAALA;eAAW;2DAAA,QAAO;;;IAClBC,QAAQ,SAARA;eAAc;2DAAA,QAAO;;;IACrBC,KAAK,SAALA;eAAW;2DAAA,QAAO;;;IAClBC,MAAM,SAANA;eAAY;2DAAA,QAAO;;;IACnBC,MAAM,SAANA;eAAY;2DAAA,QAAO;;;IACnBC,SAAS,SAATA;eAAe;2DAAA,QAAO;;;AACxB"}
@@ -8,9 +8,7 @@ Object.defineProperty(exports, "default", {
8
8
  return _default;
9
9
  }
10
10
  });
11
- var _peekts = require("../commands/peek.js");
12
- var _scopets = require("../commands/scope.js");
13
- var _traversets = require("../graph/traverse.js");
11
+ var _pathts = require("../commands/path.js");
14
12
  var _outputts = require("../output/output.js");
15
13
  var _indexts = require("./index.js");
16
14
  var _sharedts = require("./shared.js");
@@ -259,39 +257,17 @@ var pathCmd = function pathCmd(ctx) {
259
257
  ])
260
258
  }, function(store, cfg) {
261
259
  return _async_to_generator(function() {
262
- var paths, from, to, allowed, hops, rows;
260
+ var hops, rows;
263
261
  return _ts_generator(this, function(_state) {
264
262
  switch(_state.label){
265
263
  case 0:
266
264
  return [
267
265
  4,
268
- store.prepare('SELECT "path" FROM frontmatter')
266
+ (0, _pathts.findPath)(store, cfg, a, b, _object_spread_props(_object_spread({}, (0, _sharedts.scopeOf)(values)), {
267
+ maxDepth: maxDepth
268
+ }))
269
269
  ];
270
270
  case 1:
271
- return [
272
- 4,
273
- _state.sent().all()
274
- ];
275
- case 2:
276
- paths = _state.sent().map(function(r) {
277
- return r.path;
278
- });
279
- from = (0, _peekts.resolveNote)(paths, a);
280
- to = (0, _peekts.resolveNote)(paths, b);
281
- return [
282
- 4,
283
- (0, _scopets.scopedPaths)(store, cfg, (0, _sharedts.scopeOf)(values))
284
- ];
285
- case 3:
286
- allowed = _state.sent();
287
- return [
288
- 4,
289
- (0, _traversets.findPath)(store, from, to, {
290
- maxDepth: maxDepth,
291
- allowed: allowed
292
- })
293
- ];
294
- case 4:
295
271
  hops = _state.sent();
296
272
  if (format === 'json') {
297
273
  console.log(JSON.stringify(hops));
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/path.ts"],"sourcesContent":["import { resolveNote } from '../commands/peek.ts';\nimport { scopedPaths } from '../commands/scope.ts';\nimport { findPath } from '../graph/traverse.ts';\nimport type { Row } from '../output/output.ts';\nimport { printRows } from '../output/output.ts';\nimport type { BuildRequirement } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, NO_BUILD, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// --max-depth must be a positive integer, mirroring shared.ts's parseK.\nfunction parseMaxDepth(depth: string | undefined, usageError: (message: string) => never): number | undefined {\n if (depth === undefined) return undefined;\n const parsed = Number(depth);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--max-depth expects a positive integer, got \"${depth}\"`);\n return parsed;\n}\n\nconst pathCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.path}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG, 'max-depth': { type: 'string' } });\n const [a, b] = positionals;\n if (!a || !b) ctx.usageError(usage);\n const maxDepth = parseMaxDepth(values['max-depth'] as string | undefined, ctx.usageError);\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, { noBuild: values['no-build'] === true, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg) => {\n const paths = ((await (await store.prepare('SELECT \"path\" FROM frontmatter')).all()) as Array<{ path: string }>).map((r) => r.path);\n const from = resolveNote(paths, a);\n const to = resolveNote(paths, b);\n const allowed = await scopedPaths(store, cfg, scopeOf(values));\n const hops = await findPath(store, from, to, { maxDepth, allowed });\n\n if (format === 'json') {\n console.log(JSON.stringify(hops));\n return;\n }\n if (hops === null) {\n console.log(maxDepth ? `no path within ${maxDepth} hops` : 'no path');\n return;\n }\n const rows: Row[] = hops.map((p, step) => ({ step, path: p }));\n printRows(rows, format);\n });\n};\nexport default pathCmd;\n"],"names":["parseMaxDepth","depth","usageError","undefined","parsed","Number","isInteger","pathCmd","ctx","usage","USAGE","name","path","parse","argv","SCOPE","NO_BUILD","FORMAT","CONFIG","type","values","positionals","a","b","maxDepth","format","formatOf","withDb","config","noBuild","requirements","Set","store","cfg","paths","from","to","allowed","hops","rows","prepare","all","map","r","resolveNote","scopedPaths","scopeOf","findPath","console","log","JSON","stringify","p","step","printRows"],"mappings":";;;;+BA4CA;;;eAAA;;;sBA5C4B;uBACA;0BACH;wBAEC;uBAEJ;wBAC4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGlF,wEAAwE;AACxE,SAASA,cAAcC,KAAyB,EAAEC,UAAsC;IACtF,IAAID,UAAUE,WAAW,OAAOA;IAChC,IAAMC,SAASC,OAAOJ;IACtB,IAAI,CAACI,OAAOC,SAAS,CAACF,WAAWA,UAAU,GAAGF,WAAW,AAAC,gDAAqD,OAAND,OAAM;IAC/G,OAAOG;AACT;AAEA,IAAMG,UAAmB,iBAACC;IACxB,IAAMC,QAAQ,AAAC,UAAqBC,OAAZF,IAAIG,IAAI,EAAC,KAAc,OAAXD,cAAK,CAACE,IAAI;IAC9C,IAAgCC,SAAAA,IAAAA,eAAK,EAACL,IAAIM,IAAI,EAAEL,OAAO,wCAAKM,eAAK,EAAKC,kBAAQ,EAAKC,gBAAM,EAAKC,gBAAM;QAAE,aAAa;YAAEC,MAAM;QAAS;SAA5HC,SAAwBP,OAAxBO,QAAQC,cAAgBR,OAAhBQ;IAChB,IAAeA,gCAAAA,iBAARC,IAAQD,iBAALE,IAAKF;IACf,IAAI,CAACC,KAAK,CAACC,GAAGf,IAAIN,UAAU,CAACO;IAC7B,IAAMe,WAAWxB,cAAcoB,MAAM,CAAC,YAAY,EAAwBZ,IAAIN,UAAU;IACxF,IAAMuB,SAASC,IAAAA,kBAAQ,EAACN;IACxB,OAAOO,IAAAA,gBAAM,EAACnB,KAAKY,OAAOQ,MAAM,EAAwB;QAAEC,SAAST,MAAM,CAAC,WAAW,KAAK;QAAMU,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,SAAOC,OAAOC;;gBAC3JC,OACAC,MACAC,IACAC,SACAC,MAUAC;;;;wBAdiB;;4BAAMP,MAAMQ,OAAO,CAAC;;;wBAA3B;;4BAAO,cAAuDC,GAAG;;;wBAA3EP,QAAQ,AAAE,cAAiGQ,GAAG,CAAC,SAACC;mCAAMA,EAAE/B,IAAI;;wBAC5HuB,OAAOS,IAAAA,mBAAW,EAACV,OAAOZ;wBAC1Bc,KAAKQ,IAAAA,mBAAW,EAACV,OAAOX;wBACd;;4BAAMsB,IAAAA,oBAAW,EAACb,OAAOC,KAAKa,IAAAA,iBAAO,EAAC1B;;;wBAAhDiB,UAAU;wBACH;;4BAAMU,IAAAA,oBAAQ,EAACf,OAAOG,MAAMC,IAAI;gCAAEZ,UAAAA;gCAAUa,SAAAA;4BAAQ;;;wBAA3DC,OAAO;wBAEb,IAAIb,WAAW,QAAQ;4BACrBuB,QAAQC,GAAG,CAACC,KAAKC,SAAS,CAACb;4BAC3B;;;wBACF;wBACA,IAAIA,SAAS,MAAM;4BACjBU,QAAQC,GAAG,CAACzB,WAAW,AAAC,kBAA0B,OAATA,UAAS,WAAS;4BAC3D;;;wBACF;wBACMe,OAAcD,KAAKI,GAAG,CAAC,SAACU,GAAGC;mCAAU;gCAAEA,MAAAA;gCAAMzC,MAAMwC;4BAAE;;wBAC3DE,IAAAA,mBAAS,EAACf,MAAMd;;;;;;QAClB;;AACF;IACA,WAAelB"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/path.ts"],"sourcesContent":["import { findPath } from '../commands/path.ts';\nimport type { Row } from '../output/output.ts';\nimport { printRows } from '../output/output.ts';\nimport type { BuildRequirement } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, NO_BUILD, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// --max-depth must be a positive integer, mirroring shared.ts's parseK.\nfunction parseMaxDepth(depth: string | undefined, usageError: (message: string) => never): number | undefined {\n if (depth === undefined) return undefined;\n const parsed = Number(depth);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--max-depth expects a positive integer, got \"${depth}\"`);\n return parsed;\n}\n\nconst pathCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.path}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG, 'max-depth': { type: 'string' } });\n const [a, b] = positionals;\n if (!a || !b) ctx.usageError(usage);\n const maxDepth = parseMaxDepth(values['max-depth'] as string | undefined, ctx.usageError);\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, { noBuild: values['no-build'] === true, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg) => {\n const hops = await findPath(store, cfg, a, b, { ...scopeOf(values), maxDepth });\n\n if (format === 'json') {\n console.log(JSON.stringify(hops));\n return;\n }\n if (hops === null) {\n console.log(maxDepth ? `no path within ${maxDepth} hops` : 'no path');\n return;\n }\n const rows: Row[] = hops.map((p, step) => ({ step, path: p }));\n printRows(rows, format);\n });\n};\nexport default pathCmd;\n"],"names":["parseMaxDepth","depth","usageError","undefined","parsed","Number","isInteger","pathCmd","ctx","usage","USAGE","name","path","parse","argv","SCOPE","NO_BUILD","FORMAT","CONFIG","type","values","positionals","a","b","maxDepth","format","formatOf","withDb","config","noBuild","requirements","Set","store","cfg","hops","rows","findPath","scopeOf","console","log","JSON","stringify","map","p","step","printRows"],"mappings":";;;;+BAsCA;;;eAAA;;;sBAtCyB;wBAEC;uBAEJ;wBAC4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGlF,wEAAwE;AACxE,SAASA,cAAcC,KAAyB,EAAEC,UAAsC;IACtF,IAAID,UAAUE,WAAW,OAAOA;IAChC,IAAMC,SAASC,OAAOJ;IACtB,IAAI,CAACI,OAAOC,SAAS,CAACF,WAAWA,UAAU,GAAGF,WAAW,AAAC,gDAAqD,OAAND,OAAM;IAC/G,OAAOG;AACT;AAEA,IAAMG,UAAmB,iBAACC;IACxB,IAAMC,QAAQ,AAAC,UAAqBC,OAAZF,IAAIG,IAAI,EAAC,KAAc,OAAXD,cAAK,CAACE,IAAI;IAC9C,IAAgCC,SAAAA,IAAAA,eAAK,EAACL,IAAIM,IAAI,EAAEL,OAAO,wCAAKM,eAAK,EAAKC,kBAAQ,EAAKC,gBAAM,EAAKC,gBAAM;QAAE,aAAa;YAAEC,MAAM;QAAS;SAA5HC,SAAwBP,OAAxBO,QAAQC,cAAgBR,OAAhBQ;IAChB,IAAeA,gCAAAA,iBAARC,IAAQD,iBAALE,IAAKF;IACf,IAAI,CAACC,KAAK,CAACC,GAAGf,IAAIN,UAAU,CAACO;IAC7B,IAAMe,WAAWxB,cAAcoB,MAAM,CAAC,YAAY,EAAwBZ,IAAIN,UAAU;IACxF,IAAMuB,SAASC,IAAAA,kBAAQ,EAACN;IACxB,OAAOO,IAAAA,gBAAM,EAACnB,KAAKY,OAAOQ,MAAM,EAAwB;QAAEC,SAAST,MAAM,CAAC,WAAW,KAAK;QAAMU,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,SAAOC,OAAOC;;gBAC3JC,MAUAC;;;;wBAVO;;4BAAMC,IAAAA,gBAAQ,EAACJ,OAAOC,KAAKX,GAAGC,GAAG,wCAAKc,IAAAA,iBAAO,EAACjB;gCAASI,UAAAA;;;;wBAA9DU,OAAO;wBAEb,IAAIT,WAAW,QAAQ;4BACrBa,QAAQC,GAAG,CAACC,KAAKC,SAAS,CAACP;4BAC3B;;;wBACF;wBACA,IAAIA,SAAS,MAAM;4BACjBI,QAAQC,GAAG,CAACf,WAAW,AAAC,kBAA0B,OAATA,UAAS,WAAS;4BAC3D;;;wBACF;wBACMW,OAAcD,KAAKQ,GAAG,CAAC,SAACC,GAAGC;mCAAU;gCAAEA,MAAAA;gCAAMhC,MAAM+B;4BAAE;;wBAC3DE,IAAAA,mBAAS,EAACV,MAAMV;;;;;;QAClB;;AACF;IACA,WAAelB"}
@@ -99,6 +99,29 @@ function _object_spread(target) {
99
99
  }
100
100
  return target;
101
101
  }
102
+ function ownKeys(object, enumerableOnly) {
103
+ var keys = Object.keys(object);
104
+ if (Object.getOwnPropertySymbols) {
105
+ var symbols = Object.getOwnPropertySymbols(object);
106
+ if (enumerableOnly) {
107
+ symbols = symbols.filter(function(sym) {
108
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
109
+ });
110
+ }
111
+ keys.push.apply(keys, symbols);
112
+ }
113
+ return keys;
114
+ }
115
+ function _object_spread_props(target, source) {
116
+ source = source != null ? source : {};
117
+ if (Object.getOwnPropertyDescriptors) Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
118
+ else {
119
+ ownKeys(Object(source)).forEach(function(key) {
120
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
121
+ });
122
+ }
123
+ return target;
124
+ }
102
125
  function _sliced_to_array(arr, i) {
103
126
  return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
104
127
  }
@@ -209,11 +232,26 @@ function _unsupported_iterable_to_array(o, minLen) {
209
232
  if (n === "Map" || n === "Set") return Array.from(n);
210
233
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
211
234
  }
235
+ function parseCountLimit(name, value, usageError) {
236
+ if (value === undefined) return undefined;
237
+ var parsed = Number(value);
238
+ if (!Number.isSafeInteger(parsed) || parsed <= 0) usageError("--".concat(name, ' expects a positive safe integer, got "').concat(value, '"'));
239
+ return parsed;
240
+ }
212
241
  var peekCmd = function peekCmd(ctx) {
213
242
  var usage = "usage: ".concat(ctx.name, " ").concat(_indexts.USAGE.peek);
214
- var _parse = (0, _sharedts.parse)(ctx.argv, usage, _object_spread({}, _sharedts.SCOPE, _sharedts.NO_BUILD, _sharedts.FORMAT, _sharedts.CONFIG)), values = _parse.values, positionals = _parse.positionals;
243
+ var _parse = (0, _sharedts.parse)(ctx.argv, usage, _object_spread_props(_object_spread({}, _sharedts.SCOPE, _sharedts.NO_BUILD, _sharedts.FORMAT, _sharedts.CONFIG), {
244
+ 'section-count-limit': {
245
+ type: 'string'
246
+ },
247
+ 'link-count-limit': {
248
+ type: 'string'
249
+ }
250
+ })), values = _parse.values, positionals = _parse.positionals;
215
251
  var _positionals = _sliced_to_array(positionals, 1), pathArg = _positionals[0];
216
252
  if (!pathArg) ctx.usageError(usage);
253
+ var sectionCountLimit = parseCountLimit('section-count-limit', values['section-count-limit'], ctx.usageError);
254
+ var linkCountLimit = parseCountLimit('link-count-limit', values['link-count-limit'], ctx.usageError);
217
255
  var format = (0, _sharedts.formatOf)(values);
218
256
  return (0, _sharedts.withDb)(ctx, values.config, {
219
257
  noBuild: values['no-build'] === true,
@@ -226,7 +264,10 @@ var peekCmd = function peekCmd(ctx) {
226
264
  return _ts_generator(this, function(_state) {
227
265
  switch(_state.label){
228
266
  case 0:
229
- overrides = (0, _sharedts.scopeOf)(values);
267
+ overrides = _object_spread_props(_object_spread({}, (0, _sharedts.scopeOf)(values)), {
268
+ sectionCountLimit: sectionCountLimit,
269
+ linkCountLimit: linkCountLimit
270
+ });
230
271
  return [
231
272
  4,
232
273
  (0, _peekts.peek)(store, cfg, pathArg, overrides)
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/peek.ts"],"sourcesContent":["import { peek } from '../commands/peek.ts';\nimport { renderPeek, stringifyJson } from '../output/output.ts';\nimport type { BuildRequirement } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, NO_BUILD, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst peekCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.peek}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG });\n const [pathArg] = positionals;\n if (!pathArg) ctx.usageError(usage);\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, { noBuild: values['no-build'] === true, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg) => {\n const overrides = scopeOf(values);\n const result = await peek(store, cfg, pathArg, overrides);\n console.log(format === 'json' ? stringifyJson(result, 2) : renderPeek(result));\n });\n};\nexport default peekCmd;\n"],"names":["peekCmd","ctx","usage","USAGE","name","peek","parse","argv","SCOPE","NO_BUILD","FORMAT","CONFIG","values","positionals","pathArg","usageError","format","formatOf","withDb","config","noBuild","requirements","Set","store","cfg","overrides","result","scopeOf","console","log","stringifyJson","renderPeek"],"mappings":";;;;+BAmBA;;;eAAA;;;sBAnBqB;wBACqB;uBAEpB;wBAC4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGlF,IAAMA,UAAmB,iBAACC;IACxB,IAAMC,QAAQ,AAAC,UAAqBC,OAAZF,IAAIG,IAAI,EAAC,KAAc,OAAXD,cAAK,CAACE,IAAI;IAC9C,IAAgCC,SAAAA,IAAAA,eAAK,EAACL,IAAIM,IAAI,EAAEL,OAAO,mBAAKM,eAAK,EAAKC,kBAAQ,EAAKC,gBAAM,EAAKC,gBAAM,IAA5FC,SAAwBN,OAAxBM,QAAQC,cAAgBP,OAAhBO;IAChB,IAAkBA,gCAAAA,iBAAXC,UAAWD;IAClB,IAAI,CAACC,SAASb,IAAIc,UAAU,CAACb;IAC7B,IAAMc,SAASC,IAAAA,kBAAQ,EAACL;IACxB,OAAOM,IAAAA,gBAAM,EAACjB,KAAKW,OAAOO,MAAM,EAAwB;QAAEC,SAASR,MAAM,CAAC,WAAW,KAAK;QAAMS,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,SAAOC,OAAOC;;gBAC3JC,WACAC;;;;wBADAD,YAAYE,IAAAA,iBAAO,EAACf;wBACX;;4BAAMP,IAAAA,YAAI,EAACkB,OAAOC,KAAKV,SAASW;;;wBAAzCC,SAAS;wBACfE,QAAQC,GAAG,CAACb,WAAW,SAASc,IAAAA,uBAAa,EAACJ,QAAQ,KAAKK,IAAAA,oBAAU,EAACL;;;;;;QACxE;;AACF;IACA,WAAe1B"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/peek.ts"],"sourcesContent":["import { peek } from '../commands/peek.ts';\nimport { renderPeek, stringifyJson } from '../output/output.ts';\nimport type { BuildRequirement } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, NO_BUILD, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nfunction parseCountLimit(name: string, value: string | undefined, usageError: (message: string) => never): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n if (!Number.isSafeInteger(parsed) || parsed <= 0) usageError(`--${name} expects a positive safe integer, got \"${value}\"`);\n return parsed;\n}\n\nconst peekCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.peek}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG, 'section-count-limit': { type: 'string' }, 'link-count-limit': { type: 'string' } });\n const [pathArg] = positionals;\n if (!pathArg) ctx.usageError(usage);\n const sectionCountLimit = parseCountLimit('section-count-limit', values['section-count-limit'] as string | undefined, ctx.usageError);\n const linkCountLimit = parseCountLimit('link-count-limit', values['link-count-limit'] as string | undefined, ctx.usageError);\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, { noBuild: values['no-build'] === true, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg) => {\n const overrides = { ...scopeOf(values), sectionCountLimit, linkCountLimit };\n const result = await peek(store, cfg, pathArg, overrides);\n console.log(format === 'json' ? stringifyJson(result, 2) : renderPeek(result));\n });\n};\nexport default peekCmd;\n"],"names":["parseCountLimit","name","value","usageError","undefined","parsed","Number","isSafeInteger","peekCmd","ctx","usage","USAGE","peek","parse","argv","SCOPE","NO_BUILD","FORMAT","CONFIG","type","values","positionals","pathArg","sectionCountLimit","linkCountLimit","format","formatOf","withDb","config","noBuild","requirements","Set","store","cfg","overrides","result","scopeOf","console","log","stringifyJson","renderPeek"],"mappings":";;;;+BA4BA;;;eAAA;;;sBA5BqB;wBACqB;uBAEpB;wBAC4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGlF,SAASA,gBAAgBC,IAAY,EAAEC,KAAyB,EAAEC,UAAsC;IACtG,IAAID,UAAUE,WAAW,OAAOA;IAChC,IAAMC,SAASC,OAAOJ;IACtB,IAAI,CAACI,OAAOC,aAAa,CAACF,WAAWA,UAAU,GAAGF,WAAW,AAAC,KAAkDD,OAA9CD,MAAK,2CAA+C,OAANC,OAAM;IACtH,OAAOG;AACT;AAEA,IAAMG,UAAmB,iBAACC;IACxB,IAAMC,QAAQ,AAAC,UAAqBC,OAAZF,IAAIR,IAAI,EAAC,KAAc,OAAXU,cAAK,CAACC,IAAI;IAC9C,IAAgCC,SAAAA,IAAAA,eAAK,EAACJ,IAAIK,IAAI,EAAEJ,OAAO,wCAAKK,eAAK,EAAKC,kBAAQ,EAAKC,gBAAM,EAAKC,gBAAM;QAAE,uBAAuB;YAAEC,MAAM;QAAS;QAAG,oBAAoB;YAAEA,MAAM;QAAS;SAA9KC,SAAwBP,OAAxBO,QAAQC,cAAgBR,OAAhBQ;IAChB,IAAkBA,gCAAAA,iBAAXC,UAAWD;IAClB,IAAI,CAACC,SAASb,IAAIN,UAAU,CAACO;IAC7B,IAAMa,oBAAoBvB,gBAAgB,uBAAuBoB,MAAM,CAAC,sBAAsB,EAAwBX,IAAIN,UAAU;IACpI,IAAMqB,iBAAiBxB,gBAAgB,oBAAoBoB,MAAM,CAAC,mBAAmB,EAAwBX,IAAIN,UAAU;IAC3H,IAAMsB,SAASC,IAAAA,kBAAQ,EAACN;IACxB,OAAOO,IAAAA,gBAAM,EAAClB,KAAKW,OAAOQ,MAAM,EAAwB;QAAEC,SAAST,MAAM,CAAC,WAAW,KAAK;QAAMU,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,SAAOC,OAAOC;;gBAC3JC,WACAC;;;;wBADAD,YAAY,wCAAKE,IAAAA,iBAAO,EAAChB;4BAASG,mBAAAA;4BAAmBC,gBAAAA;;wBAC5C;;4BAAMZ,IAAAA,YAAI,EAACoB,OAAOC,KAAKX,SAASY;;;wBAAzCC,SAAS;wBACfE,QAAQC,GAAG,CAACb,WAAW,SAASc,IAAAA,uBAAa,EAACJ,QAAQ,KAAKK,IAAAA,oBAAU,EAACL;;;;;;QACxE;;AACF;IACA,WAAe3B"}
@@ -249,7 +249,6 @@ function _unsupported_iterable_to_array(o, minLen) {
249
249
  if (n === "Map" || n === "Set") return Array.from(n);
250
250
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
251
251
  }
252
- var RELATED_DEFAULT_K = 5;
253
252
  var relatedCmd = function relatedCmd(ctx) {
254
253
  var _parseK;
255
254
  var usage = "usage: ".concat(ctx.name, " ").concat(_indexts1.USAGE.related);
@@ -260,7 +259,7 @@ var relatedCmd = function relatedCmd(ctx) {
260
259
  })), values = _parse.values, positionals = _parse.positionals;
261
260
  var _positionals = _sliced_to_array(positionals, 1), pathArg = _positionals[0];
262
261
  if (!pathArg) ctx.usageError(usage);
263
- var k = (_parseK = (0, _sharedts.parseK)(values.k, ctx.usageError)) !== null && _parseK !== void 0 ? _parseK : RELATED_DEFAULT_K;
262
+ var k = (_parseK = (0, _sharedts.parseK)(values.k, ctx.usageError)) !== null && _parseK !== void 0 ? _parseK : _relatedts.RELATED_DEFAULT_K;
264
263
  var format = (0, _sharedts.rowFormatOf)(values);
265
264
  var noBuild = values['no-build'] === true;
266
265
  return (0, _sharedts.withDb)(ctx, values.config, {
@@ -303,7 +302,9 @@ var relatedCmd = function relatedCmd(ctx) {
303
302
  case 4:
304
303
  return [
305
304
  4,
306
- (0, _relatedts.relatedNotes)(store, cfg, pathArg, overrides, k)
305
+ (0, _relatedts.relatedNotes)(store, cfg, pathArg, _object_spread_props(_object_spread({}, overrides), {
306
+ k: k
307
+ }))
307
308
  ];
308
309
  case 5:
309
310
  _outputts.printRows.apply(void 0, [
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/related.ts"],"sourcesContent":["import { relatedNotes, resolveRelatedSeed } from '../commands/related.ts';\nimport { scopedPaths } from '../commands/scope.ts';\nimport { resolveSearch } from '../config/index.ts';\nimport type { Row } from '../output/output.ts';\nimport { printRows } from '../output/output.ts';\nimport { type BuildRequirement, prepareDocumentEmbeddings } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, NO_BUILD, parse, parseK, rowFormatOf, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst RELATED_DEFAULT_K = 5;\n\nconst relatedCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.related}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG, k: { type: 'string' } });\n const [pathArg] = positionals;\n if (!pathArg) ctx.usageError(usage);\n const k = parseK(values.k as string | undefined, ctx.usageError) ?? RELATED_DEFAULT_K;\n const format = rowFormatOf(values);\n const noBuild = values['no-build'] === true;\n return withDb(ctx, values.config as string | undefined, { noBuild, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg, build) => {\n const overrides = scopeOf(values);\n if (build && resolveSearch(cfg, overrides).signals.vectors !== undefined) {\n const path = await resolveRelatedSeed(store, pathArg);\n const allowed = await scopedPaths(store, cfg, overrides);\n await prepareDocumentEmbeddings(store, cfg, new Set([...allowed, path]));\n }\n printRows((await relatedNotes(store, cfg, pathArg, overrides, k)) as Row[], format);\n });\n};\nexport default relatedCmd;\n"],"names":["RELATED_DEFAULT_K","relatedCmd","ctx","parseK","usage","USAGE","name","related","parse","argv","SCOPE","NO_BUILD","FORMAT","CONFIG","k","type","values","positionals","pathArg","usageError","format","rowFormatOf","noBuild","withDb","config","requirements","Set","store","cfg","build","overrides","path","allowed","scopeOf","resolveSearch","signals","vectors","undefined","resolveRelatedSeed","scopedPaths","prepareDocumentEmbeddings","relatedNotes","printRows"],"mappings":";;;;+BA8BA;;;eAAA;;;yBA9BiD;uBACrB;uBACE;wBAEJ;sBACuC;wBAC3C;wBACuE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAG7F,IAAMA,oBAAoB;AAE1B,IAAMC,aAAsB,oBAACC;QAKjBC;IAJV,IAAMC,QAAQ,AAAC,UAAqBC,OAAZH,IAAII,IAAI,EAAC,KAAiB,OAAdD,eAAK,CAACE,OAAO;IACjD,IAAgCC,SAAAA,IAAAA,eAAK,EAACN,IAAIO,IAAI,EAAEL,OAAO,wCAAKM,eAAK,EAAKC,kBAAQ,EAAKC,gBAAM,EAAKC,gBAAM;QAAEC,GAAG;YAAEC,MAAM;QAAS;SAAlHC,SAAwBR,OAAxBQ,QAAQC,cAAgBT,OAAhBS;IAChB,IAAkBA,gCAAAA,iBAAXC,UAAWD;IAClB,IAAI,CAACC,SAAShB,IAAIiB,UAAU,CAACf;IAC7B,IAAMU,KAAIX,UAAAA,IAAAA,gBAAM,EAACa,OAAOF,CAAC,EAAwBZ,IAAIiB,UAAU,eAArDhB,qBAAAA,UAA0DH;IACpE,IAAMoB,SAASC,IAAAA,qBAAW,EAACL;IAC3B,IAAMM,UAAUN,MAAM,CAAC,WAAW,KAAK;IACvC,OAAOO,IAAAA,gBAAM,EAACrB,KAAKc,OAAOQ,MAAM,EAAwB;QAAEF,SAAAA;QAASG,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,SAAOC,OAAOC,KAAKC;;gBACnIC,WAEEC,MACAC;;;;wBAHFF,YAAYG,IAAAA,iBAAO,EAACjB;6BACtBa,CAAAA,SAASK,IAAAA,sBAAa,EAACN,KAAKE,WAAWK,OAAO,CAACC,OAAO,KAAKC,SAAQ,GAAnER;;;;wBACW;;4BAAMS,IAAAA,6BAAkB,EAACX,OAAOT;;;wBAAvCa,OAAO;wBACG;;4BAAMQ,IAAAA,oBAAW,EAACZ,OAAOC,KAAKE;;;wBAAxCE,UAAU;wBAChB;;4BAAMQ,IAAAA,iCAAyB,EAACb,OAAOC,KAAK,IAAIF,IAAI,AAAC,qBAAGM;gCAASD;;;;wBAAjE;;;wBAES;;4BAAMU,IAAAA,uBAAY,EAACd,OAAOC,KAAKV,SAASY,WAAWhB;;;wBAA9D4B,mBAAS;4BAAE;4BAAiEtB;;;;;;;QAC9E;;AACF;IACA,WAAenB"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/related.ts"],"sourcesContent":["import { RELATED_DEFAULT_K, relatedNotes, resolveRelatedSeed } from '../commands/related.ts';\nimport { scopedPaths } from '../commands/scope.ts';\nimport { resolveSearch } from '../config/index.ts';\nimport { printRows } from '../output/output.ts';\nimport { type BuildRequirement, prepareDocumentEmbeddings } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, NO_BUILD, parse, parseK, rowFormatOf, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst relatedCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.related}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG, k: { type: 'string' } });\n const [pathArg] = positionals;\n if (!pathArg) ctx.usageError(usage);\n const k = parseK(values.k as string | undefined, ctx.usageError) ?? RELATED_DEFAULT_K;\n const format = rowFormatOf(values);\n const noBuild = values['no-build'] === true;\n return withDb(ctx, values.config as string | undefined, { noBuild, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg, build) => {\n const overrides = scopeOf(values);\n if (build && resolveSearch(cfg, overrides).signals.vectors !== undefined) {\n const path = await resolveRelatedSeed(store, pathArg);\n const allowed = await scopedPaths(store, cfg, overrides);\n await prepareDocumentEmbeddings(store, cfg, new Set([...allowed, path]));\n }\n printRows(await relatedNotes(store, cfg, pathArg, { ...overrides, k }), format);\n });\n};\nexport default relatedCmd;\n"],"names":["relatedCmd","ctx","parseK","usage","USAGE","name","related","parse","argv","SCOPE","NO_BUILD","FORMAT","CONFIG","k","type","values","positionals","pathArg","usageError","RELATED_DEFAULT_K","format","rowFormatOf","noBuild","withDb","config","requirements","Set","store","cfg","build","overrides","path","allowed","scopeOf","resolveSearch","signals","vectors","undefined","resolveRelatedSeed","scopedPaths","prepareDocumentEmbeddings","relatedNotes","printRows"],"mappings":";;;;+BA2BA;;;eAAA;;;yBA3BoE;uBACxC;uBACE;wBACJ;sBACuC;wBAC3C;wBACuE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAG7F,IAAMA,aAAsB,oBAACC;QAKjBC;IAJV,IAAMC,QAAQ,AAAC,UAAqBC,OAAZH,IAAII,IAAI,EAAC,KAAiB,OAAdD,eAAK,CAACE,OAAO;IACjD,IAAgCC,SAAAA,IAAAA,eAAK,EAACN,IAAIO,IAAI,EAAEL,OAAO,wCAAKM,eAAK,EAAKC,kBAAQ,EAAKC,gBAAM,EAAKC,gBAAM;QAAEC,GAAG;YAAEC,MAAM;QAAS;SAAlHC,SAAwBR,OAAxBQ,QAAQC,cAAgBT,OAAhBS;IAChB,IAAkBA,gCAAAA,iBAAXC,UAAWD;IAClB,IAAI,CAACC,SAAShB,IAAIiB,UAAU,CAACf;IAC7B,IAAMU,KAAIX,UAAAA,IAAAA,gBAAM,EAACa,OAAOF,CAAC,EAAwBZ,IAAIiB,UAAU,eAArDhB,qBAAAA,UAA0DiB,4BAAiB;IACrF,IAAMC,SAASC,IAAAA,qBAAW,EAACN;IAC3B,IAAMO,UAAUP,MAAM,CAAC,WAAW,KAAK;IACvC,OAAOQ,IAAAA,gBAAM,EAACtB,KAAKc,OAAOS,MAAM,EAAwB;QAAEF,SAAAA;QAASG,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,SAAOC,OAAOC,KAAKC;;gBACnIC,WAEEC,MACAC;;;;wBAHFF,YAAYG,IAAAA,iBAAO,EAAClB;6BACtBc,CAAAA,SAASK,IAAAA,sBAAa,EAACN,KAAKE,WAAWK,OAAO,CAACC,OAAO,KAAKC,SAAQ,GAAnER;;;;wBACW;;4BAAMS,IAAAA,6BAAkB,EAACX,OAAOV;;;wBAAvCc,OAAO;wBACG;;4BAAMQ,IAAAA,oBAAW,EAACZ,OAAOC,KAAKE;;;wBAAxCE,UAAU;wBAChB;;4BAAMQ,IAAAA,iCAAyB,EAACb,OAAOC,KAAK,IAAIF,IAAI,AAAC,qBAAGM;gCAASD;;;;wBAAjE;;;wBAEQ;;4BAAMU,IAAAA,uBAAY,EAACd,OAAOC,KAAKX,SAAS,wCAAKa;gCAAWjB,GAAAA;;;;wBAAlE6B,mBAAS;4BAAC;4BAA8DtB;;;;;;;QAC1E;;AACF;IACA,WAAepB"}
@@ -102,6 +102,29 @@ function _object_spread(target) {
102
102
  }
103
103
  return target;
104
104
  }
105
+ function ownKeys(object, enumerableOnly) {
106
+ var keys = Object.keys(object);
107
+ if (Object.getOwnPropertySymbols) {
108
+ var symbols = Object.getOwnPropertySymbols(object);
109
+ if (enumerableOnly) {
110
+ symbols = symbols.filter(function(sym) {
111
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
112
+ });
113
+ }
114
+ keys.push.apply(keys, symbols);
115
+ }
116
+ return keys;
117
+ }
118
+ function _object_spread_props(target, source) {
119
+ source = source != null ? source : {};
120
+ if (Object.getOwnPropertyDescriptors) Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
121
+ else {
122
+ ownKeys(Object(source)).forEach(function(key) {
123
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
124
+ });
125
+ }
126
+ return target;
127
+ }
105
128
  function _sliced_to_array(arr, i) {
106
129
  return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
107
130
  }
@@ -219,7 +242,11 @@ var searchCmd = function searchCmd(ctx) {
219
242
  switch(_state.label){
220
243
  case 0:
221
244
  usage = "usage: ".concat(ctx.name, " ").concat(_indexts1.USAGE.search);
222
- _parse = (0, _sharedts.parse)(ctx.argv, usage, _object_spread({}, _sharedts.SEARCH_FLAGS, _sharedts.NO_BUILD, _sharedts.FORMAT, _sharedts.CONFIG)), values = _parse.values, positionals = _parse.positionals;
245
+ _parse = (0, _sharedts.parse)(ctx.argv, usage, _object_spread_props(_object_spread({}, _sharedts.SEARCH_FLAGS, _sharedts.NO_BUILD, _sharedts.FORMAT, _sharedts.CONFIG), {
246
+ explain: {
247
+ type: 'boolean'
248
+ }
249
+ })), values = _parse.values, positionals = _parse.positionals;
223
250
  _positionals = _sliced_to_array(positionals, 1), terms = _positionals[0];
224
251
  if (!terms) ctx.usageError(usage);
225
252
  k = (0, _sharedts.parseK)(values.k, ctx.usageError);
@@ -228,6 +255,7 @@ var searchCmd = function searchCmd(ctx) {
228
255
  format = (0, _sharedts.rowFormatOf)(values);
229
256
  overrides = _object_spread({
230
257
  k: k,
258
+ explain: values.explain === true,
231
259
  snippetCharLimit: snippetCharLimit,
232
260
  snippetCountLimit: snippetCountLimit
233
261
  }, (0, _sharedts.scopeOf)(values));
@@ -246,7 +274,7 @@ var searchCmd = function searchCmd(ctx) {
246
274
  }
247
275
  }, function(store, cfg, build) {
248
276
  return _async_to_generator(function() {
249
- var _tmp;
277
+ var _tmp, rows, rendered;
250
278
  return _ts_generator(this, function(_state) {
251
279
  switch(_state.label){
252
280
  case 0:
@@ -278,10 +306,14 @@ var searchCmd = function searchCmd(ctx) {
278
306
  (0, _searchts.search)(store, cfg, terms, overrides)
279
307
  ];
280
308
  case 4:
281
- _outputts.printRows.apply(void 0, [
282
- _state.sent(),
283
- format
284
- ]);
309
+ rows = _state.sent();
310
+ // Table cells use the shared renderer's width clipping; JSON retains the complete explanation.
311
+ rendered = overrides.explain && format !== 'json' ? rows.map(function(row) {
312
+ return _object_spread_props(_object_spread({}, row), {
313
+ explanation: JSON.stringify(row.explanation)
314
+ });
315
+ }) : rows;
316
+ (0, _outputts.printRows)(rendered, format);
285
317
  return [
286
318
  2
287
319
  ];
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/search.ts"],"sourcesContent":["import { scopedPaths } from '../commands/scope.ts';\nimport { search } from '../commands/search.ts';\nimport { resolveSearch } from '../config/index.ts';\nimport { printRows } from '../output/output.ts';\nimport { type BuildRequirement, prepareDocumentEmbeddings } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, NO_BUILD, parse, parseK, parseSnippetCharLimit, parseSnippetCountLimit, rowFormatOf, SEARCH_FLAGS, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst searchCmd: Command = async (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.search}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SEARCH_FLAGS, ...NO_BUILD, ...FORMAT, ...CONFIG });\n const [terms] = positionals;\n if (!terms) ctx.usageError(usage);\n const k = parseK(values.k as string | undefined, ctx.usageError);\n const snippetCharLimit = parseSnippetCharLimit(values['snippet-char-limit'] as string | undefined, ctx.usageError);\n const snippetCountLimit = parseSnippetCountLimit(values['snippet-count-limit'] as string | undefined, ctx.usageError);\n const format = rowFormatOf(values);\n const overrides = { k, snippetCharLimit, snippetCountLimit, ...scopeOf(values) };\n const noBuild = values['no-build'] === true;\n await withDb(\n ctx,\n values.config as string | undefined,\n {\n noBuild,\n requirements: (cfg) => {\n const signals = resolveSearch(cfg, overrides).signals;\n const requirements = new Set<BuildRequirement>(['core']);\n if (signals.words !== undefined) requirements.add('lexical');\n return requirements;\n },\n },\n async (store, cfg, build) => {\n if (build && resolveSearch(cfg, overrides).signals.vectors !== undefined) {\n await prepareDocumentEmbeddings(store, cfg, await scopedPaths(store, cfg, overrides));\n }\n printRows(await search(store, cfg, terms, overrides), format);\n }\n );\n};\nexport default searchCmd;\n"],"names":["searchCmd","ctx","usage","parse","values","positionals","terms","k","snippetCharLimit","snippetCountLimit","format","overrides","noBuild","USAGE","name","search","argv","SEARCH_FLAGS","NO_BUILD","FORMAT","CONFIG","usageError","parseK","parseSnippetCharLimit","parseSnippetCountLimit","rowFormatOf","scopeOf","withDb","config","requirements","cfg","signals","resolveSearch","Set","words","undefined","add","store","build","vectors","scopedPaths","prepareDocumentEmbeddings","printRows"],"mappings":";;;;+BAwCA;;;eAAA;;;uBAxC4B;wBACL;uBACO;wBACJ;sBACuC;wBAC3C;wBAC6H;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGnJ,IAAMA,YAAqB,mBAAOC;;YAC1BC,OAC0BC,QAAxBC,QAAQC,aACAA,cAATC,OAEDC,GACAC,kBACAC,mBACAC,QACAC,WACAC;;;;oBATAV,QAAQ,AAAC,UAAqBW,OAAZZ,IAAIa,IAAI,EAAC,KAAgB,OAAbD,eAAK,CAACE,MAAM;oBAChBZ,SAAAA,IAAAA,eAAK,EAACF,IAAIe,IAAI,EAAEd,OAAO,mBAAKe,sBAAY,EAAKC,kBAAQ,EAAKC,gBAAM,EAAKC,gBAAM,IAAnGhB,SAAwBD,OAAxBC,QAAQC,cAAgBF,OAAhBE;oBACAA,gCAAAA,iBAATC,QAASD;oBAChB,IAAI,CAACC,OAAOL,IAAIoB,UAAU,CAACnB;oBACrBK,IAAIe,IAAAA,gBAAM,EAAClB,OAAOG,CAAC,EAAwBN,IAAIoB,UAAU;oBACzDb,mBAAmBe,IAAAA,+BAAqB,EAACnB,MAAM,CAAC,qBAAqB,EAAwBH,IAAIoB,UAAU;oBAC3GZ,oBAAoBe,IAAAA,gCAAsB,EAACpB,MAAM,CAAC,sBAAsB,EAAwBH,IAAIoB,UAAU;oBAC9GX,SAASe,IAAAA,qBAAW,EAACrB;oBACrBO,YAAY;wBAAEJ,GAAAA;wBAAGC,kBAAAA;wBAAkBC,mBAAAA;uBAAsBiB,IAAAA,iBAAO,EAACtB;oBACjEQ,UAAUR,MAAM,CAAC,WAAW,KAAK;oBACvC;;wBAAMuB,IAAAA,gBAAM,EACV1B,KACAG,OAAOwB,MAAM,EACb;4BACEhB,SAAAA;4BACAiB,cAAc,SAAdA,aAAeC;gCACb,IAAMC,UAAUC,IAAAA,sBAAa,EAACF,KAAKnB,WAAWoB,OAAO;gCACrD,IAAMF,eAAe,IAAII,IAAsB;oCAAC;iCAAO;gCACvD,IAAIF,QAAQG,KAAK,KAAKC,WAAWN,aAAaO,GAAG,CAAC;gCAClD,OAAOP;4BACT;wBACF,GACA,SAAOQ,OAAOP,KAAKQ;;;;;;iDACbA,CAAAA,SAASN,IAAAA,sBAAa,EAACF,KAAKnB,WAAWoB,OAAO,CAACQ,OAAO,KAAKJ,SAAQ,GAAnEG;;;;;gDAC8BD;gDAAOP;;4CAAK;;gDAAMU,IAAAA,oBAAW,EAACH,OAAOP,KAAKnB;;;4CAA1E;;gDAAM8B,iCAAyB;oDAAa;;;;4CAA5C;;;4CAEQ;;gDAAM1B,IAAAA,gBAAM,EAACsB,OAAOP,KAAKxB,OAAOK;;;4CAA1C+B,mBAAS;gDAAC;gDAA4ChC;;;;;;;4BACxD;;;;oBAjBF;;;;;;IAmBF;;IACA,WAAeV"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/search.ts"],"sourcesContent":["import { scopedPaths } from '../commands/scope.ts';\nimport { search } from '../commands/search.ts';\nimport { resolveSearch } from '../config/index.ts';\nimport { printRows } from '../output/output.ts';\nimport { type BuildRequirement, prepareDocumentEmbeddings } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, NO_BUILD, parse, parseK, parseSnippetCharLimit, parseSnippetCountLimit, rowFormatOf, SEARCH_FLAGS, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst searchCmd: Command = async (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.search}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SEARCH_FLAGS, ...NO_BUILD, ...FORMAT, ...CONFIG, explain: { type: 'boolean' } });\n const [terms] = positionals;\n if (!terms) ctx.usageError(usage);\n const k = parseK(values.k as string | undefined, ctx.usageError);\n const snippetCharLimit = parseSnippetCharLimit(values['snippet-char-limit'] as string | undefined, ctx.usageError);\n const snippetCountLimit = parseSnippetCountLimit(values['snippet-count-limit'] as string | undefined, ctx.usageError);\n const format = rowFormatOf(values);\n const overrides = { k, explain: values.explain === true, snippetCharLimit, snippetCountLimit, ...scopeOf(values) };\n const noBuild = values['no-build'] === true;\n await withDb(\n ctx,\n values.config as string | undefined,\n {\n noBuild,\n requirements: (cfg) => {\n const signals = resolveSearch(cfg, overrides).signals;\n const requirements = new Set<BuildRequirement>(['core']);\n if (signals.words !== undefined) requirements.add('lexical');\n return requirements;\n },\n },\n async (store, cfg, build) => {\n if (build && resolveSearch(cfg, overrides).signals.vectors !== undefined) {\n await prepareDocumentEmbeddings(store, cfg, await scopedPaths(store, cfg, overrides));\n }\n const rows = await search(store, cfg, terms, overrides);\n // Table cells use the shared renderer's width clipping; JSON retains the complete explanation.\n const rendered = overrides.explain && format !== 'json' ? rows.map((row) => ({ ...row, explanation: JSON.stringify(row.explanation) })) : rows;\n printRows(rendered, format);\n }\n );\n};\nexport default searchCmd;\n"],"names":["searchCmd","ctx","usage","parse","values","positionals","terms","k","snippetCharLimit","snippetCountLimit","format","overrides","noBuild","USAGE","name","search","argv","SEARCH_FLAGS","NO_BUILD","FORMAT","CONFIG","explain","type","usageError","parseK","parseSnippetCharLimit","parseSnippetCountLimit","rowFormatOf","scopeOf","withDb","config","requirements","cfg","signals","resolveSearch","Set","words","undefined","add","store","build","rows","rendered","vectors","scopedPaths","prepareDocumentEmbeddings","map","row","explanation","JSON","stringify","printRows"],"mappings":";;;;+BA2CA;;;eAAA;;;uBA3C4B;wBACL;uBACO;wBACJ;sBACuC;wBAC3C;wBAC6H;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGnJ,IAAMA,YAAqB,mBAAOC;;YAC1BC,OAC0BC,QAAxBC,QAAQC,aACAA,cAATC,OAEDC,GACAC,kBACAC,mBACAC,QACAC,WACAC;;;;oBATAV,QAAQ,AAAC,UAAqBW,OAAZZ,IAAIa,IAAI,EAAC,KAAgB,OAAbD,eAAK,CAACE,MAAM;oBAChBZ,SAAAA,IAAAA,eAAK,EAACF,IAAIe,IAAI,EAAEd,OAAO,wCAAKe,sBAAY,EAAKC,kBAAQ,EAAKC,gBAAM,EAAKC,gBAAM;wBAAEC,SAAS;4BAAEC,MAAM;wBAAU;yBAAhIlB,SAAwBD,OAAxBC,QAAQC,cAAgBF,OAAhBE;oBACAA,gCAAAA,iBAATC,QAASD;oBAChB,IAAI,CAACC,OAAOL,IAAIsB,UAAU,CAACrB;oBACrBK,IAAIiB,IAAAA,gBAAM,EAACpB,OAAOG,CAAC,EAAwBN,IAAIsB,UAAU;oBACzDf,mBAAmBiB,IAAAA,+BAAqB,EAACrB,MAAM,CAAC,qBAAqB,EAAwBH,IAAIsB,UAAU;oBAC3Gd,oBAAoBiB,IAAAA,gCAAsB,EAACtB,MAAM,CAAC,sBAAsB,EAAwBH,IAAIsB,UAAU;oBAC9Gb,SAASiB,IAAAA,qBAAW,EAACvB;oBACrBO,YAAY;wBAAEJ,GAAAA;wBAAGc,SAASjB,OAAOiB,OAAO,KAAK;wBAAMb,kBAAAA;wBAAkBC,mBAAAA;uBAAsBmB,IAAAA,iBAAO,EAACxB;oBACnGQ,UAAUR,MAAM,CAAC,WAAW,KAAK;oBACvC;;wBAAMyB,IAAAA,gBAAM,EACV5B,KACAG,OAAO0B,MAAM,EACb;4BACElB,SAAAA;4BACAmB,cAAc,SAAdA,aAAeC;gCACb,IAAMC,UAAUC,IAAAA,sBAAa,EAACF,KAAKrB,WAAWsB,OAAO;gCACrD,IAAMF,eAAe,IAAII,IAAsB;oCAAC;iCAAO;gCACvD,IAAIF,QAAQG,KAAK,KAAKC,WAAWN,aAAaO,GAAG,CAAC;gCAClD,OAAOP;4BACT;wBACF,GACA,SAAOQ,OAAOP,KAAKQ;;0CAIXC,MAEAC;;;;iDALFF,CAAAA,SAASN,IAAAA,sBAAa,EAACF,KAAKrB,WAAWsB,OAAO,CAACU,OAAO,KAAKN,SAAQ,GAAnEG;;;;;gDAC8BD;gDAAOP;;4CAAK;;gDAAMY,IAAAA,oBAAW,EAACL,OAAOP,KAAKrB;;;4CAA1E;;gDAAMkC,iCAAyB;oDAAa;;;;4CAA5C;;;4CAEW;;gDAAM9B,IAAAA,gBAAM,EAACwB,OAAOP,KAAK1B,OAAOK;;;4CAAvC8B,OAAO;4CACb,+FAA+F;4CACzFC,WAAW/B,UAAUU,OAAO,IAAIX,WAAW,SAAS+B,KAAKK,GAAG,CAAC,SAACC;uDAAS,wCAAKA;oDAAKC,aAAaC,KAAKC,SAAS,CAACH,IAAIC,WAAW;;iDAAQP;4CAC1IU,IAAAA,mBAAS,EAACT,UAAUhC;;;;;;4BACtB;;;;oBApBF;;;;;;IAsBF;;IACA,WAAeV"}
@@ -1,10 +1,13 @@
1
- export type { TreeMap } from './map.js';
1
+ export type { TreeMap, TreeMapField, TreeMapHub, TreeMapRecent } from './map.js';
2
2
  export { mapTree } from './map.js';
3
- export type { Peek } from './peek.js';
3
+ export type { PathOptions } from './path.js';
4
+ export { findPath } from './path.js';
5
+ export type { Peek, PeekOptions, PeekSection } from './peek.js';
4
6
  export { peek, resolveNote } from './peek.js';
7
+ export type { RelatedOptions, RelatedResult } from './related.js';
5
8
  export { relatedNotes } from './related.js';
6
9
  export { scopedPaths } from './scope.js';
7
- export type { SearchOptions } from './search.js';
10
+ export type { SearchOptions, SearchResult, SearchResultVia, SearchSignalContribution } from './search.js';
8
11
  export { search } from './search.js';
9
12
  export type { PresetCoverage } from './status.js';
10
13
  export { presetCoverage } from './status.js';
@@ -1,10 +1,13 @@
1
- export type { TreeMap } from './map.js';
1
+ export type { TreeMap, TreeMapField, TreeMapHub, TreeMapRecent } from './map.js';
2
2
  export { mapTree } from './map.js';
3
- export type { Peek } from './peek.js';
3
+ export type { PathOptions } from './path.js';
4
+ export { findPath } from './path.js';
5
+ export type { Peek, PeekOptions, PeekSection } from './peek.js';
4
6
  export { peek, resolveNote } from './peek.js';
7
+ export type { RelatedOptions, RelatedResult } from './related.js';
5
8
  export { relatedNotes } from './related.js';
6
9
  export { scopedPaths } from './scope.js';
7
- export type { SearchOptions } from './search.js';
10
+ export type { SearchOptions, SearchResult, SearchResultVia, SearchSignalContribution } from './search.js';
8
11
  export { search } from './search.js';
9
12
  export type { PresetCoverage } from './status.js';
10
13
  export { presetCoverage } from './status.js';
@@ -11,6 +11,9 @@ function _export(target, all) {
11
11
  });
12
12
  }
13
13
  _export(exports, {
14
+ get findPath () {
15
+ return _pathts.findPath;
16
+ },
14
17
  get mapTree () {
15
18
  return _mapts.mapTree;
16
19
  },
@@ -34,6 +37,7 @@ _export(exports, {
34
37
  }
35
38
  });
36
39
  var _mapts = require("./map.js");
40
+ var _pathts = require("./path.js");
37
41
  var _peekts = require("./peek.js");
38
42
  var _relatedts = require("./related.js");
39
43
  var _scopets = require("./scope.js");
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/index.ts"],"sourcesContent":["// The three commands: mapTree (orient), search (locate), peek (structure).\n// Each returns data; cli.ts renders. All of them degrade when a feature is off.\n\nexport type { TreeMap } from './map.ts';\nexport { mapTree } from './map.ts';\nexport type { Peek } from './peek.ts';\nexport { peek, resolveNote } from './peek.ts';\nexport { relatedNotes } from './related.ts';\nexport { scopedPaths } from './scope.ts';\nexport type { SearchOptions } from './search.ts';\nexport { search } from './search.ts';\nexport type { PresetCoverage } from './status.ts';\nexport { presetCoverage } from './status.ts';\n"],"names":["mapTree","peek","presetCoverage","relatedNotes","resolveNote","scopedPaths","search"],"mappings":"AAAA,2EAA2E;AAC3E,gFAAgF;;;;;;;;;;;;QAGvEA;eAAAA,cAAO;;QAEPC;eAAAA,YAAI;;QAMJC;eAAAA,wBAAc;;QALdC;eAAAA,uBAAY;;QADNC;eAAAA,mBAAW;;QAEjBC;eAAAA,oBAAW;;QAEXC;eAAAA,gBAAM;;;qBANS;sBAEU;yBACL;uBACD;wBAEL;wBAEQ"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/index.ts"],"sourcesContent":["// The three commands: mapTree (orient), search (locate), peek (structure).\n// Each returns data; cli.ts renders. All of them degrade when a feature is off.\n\nexport type { TreeMap, TreeMapField, TreeMapHub, TreeMapRecent } from './map.ts';\nexport { mapTree } from './map.ts';\nexport type { PathOptions } from './path.ts';\nexport { findPath } from './path.ts';\nexport type { Peek, PeekOptions, PeekSection } from './peek.ts';\nexport { peek, resolveNote } from './peek.ts';\nexport type { RelatedOptions, RelatedResult } from './related.ts';\nexport { relatedNotes } from './related.ts';\nexport { scopedPaths } from './scope.ts';\nexport type { SearchOptions, SearchResult, SearchResultVia, SearchSignalContribution } from './search.ts';\nexport { search } from './search.ts';\nexport type { PresetCoverage } from './status.ts';\nexport { presetCoverage } from './status.ts';\n"],"names":["findPath","mapTree","peek","presetCoverage","relatedNotes","resolveNote","scopedPaths","search"],"mappings":"AAAA,2EAA2E;AAC3E,gFAAgF;;;;;;;;;;;;QAKvEA;eAAAA,gBAAQ;;QAFRC;eAAAA,cAAO;;QAIPC;eAAAA,YAAI;;QAOJC;eAAAA,wBAAc;;QALdC;eAAAA,uBAAY;;QAFNC;eAAAA,mBAAW;;QAGjBC;eAAAA,oBAAW;;QAEXC;eAAAA,gBAAM;;;qBATS;sBAEC;sBAES;yBAEL;uBACD;wBAEL;wBAEQ"}