sensemaking 0.27.0 → 0.28.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 (364) hide show
  1. package/bin/cli.js +16 -7
  2. package/dist/cjs/chunk/extract.js.map +1 -1
  3. package/dist/cjs/chunk/group.js.map +1 -1
  4. package/dist/cjs/chunk/index.js.map +1 -1
  5. package/dist/cjs/chunk/parse.js.map +1 -1
  6. package/dist/cjs/chunk/parser.js.map +1 -1
  7. package/dist/cjs/chunk/tokens.js.map +1 -1
  8. package/dist/cjs/chunk/version.js.map +1 -1
  9. package/dist/cjs/cli/build.js.map +1 -1
  10. package/dist/cjs/cli/constants.d.cts +2 -0
  11. package/dist/cjs/cli/constants.d.ts +2 -0
  12. package/dist/cjs/cli/constants.js +21 -0
  13. package/dist/cjs/cli/constants.js.map +1 -0
  14. package/dist/cjs/cli/download.js.map +1 -1
  15. package/dist/cjs/cli/index.js.map +1 -1
  16. package/dist/cjs/cli/init.js.map +1 -1
  17. package/dist/cjs/cli/map.js.map +1 -1
  18. package/dist/cjs/cli/named.js +2 -1
  19. package/dist/cjs/cli/named.js.map +1 -1
  20. package/dist/cjs/cli/path.js.map +1 -1
  21. package/dist/cjs/cli/peek.js.map +1 -1
  22. package/dist/cjs/cli/related.js.map +1 -1
  23. package/dist/cjs/cli/search.js.map +1 -1
  24. package/dist/cjs/cli/shared.js +5 -4
  25. package/dist/cjs/cli/shared.js.map +1 -1
  26. package/dist/cjs/cli/sql.js.map +1 -1
  27. package/dist/cjs/cli/status.js.map +1 -1
  28. package/dist/cjs/cli/watch.js.map +1 -1
  29. package/dist/cjs/cli.js +10 -9
  30. package/dist/cjs/cli.js.map +1 -1
  31. package/dist/cjs/commands/index.js.map +1 -1
  32. package/dist/cjs/commands/map.js.map +1 -1
  33. package/dist/cjs/commands/path.js.map +1 -1
  34. package/dist/cjs/commands/peek.js.map +1 -1
  35. package/dist/cjs/commands/related.js.map +1 -1
  36. package/dist/cjs/commands/scope.js.map +1 -1
  37. package/dist/cjs/commands/search.js.map +1 -1
  38. package/dist/cjs/commands/signals.js.map +1 -1
  39. package/dist/cjs/commands/snapshot.js.map +1 -1
  40. package/dist/cjs/commands/status.js.map +1 -1
  41. package/dist/cjs/config/access.js.map +1 -1
  42. package/dist/cjs/config/index.js.map +1 -1
  43. package/dist/cjs/config/load.js.map +1 -1
  44. package/dist/cjs/config/resolve.js.map +1 -1
  45. package/dist/cjs/config/signals.js.map +1 -1
  46. package/dist/cjs/config/types.js.map +1 -1
  47. package/dist/cjs/config/validate.js.map +1 -1
  48. package/dist/cjs/embed/cohere.js.map +1 -1
  49. package/dist/cjs/embed/distribution.js.map +1 -1
  50. package/dist/cjs/embed/endpoint.js.map +1 -1
  51. package/dist/cjs/embed/handoff.js.map +1 -1
  52. package/dist/cjs/embed/http.js.map +1 -1
  53. package/dist/cjs/embed/identity.js.map +1 -1
  54. package/dist/cjs/embed/langfit.js.map +1 -1
  55. package/dist/cjs/embed/languages.js.map +1 -1
  56. package/dist/cjs/embed/openai.js.map +1 -1
  57. package/dist/cjs/embed/query.js.map +1 -1
  58. package/dist/cjs/embed/registry.js.map +1 -1
  59. package/dist/cjs/embed/static.js.map +1 -1
  60. package/dist/cjs/embed/store.js.map +1 -1
  61. package/dist/cjs/embed/types.js.map +1 -1
  62. package/dist/cjs/errors.js.map +1 -1
  63. package/dist/cjs/features/embed.js.map +1 -1
  64. package/dist/cjs/features/fences.js.map +1 -1
  65. package/dist/cjs/features/index.js.map +1 -1
  66. package/dist/cjs/features/links.js.map +1 -1
  67. package/dist/cjs/features/rank.js.map +1 -1
  68. package/dist/cjs/features/sections.js.map +1 -1
  69. package/dist/cjs/features/tags.js.map +1 -1
  70. package/dist/cjs/graph/graph.js.map +1 -1
  71. package/dist/cjs/graph/traverse.js.map +1 -1
  72. package/dist/cjs/index.js.map +1 -1
  73. package/dist/cjs/lib/atomic-write.js.map +1 -1
  74. package/dist/cjs/lib/guarded-tick.js.map +1 -1
  75. package/dist/cjs/lib/serial-query.js.map +1 -1
  76. package/dist/cjs/lib/watch-notification.js.map +1 -1
  77. package/dist/cjs/lib/worker-file.js.map +1 -1
  78. package/dist/cjs/output/column-hint.js.map +1 -1
  79. package/dist/cjs/output/output.js.map +1 -1
  80. package/dist/cjs/output/progress.js.map +1 -1
  81. package/dist/cjs/output/search-error.js.map +1 -1
  82. package/dist/cjs/scan/frontmatter.js.map +1 -1
  83. package/dist/cjs/scan/index.js.map +1 -1
  84. package/dist/cjs/scan/list.js.map +1 -1
  85. package/dist/cjs/scan/pool.js.map +1 -1
  86. package/dist/cjs/scan/reparse.js.map +1 -1
  87. package/dist/cjs/scan/worker-error.js.map +1 -1
  88. package/dist/cjs/store/batch.js.map +1 -1
  89. package/dist/cjs/store/builder.js.map +1 -1
  90. package/dist/cjs/store/cache.js.map +1 -1
  91. package/dist/cjs/store/duckdb/batch.js.map +1 -1
  92. package/dist/cjs/store/duckdb/connection.js.map +1 -1
  93. package/dist/cjs/store/duckdb/engine.d.cts +11 -0
  94. package/dist/cjs/store/duckdb/engine.d.ts +11 -0
  95. package/dist/cjs/store/duckdb/engine.js +193 -0
  96. package/dist/cjs/store/duckdb/engine.js.map +1 -0
  97. package/dist/cjs/store/duckdb/fieldStats.js.map +1 -1
  98. package/dist/cjs/store/duckdb/lexical.d.cts +1 -6
  99. package/dist/cjs/store/duckdb/lexical.d.ts +1 -6
  100. package/dist/cjs/store/duckdb/lexical.js +48 -45
  101. package/dist/cjs/store/duckdb/lexical.js.map +1 -1
  102. package/dist/cjs/store/duckdb/native.d.cts +5 -3
  103. package/dist/cjs/store/duckdb/native.d.ts +5 -3
  104. package/dist/cjs/store/duckdb/native.js +157 -18
  105. package/dist/cjs/store/duckdb/native.js.map +1 -1
  106. package/dist/cjs/store/duckdb/open.js +151 -3
  107. package/dist/cjs/store/duckdb/open.js.map +1 -1
  108. package/dist/cjs/store/duckdb/ordered-bm25.d.cts +3 -16
  109. package/dist/cjs/store/duckdb/ordered-bm25.d.ts +3 -16
  110. package/dist/cjs/store/duckdb/ordered-bm25.js +24 -80
  111. package/dist/cjs/store/duckdb/ordered-bm25.js.map +1 -1
  112. package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
  113. package/dist/cjs/store/duckdb/sql-functions.js.map +1 -1
  114. package/dist/cjs/store/duckdb/store.js.map +1 -1
  115. package/dist/cjs/store/duckdb/vectors.js.map +1 -1
  116. package/dist/cjs/store/embed-scope.js.map +1 -1
  117. package/dist/cjs/store/engine.d.cts +28 -0
  118. package/dist/cjs/store/engine.d.ts +28 -0
  119. package/dist/cjs/store/engine.js +362 -0
  120. package/dist/cjs/store/engine.js.map +1 -0
  121. package/dist/cjs/store/feature-scope.js.map +1 -1
  122. package/dist/cjs/store/index.js.map +1 -1
  123. package/dist/cjs/store/lock-wait.js.map +1 -1
  124. package/dist/cjs/store/native.d.cts +8 -5
  125. package/dist/cjs/store/native.d.ts +8 -5
  126. package/dist/cjs/store/native.js +78 -73
  127. package/dist/cjs/store/native.js.map +1 -1
  128. package/dist/cjs/store/open.js +100 -40
  129. package/dist/cjs/store/open.js.map +1 -1
  130. package/dist/cjs/store/preset-scope.js.map +1 -1
  131. package/dist/cjs/store/readiness.js.map +1 -1
  132. package/dist/cjs/store/reconcile.js.map +1 -1
  133. package/dist/cjs/store/shared.js.map +1 -1
  134. package/dist/cjs/store/signature.js.map +1 -1
  135. package/dist/cjs/store/sql-functions.js.map +1 -1
  136. package/dist/cjs/store/sqlite/connection.js.map +1 -1
  137. package/dist/cjs/store/sqlite/engine.d.cts +12 -0
  138. package/dist/cjs/store/sqlite/engine.d.ts +12 -0
  139. package/dist/cjs/store/sqlite/engine.js +53 -0
  140. package/dist/cjs/store/sqlite/engine.js.map +1 -0
  141. package/dist/cjs/store/sqlite/fieldStats.js.map +1 -1
  142. package/dist/cjs/store/sqlite/lexical.js +3 -4
  143. package/dist/cjs/store/sqlite/lexical.js.map +1 -1
  144. package/dist/cjs/store/sqlite/open.js +119 -6
  145. package/dist/cjs/store/sqlite/open.js.map +1 -1
  146. package/dist/cjs/store/sqlite/reconcile.js.map +1 -1
  147. package/dist/cjs/store/sqlite/sql-functions.js.map +1 -1
  148. package/dist/cjs/store/sqlite/store.js.map +1 -1
  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/transaction.js.map +1 -1
  152. package/dist/cjs/store/turso/connection.js.map +1 -1
  153. package/dist/cjs/store/turso/engine.d.cts +9 -0
  154. package/dist/cjs/store/turso/engine.d.ts +9 -0
  155. package/dist/cjs/store/turso/engine.js +189 -0
  156. package/dist/cjs/store/turso/engine.js.map +1 -0
  157. package/dist/cjs/store/turso/fieldStats.js.map +1 -1
  158. package/dist/cjs/store/turso/lexical-text.js.map +1 -1
  159. package/dist/cjs/store/turso/lexical.js +16 -11
  160. package/dist/cjs/store/turso/lexical.js.map +1 -1
  161. package/dist/cjs/store/turso/native.d.cts +5 -1
  162. package/dist/cjs/store/turso/native.d.ts +5 -1
  163. package/dist/cjs/store/turso/native.js +157 -8
  164. package/dist/cjs/store/turso/native.js.map +1 -1
  165. package/dist/cjs/store/turso/open.js +172 -27
  166. package/dist/cjs/store/turso/open.js.map +1 -1
  167. package/dist/cjs/store/turso/reconcile.d.cts +0 -1
  168. package/dist/cjs/store/turso/reconcile.d.ts +0 -1
  169. package/dist/cjs/store/turso/reconcile.js +22 -23
  170. package/dist/cjs/store/turso/reconcile.js.map +1 -1
  171. package/dist/cjs/store/turso/sql-functions.js.map +1 -1
  172. package/dist/cjs/store/turso/store.js.map +1 -1
  173. package/dist/cjs/store/turso/vectors.js.map +1 -1
  174. package/dist/cjs/store/types.d.cts +2 -0
  175. package/dist/cjs/store/types.d.ts +2 -0
  176. package/dist/cjs/store/types.js.map +1 -1
  177. package/dist/cjs/store/vectors.js.map +1 -1
  178. package/dist/cjs/text/segment.js.map +1 -1
  179. package/dist/cjs/text/strip.js.map +1 -1
  180. package/dist/cjs/watch-claim.js.map +1 -1
  181. package/dist/cjs/watch.js.map +1 -1
  182. package/dist/cjs/workers/parse.js.map +1 -1
  183. package/dist/cjs/workers/watch-heartbeat.js.map +1 -1
  184. package/dist/esm/chunk/extract.js.map +1 -1
  185. package/dist/esm/chunk/group.js.map +1 -1
  186. package/dist/esm/chunk/index.js.map +1 -1
  187. package/dist/esm/chunk/parse.js.map +1 -1
  188. package/dist/esm/chunk/parser.js.map +1 -1
  189. package/dist/esm/chunk/tokens.js.map +1 -1
  190. package/dist/esm/chunk/types.js.map +1 -1
  191. package/dist/esm/chunk/version.js.map +1 -1
  192. package/dist/esm/cli/build.js.map +1 -1
  193. package/dist/esm/cli/constants.d.ts +2 -0
  194. package/dist/esm/cli/constants.js +2 -0
  195. package/dist/esm/cli/constants.js.map +1 -0
  196. package/dist/esm/cli/download.js.map +1 -1
  197. package/dist/esm/cli/index.js.map +1 -1
  198. package/dist/esm/cli/init.js.map +1 -1
  199. package/dist/esm/cli/map.js.map +1 -1
  200. package/dist/esm/cli/named.js +2 -1
  201. package/dist/esm/cli/named.js.map +1 -1
  202. package/dist/esm/cli/path.js.map +1 -1
  203. package/dist/esm/cli/peek.js.map +1 -1
  204. package/dist/esm/cli/related.js.map +1 -1
  205. package/dist/esm/cli/search.js.map +1 -1
  206. package/dist/esm/cli/shared.js +6 -5
  207. package/dist/esm/cli/shared.js.map +1 -1
  208. package/dist/esm/cli/sql.js.map +1 -1
  209. package/dist/esm/cli/status.js.map +1 -1
  210. package/dist/esm/cli/types.js.map +1 -1
  211. package/dist/esm/cli/watch.js.map +1 -1
  212. package/dist/esm/cli.js +10 -9
  213. package/dist/esm/cli.js.map +1 -1
  214. package/dist/esm/commands/index.js.map +1 -1
  215. package/dist/esm/commands/map.js.map +1 -1
  216. package/dist/esm/commands/path.js.map +1 -1
  217. package/dist/esm/commands/peek.js.map +1 -1
  218. package/dist/esm/commands/related.js.map +1 -1
  219. package/dist/esm/commands/scope.js.map +1 -1
  220. package/dist/esm/commands/search.js.map +1 -1
  221. package/dist/esm/commands/signals.js.map +1 -1
  222. package/dist/esm/commands/snapshot.js.map +1 -1
  223. package/dist/esm/commands/status.js.map +1 -1
  224. package/dist/esm/config/access.js.map +1 -1
  225. package/dist/esm/config/index.js.map +1 -1
  226. package/dist/esm/config/load.js.map +1 -1
  227. package/dist/esm/config/resolve.js.map +1 -1
  228. package/dist/esm/config/signals.js.map +1 -1
  229. package/dist/esm/config/types.js.map +1 -1
  230. package/dist/esm/config/validate.js.map +1 -1
  231. package/dist/esm/embed/cohere.js.map +1 -1
  232. package/dist/esm/embed/distribution.js.map +1 -1
  233. package/dist/esm/embed/endpoint.js.map +1 -1
  234. package/dist/esm/embed/handoff.js.map +1 -1
  235. package/dist/esm/embed/http.js.map +1 -1
  236. package/dist/esm/embed/identity.js.map +1 -1
  237. package/dist/esm/embed/langfit.js.map +1 -1
  238. package/dist/esm/embed/languages.js.map +1 -1
  239. package/dist/esm/embed/openai.js.map +1 -1
  240. package/dist/esm/embed/query.js +1 -1
  241. package/dist/esm/embed/query.js.map +1 -1
  242. package/dist/esm/embed/registry.js.map +1 -1
  243. package/dist/esm/embed/static.js.map +1 -1
  244. package/dist/esm/embed/store.js.map +1 -1
  245. package/dist/esm/embed/types.js.map +1 -1
  246. package/dist/esm/errors.js.map +1 -1
  247. package/dist/esm/features/embed.js.map +1 -1
  248. package/dist/esm/features/fences.js.map +1 -1
  249. package/dist/esm/features/index.js.map +1 -1
  250. package/dist/esm/features/links.js.map +1 -1
  251. package/dist/esm/features/rank.js.map +1 -1
  252. package/dist/esm/features/sections.js.map +1 -1
  253. package/dist/esm/features/tags.js.map +1 -1
  254. package/dist/esm/features/types.js.map +1 -1
  255. package/dist/esm/graph/graph.js.map +1 -1
  256. package/dist/esm/graph/traverse.js.map +1 -1
  257. package/dist/esm/index.js.map +1 -1
  258. package/dist/esm/lib/atomic-write.js.map +1 -1
  259. package/dist/esm/lib/guarded-tick.js.map +1 -1
  260. package/dist/esm/lib/serial-query.js.map +1 -1
  261. package/dist/esm/lib/watch-notification.js.map +1 -1
  262. package/dist/esm/lib/worker-file.js.map +1 -1
  263. package/dist/esm/output/column-hint.js.map +1 -1
  264. package/dist/esm/output/output.js.map +1 -1
  265. package/dist/esm/output/progress.js.map +1 -1
  266. package/dist/esm/output/search-error.js.map +1 -1
  267. package/dist/esm/scan/frontmatter.js.map +1 -1
  268. package/dist/esm/scan/index.js.map +1 -1
  269. package/dist/esm/scan/list.js.map +1 -1
  270. package/dist/esm/scan/pool.js.map +1 -1
  271. package/dist/esm/scan/reparse.js.map +1 -1
  272. package/dist/esm/scan/worker-error.js.map +1 -1
  273. package/dist/esm/store/batch.js.map +1 -1
  274. package/dist/esm/store/builder.js.map +1 -1
  275. package/dist/esm/store/cache.js.map +1 -1
  276. package/dist/esm/store/duckdb/batch.js.map +1 -1
  277. package/dist/esm/store/duckdb/connection.js.map +1 -1
  278. package/dist/esm/store/duckdb/engine.d.ts +11 -0
  279. package/dist/esm/store/duckdb/engine.js +18 -0
  280. package/dist/esm/store/duckdb/engine.js.map +1 -0
  281. package/dist/esm/store/duckdb/fieldStats.js.map +1 -1
  282. package/dist/esm/store/duckdb/lexical.d.ts +1 -6
  283. package/dist/esm/store/duckdb/lexical.js +16 -20
  284. package/dist/esm/store/duckdb/lexical.js.map +1 -1
  285. package/dist/esm/store/duckdb/native.d.ts +5 -3
  286. package/dist/esm/store/duckdb/native.js +16 -14
  287. package/dist/esm/store/duckdb/native.js.map +1 -1
  288. package/dist/esm/store/duckdb/open.js +40 -2
  289. package/dist/esm/store/duckdb/open.js.map +1 -1
  290. package/dist/esm/store/duckdb/ordered-bm25.d.ts +3 -16
  291. package/dist/esm/store/duckdb/ordered-bm25.js +14 -55
  292. package/dist/esm/store/duckdb/ordered-bm25.js.map +1 -1
  293. package/dist/esm/store/duckdb/reconcile.js.map +1 -1
  294. package/dist/esm/store/duckdb/sql-functions.js.map +1 -1
  295. package/dist/esm/store/duckdb/store.js.map +1 -1
  296. package/dist/esm/store/duckdb/vectors.js.map +1 -1
  297. package/dist/esm/store/embed-scope.js.map +1 -1
  298. package/dist/esm/store/engine.d.ts +28 -0
  299. package/dist/esm/store/engine.js +85 -0
  300. package/dist/esm/store/engine.js.map +1 -0
  301. package/dist/esm/store/feature-scope.js.map +1 -1
  302. package/dist/esm/store/index.js.map +1 -1
  303. package/dist/esm/store/lock-wait.js.map +1 -1
  304. package/dist/esm/store/native.d.ts +8 -5
  305. package/dist/esm/store/native.js +59 -57
  306. package/dist/esm/store/native.js.map +1 -1
  307. package/dist/esm/store/open.js +24 -7
  308. package/dist/esm/store/open.js.map +1 -1
  309. package/dist/esm/store/preset-scope.js.map +1 -1
  310. package/dist/esm/store/readiness.js.map +1 -1
  311. package/dist/esm/store/reconcile.js.map +1 -1
  312. package/dist/esm/store/shared.js.map +1 -1
  313. package/dist/esm/store/signature.js.map +1 -1
  314. package/dist/esm/store/sql-functions.js.map +1 -1
  315. package/dist/esm/store/sqlite/connection.js.map +1 -1
  316. package/dist/esm/store/sqlite/engine.d.ts +12 -0
  317. package/dist/esm/store/sqlite/engine.js +16 -0
  318. package/dist/esm/store/sqlite/engine.js.map +1 -0
  319. package/dist/esm/store/sqlite/fieldStats.js.map +1 -1
  320. package/dist/esm/store/sqlite/lexical.js +2 -3
  321. package/dist/esm/store/sqlite/lexical.js.map +1 -1
  322. package/dist/esm/store/sqlite/open.js +38 -7
  323. package/dist/esm/store/sqlite/open.js.map +1 -1
  324. package/dist/esm/store/sqlite/reconcile.js.map +1 -1
  325. package/dist/esm/store/sqlite/sql-functions.js.map +1 -1
  326. package/dist/esm/store/sqlite/store.js.map +1 -1
  327. package/dist/esm/store/sqlite/vectors.js.map +1 -1
  328. package/dist/esm/store/stages.js.map +1 -1
  329. package/dist/esm/store/transaction.js.map +1 -1
  330. package/dist/esm/store/turso/connection.js.map +1 -1
  331. package/dist/esm/store/turso/engine.d.ts +9 -0
  332. package/dist/esm/store/turso/engine.js +14 -0
  333. package/dist/esm/store/turso/engine.js.map +1 -0
  334. package/dist/esm/store/turso/fieldStats.js.map +1 -1
  335. package/dist/esm/store/turso/lexical-text.js.map +1 -1
  336. package/dist/esm/store/turso/lexical.js +9 -9
  337. package/dist/esm/store/turso/lexical.js.map +1 -1
  338. package/dist/esm/store/turso/native.d.ts +5 -1
  339. package/dist/esm/store/turso/native.js +16 -10
  340. package/dist/esm/store/turso/native.js.map +1 -1
  341. package/dist/esm/store/turso/open.js +44 -3
  342. package/dist/esm/store/turso/open.js.map +1 -1
  343. package/dist/esm/store/turso/reconcile.d.ts +0 -1
  344. package/dist/esm/store/turso/reconcile.js +3 -8
  345. package/dist/esm/store/turso/reconcile.js.map +1 -1
  346. package/dist/esm/store/turso/sql-functions.js.map +1 -1
  347. package/dist/esm/store/turso/store.js.map +1 -1
  348. package/dist/esm/store/turso/vectors.js.map +1 -1
  349. package/dist/esm/store/types.d.ts +2 -0
  350. package/dist/esm/store/types.js.map +1 -1
  351. package/dist/esm/store/vectors.js.map +1 -1
  352. package/dist/esm/text/segment.js.map +1 -1
  353. package/dist/esm/text/strip.js.map +1 -1
  354. package/dist/esm/watch-claim.js.map +1 -1
  355. package/dist/esm/watch.js.map +1 -1
  356. package/dist/esm/workers/parse.js.map +1 -1
  357. package/dist/esm/workers/watch-heartbeat.js.map +1 -1
  358. package/package.json +21 -6
  359. package/skills/sense/SKILL.md +1 -1
  360. package/skills/sense/references/stores/duckdb.md +1 -1
  361. package/skills/sense/references/stores/sqlite.md +1 -1
  362. package/skills/sense/references/stores/turso.md +1 -1
  363. package/skills/sense-setup/references/stores/duckdb.md +1 -1
  364. package/skills/sense-setup/references/stores/sqlite.md +1 -1
@@ -4,6 +4,7 @@ import { columnHint } from '../output/column-hint.js';
4
4
  import { printRowStream } from '../output/output.js';
5
5
  import { searchError } from '../output/search-error.js';
6
6
  import { openStoreFor } from '../store/index.js';
7
+ import { USAGE_CODE } from './constants.js';
7
8
  // Spreadable option fragments -- one flag name keeps one meaning across every command's table.
8
9
  export const FORMAT = {
9
10
  format: {
@@ -75,7 +76,7 @@ function pickFormat(values, allowed) {
75
76
  const format = String(values.format);
76
77
  if (allowed.includes(format)) return format;
77
78
  console.error(`unknown --format "${format}"; expected ${allowed.join(', ')}`);
78
- process.exit(2);
79
+ process.exit(USAGE_CODE);
79
80
  }
80
81
  export function formatOf(values) {
81
82
  return pickFormat(values, [
@@ -92,7 +93,7 @@ export function rowFormatOf(values) {
92
93
  'csv'
93
94
  ]);
94
95
  }
95
- // Per-command parseArgs: strict (a foreign flag exits 2), and every table gets --help for free.
96
+ // Per-command parseArgs rejects foreign flags as usage errors; every table gets --help for free.
96
97
  export function parse(argv, usage, options) {
97
98
  let values;
98
99
  let positionals;
@@ -113,7 +114,7 @@ export function parse(argv, usage, options) {
113
114
  } catch (err) {
114
115
  console.error(err.message);
115
116
  console.error(usage);
116
- process.exit(2);
117
+ process.exit(USAGE_CODE);
117
118
  }
118
119
  if (values.help) {
119
120
  console.log(usage);
@@ -185,14 +186,14 @@ export async function runSql(cfg, sql, params, format, label, noBuild, preset) {
185
186
  const placeholderCount = ((_sql_match = sql.match(/\?/g)) !== null && _sql_match !== void 0 ? _sql_match : []).length;
186
187
  if (params.length !== placeholderCount) {
187
188
  console.error(`${label} expects ${placeholderCount} parameter(s), got ${params.length}`);
188
- process.exit(2);
189
+ process.exit(USAGE_CODE);
189
190
  }
190
191
  // Naming a preset and never joining it would return the whole index while reading as scoped,
191
192
  // which is the one hazard of binding rather than applying. Refuse instead.
192
193
  if (preset !== undefined && !/\bscope\b/i.test(sql)) {
193
194
  console.error(`--preset binds a temporary "scope" table of the preset's paths, and ${label} never joins it, so the preset would have no effect`);
194
195
  console.error(`add: JOIN scope ON scope."path" = <table>."path"`);
195
- process.exit(2);
196
+ process.exit(USAGE_CODE);
196
197
  }
197
198
  await withResolvedDb(cfg, {
198
199
  noBuild,
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/shared.ts"],"sourcesContent":["import type { ParseArgsOptionsConfig } from 'node:util';\nimport { parseArgs } from 'node:util';\nimport type { ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { resolvePreset } from '../config/index.ts';\nimport { columnHint } from '../output/column-hint.ts';\nimport type { Row, RowFormat } from '../output/output.ts';\nimport { printRowStream } from '../output/output.ts';\nimport { searchError } from '../output/search-error.ts';\nimport { openStoreFor } from '../store/index.ts';\nimport type { BuildRequirement, OpenResult } from '../store/open.ts';\nimport type { Store } from '../store/types.ts';\nimport type { Ctx } from './types.ts';\n\n// Spreadable option fragments -- one flag name keeps one meaning across every command's table.\nexport const FORMAT: ParseArgsOptionsConfig = { format: { type: 'string', default: 'table' } };\nexport const CONFIG: ParseArgsOptionsConfig = { config: { type: 'string' } };\nexport const NO_BUILD: ParseArgsOptionsConfig = { 'no-build': { type: 'boolean', default: false } };\n// The scope vocabulary every scoped command shares: named preset, ad hoc include/exclude\n// globs, a where SQL condition. search adds k on top.\nexport const SCOPE: ParseArgsOptionsConfig = {\n where: { type: 'string' },\n preset: { type: 'string' },\n include: { type: 'string', multiple: true },\n exclude: { type: 'string', multiple: true },\n // Widening, which no other flag can express: --include and --exclude each override their\n // own side of the preset, so neither can drop an exclusion the preset declares.\n 'no-exclude': { type: 'boolean', default: false },\n};\nexport const SEARCH_FLAGS: ParseArgsOptionsConfig = { ...SCOPE, k: { type: 'string' }, 'snippet-char-limit': { type: 'string' }, 'snippet-count-limit': { type: 'string' } };\n\ntype Values = Record<string, string | boolean | string[] | undefined>;\n\n// The SCOPE fragment's parsed values as the overrides every scoped command passes down.\n// One place to read them: a new scope field is added to the fragment and here, not per-command.\nexport function scopeOf(values: Values): SearchOverrides {\n return {\n preset: values.preset as string | undefined,\n include: values.include as string[] | undefined,\n exclude: values.exclude as string[] | undefined,\n where: values.where as string | undefined,\n noExclude: values['no-exclude'] === true,\n };\n}\n\n// parseArgs is strict about flag names; this applies the same strictness to the value.\n// An unrecognised --format is a usage error, not a silent fallback to `table`.\nfunction pickFormat<T extends string>(values: Values, allowed: readonly T[]): T {\n const format = String(values.format);\n if ((allowed as readonly string[]).includes(format)) return format as T;\n console.error(`unknown --format \"${format}\"; expected ${allowed.join(', ')}`);\n process.exit(2);\n}\n\nexport function formatOf(values: Values): 'table' | 'json' {\n return pickFormat(values, ['table', 'json'] as const);\n}\n\n// csv is a row set rendered as rows; map, peek, status, and path render structures instead,\n// and take formatOf.\nexport function rowFormatOf(values: Values): RowFormat {\n return pickFormat(values, ['table', 'json', 'csv'] as const);\n}\n\n// Per-command parseArgs: strict (a foreign flag exits 2), and every table gets --help for free.\nexport function parse(argv: string[], usage: string, options: ParseArgsOptionsConfig): { values: Values; positionals: string[] } {\n let values: Values;\n let positionals: string[];\n try {\n ({ values, positionals } = parseArgs({\n args: argv,\n options: { ...options, help: { type: 'boolean', default: false, short: 'h' } },\n strict: true,\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage);\n process.exit(2);\n }\n if (values.help) {\n console.log(usage);\n process.exit(0);\n }\n return { values, positionals };\n}\n\n// --k must be a positive integer: SQLite reads a bound LIMIT of -1 as \"unlimited\" and 0 as \"nothing\", and parseInt would silently truncate \"5.9\".\n// All three are caller mistakes worth a usage error, matching the config-level SavedSearch validation.\nexport function parseK(k: string | undefined, usageError: (message: string) => never): number | undefined {\n if (k === undefined) return undefined;\n const parsed = Number(k);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--k expects a positive integer, got \"${k}\"`);\n return parsed;\n}\n\n// Same positive-integer rule as --k, beside it since both flags come from SEARCH_FLAGS.\nexport function parseSnippetCharLimit(value: string | undefined, usageError: (message: string) => never): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--snippet-char-limit expects a positive integer, got \"${value}\"`);\n return parsed;\n}\n\nexport function parseSnippetCountLimit(value: string | undefined, usageError: (message: string) => never): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--snippet-count-limit expects a positive integer, got \"${value}\"`);\n return parsed;\n}\n\n// Shared open-query-close envelope for commands that touch the tree.\n\nexport function printWarnings(warnings: string[]): void {\n for (const w of warnings) console.warn(w);\n}\n\nexport interface DbOpenOptions {\n noBuild: boolean;\n requirements: ReadonlySet<BuildRequirement> | ((cfg: ResolvedConfig) => ReadonlySet<BuildRequirement>);\n}\n\nexport async function withResolvedDb(cfg: ResolvedConfig, options: DbOpenOptions, fn: (store: OpenResult['store'], cfg: ResolvedConfig, build: boolean) => void | Promise<void>): Promise<void> {\n const requirements = typeof options.requirements === 'function' ? options.requirements(cfg) : options.requirements;\n const build = !options.noBuild && cfg.build !== false;\n const { store, warnings } = await openStoreFor(cfg, {\n build,\n requirements,\n });\n printWarnings(warnings);\n try {\n await fn(store, cfg, build);\n } finally {\n await store.close();\n }\n}\n\nexport async function withDb(ctx: Ctx, configPath: string | undefined, options: DbOpenOptions, fn: (store: OpenResult['store'], cfg: ResolvedConfig, build: boolean) => void | Promise<void>): Promise<void> {\n const cfg = ctx.resolveConfig(configPath, { writeMigration: !options.noBuild, query: true });\n return withResolvedDb(cfg, options, fn);\n}\n\n// `--preset` on SQL binds a temp `scope` table rather than transparently filtering: temp views shadowing the base tables can't cover `content`, since FTS5 MATCH treats the table name as a hidden column.\n// A flag that silently scoped three tables of four would look scoped and not be.\nasync function bindScope(store: Store, cfg: ResolvedConfig, preset: string): Promise<void> {\n const { name } = resolvePreset(cfg, preset); // unknown names throw, listing what is declared\n await store.exec('DROP TABLE IF EXISTS temp.scope');\n await store.exec('CREATE TEMP TABLE scope (\"path\" TEXT PRIMARY KEY)');\n const insert = await store.prepare('INSERT INTO temp.scope (\"path\") SELECT \"path\" FROM preset_files WHERE preset = ?');\n await insert.run(name);\n}\n\n// An unbound `?` silently binds NULL, so mismatched param counts fail loudly instead.\nexport async function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: RowFormat, label: string, noBuild: boolean, preset?: string): Promise<void> {\n const placeholderCount = (sql.match(/\\?/g) ?? []).length;\n if (params.length !== placeholderCount) {\n console.error(`${label} expects ${placeholderCount} parameter(s), got ${params.length}`);\n process.exit(2);\n }\n // Naming a preset and never joining it would return the whole index while reading as scoped,\n // which is the one hazard of binding rather than applying. Refuse instead.\n if (preset !== undefined && !/\\bscope\\b/i.test(sql)) {\n console.error(`--preset binds a temporary \"scope\" table of the preset's paths, and ${label} never joins it, so the preset would have no effect`);\n console.error(`add: JOIN scope ON scope.\"path\" = <table>.\"path\"`);\n process.exit(2);\n }\n await withResolvedDb(cfg, { noBuild, requirements: new Set<BuildRequirement>(['core']) }, async (store) => {\n if (preset !== undefined) await bindScope(store, cfg, preset);\n // Streamed, not collected: `sql`'s result size is the caller's business, not ours. columns() reads the statement's own metadata, so a 0-row csv gets a header too.\n // A mid-stream SQLite error (e.g. SQLITE_BUSY outlasting busy_timeout) may leave partial output; the nonzero exit code is the failure signal, not a completeness guarantee.\n try {\n const statement = await store.raw.prepare(sql);\n const columns = statement.columns().map((c) => c.name);\n await printRowStream(statement.iterate(...params) as AsyncIterable<Row>, format, columns);\n } catch (err) {\n const hinted = columnHint(await store.docs.columns(), err as Error); // columns read while the store is still open\n // A saved query or ad-hoc SQL can carry `content MATCH ?` too, so the same FTS5 punctuation trap applies to its bound parameters.\n // SQL without MATCH gets its error verbatim; search advice on a plain typo would mislead.\n if (/\\bMATCH\\b/i.test(sql)) throw searchError(hinted, params.join(' '));\n throw hinted;\n }\n });\n}\n"],"names":["parseArgs","resolvePreset","columnHint","printRowStream","searchError","openStoreFor","FORMAT","format","type","default","CONFIG","config","NO_BUILD","SCOPE","where","preset","include","multiple","exclude","SEARCH_FLAGS","k","scopeOf","values","noExclude","pickFormat","allowed","String","includes","console","error","join","process","exit","formatOf","rowFormatOf","parse","argv","usage","options","positionals","args","help","short","strict","allowPositionals","err","message","log","parseK","usageError","undefined","parsed","Number","isInteger","parseSnippetCharLimit","value","parseSnippetCountLimit","printWarnings","warnings","w","warn","withResolvedDb","cfg","fn","requirements","build","noBuild","store","close","withDb","ctx","configPath","resolveConfig","writeMigration","query","bindScope","name","exec","insert","prepare","run","runSql","sql","params","label","placeholderCount","match","length","test","Set","statement","raw","columns","map","c","iterate","hinted","docs"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/cli/shared.ts"],"sourcesContent":["import type { ParseArgsOptionsConfig } from 'node:util';\nimport { parseArgs } from 'node:util';\nimport type { ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { resolvePreset } from '../config/index.ts';\nimport { columnHint } from '../output/column-hint.ts';\nimport type { Row, RowFormat } from '../output/output.ts';\nimport { printRowStream } from '../output/output.ts';\nimport { searchError } from '../output/search-error.ts';\nimport { openStoreFor } from '../store/index.ts';\nimport type { BuildRequirement, OpenResult } from '../store/open.ts';\nimport type { Store } from '../store/types.ts';\nimport { USAGE_CODE } from './constants.ts';\nimport type { Ctx } from './types.ts';\n\n// Spreadable option fragments -- one flag name keeps one meaning across every command's table.\nexport const FORMAT: ParseArgsOptionsConfig = { format: { type: 'string', default: 'table' } };\nexport const CONFIG: ParseArgsOptionsConfig = { config: { type: 'string' } };\nexport const NO_BUILD: ParseArgsOptionsConfig = { 'no-build': { type: 'boolean', default: false } };\n// The scope vocabulary every scoped command shares: named preset, ad hoc include/exclude\n// globs, a where SQL condition. search adds k on top.\nexport const SCOPE: ParseArgsOptionsConfig = {\n where: { type: 'string' },\n preset: { type: 'string' },\n include: { type: 'string', multiple: true },\n exclude: { type: 'string', multiple: true },\n // Widening, which no other flag can express: --include and --exclude each override their\n // own side of the preset, so neither can drop an exclusion the preset declares.\n 'no-exclude': { type: 'boolean', default: false },\n};\nexport const SEARCH_FLAGS: ParseArgsOptionsConfig = { ...SCOPE, k: { type: 'string' }, 'snippet-char-limit': { type: 'string' }, 'snippet-count-limit': { type: 'string' } };\n\ntype Values = Record<string, string | boolean | string[] | undefined>;\n\n// The SCOPE fragment's parsed values as the overrides every scoped command passes down.\n// One place to read them: a new scope field is added to the fragment and here, not per-command.\nexport function scopeOf(values: Values): SearchOverrides {\n return {\n preset: values.preset as string | undefined,\n include: values.include as string[] | undefined,\n exclude: values.exclude as string[] | undefined,\n where: values.where as string | undefined,\n noExclude: values['no-exclude'] === true,\n };\n}\n\n// parseArgs is strict about flag names; this applies the same strictness to the value.\n// An unrecognised --format is a usage error, not a silent fallback to `table`.\nfunction pickFormat<T extends string>(values: Values, allowed: readonly T[]): T {\n const format = String(values.format);\n if ((allowed as readonly string[]).includes(format)) return format as T;\n console.error(`unknown --format \"${format}\"; expected ${allowed.join(', ')}`);\n process.exit(USAGE_CODE);\n}\n\nexport function formatOf(values: Values): 'table' | 'json' {\n return pickFormat(values, ['table', 'json'] as const);\n}\n\n// csv is a row set rendered as rows; map, peek, status, and path render structures instead,\n// and take formatOf.\nexport function rowFormatOf(values: Values): RowFormat {\n return pickFormat(values, ['table', 'json', 'csv'] as const);\n}\n\n// Per-command parseArgs rejects foreign flags as usage errors; every table gets --help for free.\nexport function parse(argv: string[], usage: string, options: ParseArgsOptionsConfig): { values: Values; positionals: string[] } {\n let values: Values;\n let positionals: string[];\n try {\n ({ values, positionals } = parseArgs({\n args: argv,\n options: { ...options, help: { type: 'boolean', default: false, short: 'h' } },\n strict: true,\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage);\n process.exit(USAGE_CODE);\n }\n if (values.help) {\n console.log(usage);\n process.exit(0);\n }\n return { values, positionals };\n}\n\n// --k must be a positive integer: SQLite reads a bound LIMIT of -1 as \"unlimited\" and 0 as \"nothing\", and parseInt would silently truncate \"5.9\".\n// All three are caller mistakes worth a usage error, matching the config-level SavedSearch validation.\nexport function parseK(k: string | undefined, usageError: (message: string) => never): number | undefined {\n if (k === undefined) return undefined;\n const parsed = Number(k);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--k expects a positive integer, got \"${k}\"`);\n return parsed;\n}\n\n// Same positive-integer rule as --k, beside it since both flags come from SEARCH_FLAGS.\nexport function parseSnippetCharLimit(value: string | undefined, usageError: (message: string) => never): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--snippet-char-limit expects a positive integer, got \"${value}\"`);\n return parsed;\n}\n\nexport function parseSnippetCountLimit(value: string | undefined, usageError: (message: string) => never): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--snippet-count-limit expects a positive integer, got \"${value}\"`);\n return parsed;\n}\n\n// Shared open-query-close envelope for commands that touch the tree.\n\nexport function printWarnings(warnings: string[]): void {\n for (const w of warnings) console.warn(w);\n}\n\nexport interface DbOpenOptions {\n noBuild: boolean;\n requirements: ReadonlySet<BuildRequirement> | ((cfg: ResolvedConfig) => ReadonlySet<BuildRequirement>);\n}\n\nexport async function withResolvedDb(cfg: ResolvedConfig, options: DbOpenOptions, fn: (store: OpenResult['store'], cfg: ResolvedConfig, build: boolean) => void | Promise<void>): Promise<void> {\n const requirements = typeof options.requirements === 'function' ? options.requirements(cfg) : options.requirements;\n const build = !options.noBuild && cfg.build !== false;\n const { store, warnings } = await openStoreFor(cfg, {\n build,\n requirements,\n });\n printWarnings(warnings);\n try {\n await fn(store, cfg, build);\n } finally {\n await store.close();\n }\n}\n\nexport async function withDb(ctx: Ctx, configPath: string | undefined, options: DbOpenOptions, fn: (store: OpenResult['store'], cfg: ResolvedConfig, build: boolean) => void | Promise<void>): Promise<void> {\n const cfg = ctx.resolveConfig(configPath, { writeMigration: !options.noBuild, query: true });\n return withResolvedDb(cfg, options, fn);\n}\n\n// `--preset` on SQL binds a temp `scope` table rather than transparently filtering: temp views shadowing the base tables can't cover `content`, since FTS5 MATCH treats the table name as a hidden column.\n// A flag that silently scoped three tables of four would look scoped and not be.\nasync function bindScope(store: Store, cfg: ResolvedConfig, preset: string): Promise<void> {\n const { name } = resolvePreset(cfg, preset); // unknown names throw, listing what is declared\n await store.exec('DROP TABLE IF EXISTS temp.scope');\n await store.exec('CREATE TEMP TABLE scope (\"path\" TEXT PRIMARY KEY)');\n const insert = await store.prepare('INSERT INTO temp.scope (\"path\") SELECT \"path\" FROM preset_files WHERE preset = ?');\n await insert.run(name);\n}\n\n// An unbound `?` silently binds NULL, so mismatched param counts fail loudly instead.\nexport async function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: RowFormat, label: string, noBuild: boolean, preset?: string): Promise<void> {\n const placeholderCount = (sql.match(/\\?/g) ?? []).length;\n if (params.length !== placeholderCount) {\n console.error(`${label} expects ${placeholderCount} parameter(s), got ${params.length}`);\n process.exit(USAGE_CODE);\n }\n // Naming a preset and never joining it would return the whole index while reading as scoped,\n // which is the one hazard of binding rather than applying. Refuse instead.\n if (preset !== undefined && !/\\bscope\\b/i.test(sql)) {\n console.error(`--preset binds a temporary \"scope\" table of the preset's paths, and ${label} never joins it, so the preset would have no effect`);\n console.error(`add: JOIN scope ON scope.\"path\" = <table>.\"path\"`);\n process.exit(USAGE_CODE);\n }\n await withResolvedDb(cfg, { noBuild, requirements: new Set<BuildRequirement>(['core']) }, async (store) => {\n if (preset !== undefined) await bindScope(store, cfg, preset);\n // Streamed, not collected: `sql`'s result size is the caller's business, not ours. columns() reads the statement's own metadata, so a 0-row csv gets a header too.\n // A mid-stream SQLite error (e.g. SQLITE_BUSY outlasting busy_timeout) may leave partial output; the nonzero exit code is the failure signal, not a completeness guarantee.\n try {\n const statement = await store.raw.prepare(sql);\n const columns = statement.columns().map((c) => c.name);\n await printRowStream(statement.iterate(...params) as AsyncIterable<Row>, format, columns);\n } catch (err) {\n const hinted = columnHint(await store.docs.columns(), err as Error); // columns read while the store is still open\n // A saved query or ad-hoc SQL can carry `content MATCH ?` too, so the same FTS5 punctuation trap applies to its bound parameters.\n // SQL without MATCH gets its error verbatim; search advice on a plain typo would mislead.\n if (/\\bMATCH\\b/i.test(sql)) throw searchError(hinted, params.join(' '));\n throw hinted;\n }\n });\n}\n"],"names":["parseArgs","resolvePreset","columnHint","printRowStream","searchError","openStoreFor","USAGE_CODE","FORMAT","format","type","default","CONFIG","config","NO_BUILD","SCOPE","where","preset","include","multiple","exclude","SEARCH_FLAGS","k","scopeOf","values","noExclude","pickFormat","allowed","String","includes","console","error","join","process","exit","formatOf","rowFormatOf","parse","argv","usage","options","positionals","args","help","short","strict","allowPositionals","err","message","log","parseK","usageError","undefined","parsed","Number","isInteger","parseSnippetCharLimit","value","parseSnippetCountLimit","printWarnings","warnings","w","warn","withResolvedDb","cfg","fn","requirements","build","noBuild","store","close","withDb","ctx","configPath","resolveConfig","writeMigration","query","bindScope","name","exec","insert","prepare","run","runSql","sql","params","label","placeholderCount","match","length","test","Set","statement","raw","columns","map","c","iterate","hinted","docs"],"mappings":"AACA,SAASA,SAAS,QAAQ,YAAY;AAEtC,SAASC,aAAa,QAAQ,qBAAqB;AACnD,SAASC,UAAU,QAAQ,2BAA2B;AAEtD,SAASC,cAAc,QAAQ,sBAAsB;AACrD,SAASC,WAAW,QAAQ,4BAA4B;AACxD,SAASC,YAAY,QAAQ,oBAAoB;AAGjD,SAASC,UAAU,QAAQ,iBAAiB;AAG5C,+FAA+F;AAC/F,OAAO,MAAMC,SAAiC;IAAEC,QAAQ;QAAEC,MAAM;QAAUC,SAAS;IAAQ;AAAE,EAAE;AAC/F,OAAO,MAAMC,SAAiC;IAAEC,QAAQ;QAAEH,MAAM;IAAS;AAAE,EAAE;AAC7E,OAAO,MAAMI,WAAmC;IAAE,YAAY;QAAEJ,MAAM;QAAWC,SAAS;IAAM;AAAE,EAAE;AACpG,yFAAyF;AACzF,sDAAsD;AACtD,OAAO,MAAMI,QAAgC;IAC3CC,OAAO;QAAEN,MAAM;IAAS;IACxBO,QAAQ;QAAEP,MAAM;IAAS;IACzBQ,SAAS;QAAER,MAAM;QAAUS,UAAU;IAAK;IAC1CC,SAAS;QAAEV,MAAM;QAAUS,UAAU;IAAK;IAC1C,yFAAyF;IACzF,gFAAgF;IAChF,cAAc;QAAET,MAAM;QAAWC,SAAS;IAAM;AAClD,EAAE;AACF,OAAO,MAAMU,eAAuC;IAAE,GAAGN,KAAK;IAAEO,GAAG;QAAEZ,MAAM;IAAS;IAAG,sBAAsB;QAAEA,MAAM;IAAS;IAAG,uBAAuB;QAAEA,MAAM;IAAS;AAAE,EAAE;AAI7K,wFAAwF;AACxF,gGAAgG;AAChG,OAAO,SAASa,QAAQC,MAAc;IACpC,OAAO;QACLP,QAAQO,OAAOP,MAAM;QACrBC,SAASM,OAAON,OAAO;QACvBE,SAASI,OAAOJ,OAAO;QACvBJ,OAAOQ,OAAOR,KAAK;QACnBS,WAAWD,MAAM,CAAC,aAAa,KAAK;IACtC;AACF;AAEA,uFAAuF;AACvF,+EAA+E;AAC/E,SAASE,WAA6BF,MAAc,EAAEG,OAAqB;IACzE,MAAMlB,SAASmB,OAAOJ,OAAOf,MAAM;IACnC,IAAI,AAACkB,QAA8BE,QAAQ,CAACpB,SAAS,OAAOA;IAC5DqB,QAAQC,KAAK,CAAC,CAAC,kBAAkB,EAAEtB,OAAO,YAAY,EAAEkB,QAAQK,IAAI,CAAC,OAAO;IAC5EC,QAAQC,IAAI,CAAC3B;AACf;AAEA,OAAO,SAAS4B,SAASX,MAAc;IACrC,OAAOE,WAAWF,QAAQ;QAAC;QAAS;KAAO;AAC7C;AAEA,4FAA4F;AAC5F,qBAAqB;AACrB,OAAO,SAASY,YAAYZ,MAAc;IACxC,OAAOE,WAAWF,QAAQ;QAAC;QAAS;QAAQ;KAAM;AACpD;AAEA,iGAAiG;AACjG,OAAO,SAASa,MAAMC,IAAc,EAAEC,KAAa,EAAEC,OAA+B;IAClF,IAAIhB;IACJ,IAAIiB;IACJ,IAAI;QACD,CAAA,EAAEjB,MAAM,EAAEiB,WAAW,EAAE,GAAGxC,UAAU;YACnCyC,MAAMJ;YACNE,SAAS;gBAAE,GAAGA,OAAO;gBAAEG,MAAM;oBAAEjC,MAAM;oBAAWC,SAAS;oBAAOiC,OAAO;gBAAI;YAAE;YAC7EC,QAAQ;YACRC,kBAAkB;QACpB,EAAC;IACH,EAAE,OAAOC,KAAK;QACZjB,QAAQC,KAAK,CAAC,AAACgB,IAAcC,OAAO;QACpClB,QAAQC,KAAK,CAACQ;QACdN,QAAQC,IAAI,CAAC3B;IACf;IACA,IAAIiB,OAAOmB,IAAI,EAAE;QACfb,QAAQmB,GAAG,CAACV;QACZN,QAAQC,IAAI,CAAC;IACf;IACA,OAAO;QAAEV;QAAQiB;IAAY;AAC/B;AAEA,kJAAkJ;AAClJ,uGAAuG;AACvG,OAAO,SAASS,OAAO5B,CAAqB,EAAE6B,UAAsC;IAClF,IAAI7B,MAAM8B,WAAW,OAAOA;IAC5B,MAAMC,SAASC,OAAOhC;IACtB,IAAI,CAACgC,OAAOC,SAAS,CAACF,WAAWA,UAAU,GAAGF,WAAW,CAAC,qCAAqC,EAAE7B,EAAE,CAAC,CAAC;IACrG,OAAO+B;AACT;AAEA,wFAAwF;AACxF,OAAO,SAASG,sBAAsBC,KAAyB,EAAEN,UAAsC;IACrG,IAAIM,UAAUL,WAAW,OAAOA;IAChC,MAAMC,SAASC,OAAOG;IACtB,IAAI,CAACH,OAAOC,SAAS,CAACF,WAAWA,UAAU,GAAGF,WAAW,CAAC,sDAAsD,EAAEM,MAAM,CAAC,CAAC;IAC1H,OAAOJ;AACT;AAEA,OAAO,SAASK,uBAAuBD,KAAyB,EAAEN,UAAsC;IACtG,IAAIM,UAAUL,WAAW,OAAOA;IAChC,MAAMC,SAASC,OAAOG;IACtB,IAAI,CAACH,OAAOC,SAAS,CAACF,WAAWA,UAAU,GAAGF,WAAW,CAAC,uDAAuD,EAAEM,MAAM,CAAC,CAAC;IAC3H,OAAOJ;AACT;AAEA,qEAAqE;AAErE,OAAO,SAASM,cAAcC,QAAkB;IAC9C,KAAK,MAAMC,KAAKD,SAAU9B,QAAQgC,IAAI,CAACD;AACzC;AAOA,OAAO,eAAeE,eAAeC,GAAmB,EAAExB,OAAsB,EAAEyB,EAA6F;IAC7K,MAAMC,eAAe,OAAO1B,QAAQ0B,YAAY,KAAK,aAAa1B,QAAQ0B,YAAY,CAACF,OAAOxB,QAAQ0B,YAAY;IAClH,MAAMC,QAAQ,CAAC3B,QAAQ4B,OAAO,IAAIJ,IAAIG,KAAK,KAAK;IAChD,MAAM,EAAEE,KAAK,EAAET,QAAQ,EAAE,GAAG,MAAMtD,aAAa0D,KAAK;QAClDG;QACAD;IACF;IACAP,cAAcC;IACd,IAAI;QACF,MAAMK,GAAGI,OAAOL,KAAKG;IACvB,SAAU;QACR,MAAME,MAAMC,KAAK;IACnB;AACF;AAEA,OAAO,eAAeC,OAAOC,GAAQ,EAAEC,UAA8B,EAAEjC,OAAsB,EAAEyB,EAA6F;IAC1L,MAAMD,MAAMQ,IAAIE,aAAa,CAACD,YAAY;QAAEE,gBAAgB,CAACnC,QAAQ4B,OAAO;QAAEQ,OAAO;IAAK;IAC1F,OAAOb,eAAeC,KAAKxB,SAASyB;AACtC;AAEA,2MAA2M;AAC3M,iFAAiF;AACjF,eAAeY,UAAUR,KAAY,EAAEL,GAAmB,EAAE/C,MAAc;IACxE,MAAM,EAAE6D,IAAI,EAAE,GAAG5E,cAAc8D,KAAK/C,SAAS,gDAAgD;IAC7F,MAAMoD,MAAMU,IAAI,CAAC;IACjB,MAAMV,MAAMU,IAAI,CAAC;IACjB,MAAMC,SAAS,MAAMX,MAAMY,OAAO,CAAC;IACnC,MAAMD,OAAOE,GAAG,CAACJ;AACnB;AAEA,sFAAsF;AACtF,OAAO,eAAeK,OAAOnB,GAAmB,EAAEoB,GAAW,EAAEC,MAAgB,EAAE5E,MAAiB,EAAE6E,KAAa,EAAElB,OAAgB,EAAEnD,MAAe;QACxHmE;IAA1B,MAAMG,mBAAmB,EAACH,aAAAA,IAAII,KAAK,CAAC,oBAAVJ,wBAAAA,aAAoB,EAAE,EAAEK,MAAM;IACxD,IAAIJ,OAAOI,MAAM,KAAKF,kBAAkB;QACtCzD,QAAQC,KAAK,CAAC,GAAGuD,MAAM,SAAS,EAAEC,iBAAiB,mBAAmB,EAAEF,OAAOI,MAAM,EAAE;QACvFxD,QAAQC,IAAI,CAAC3B;IACf;IACA,6FAA6F;IAC7F,2EAA2E;IAC3E,IAAIU,WAAWmC,aAAa,CAAC,aAAasC,IAAI,CAACN,MAAM;QACnDtD,QAAQC,KAAK,CAAC,CAAC,oEAAoE,EAAEuD,MAAM,mDAAmD,CAAC;QAC/IxD,QAAQC,KAAK,CAAC,CAAC,gDAAgD,CAAC;QAChEE,QAAQC,IAAI,CAAC3B;IACf;IACA,MAAMwD,eAAeC,KAAK;QAAEI;QAASF,cAAc,IAAIyB,IAAsB;YAAC;SAAO;IAAE,GAAG,OAAOtB;QAC/F,IAAIpD,WAAWmC,WAAW,MAAMyB,UAAUR,OAAOL,KAAK/C;QACtD,mKAAmK;QACnK,4KAA4K;QAC5K,IAAI;YACF,MAAM2E,YAAY,MAAMvB,MAAMwB,GAAG,CAACZ,OAAO,CAACG;YAC1C,MAAMU,UAAUF,UAAUE,OAAO,GAAGC,GAAG,CAAC,CAACC,IAAMA,EAAElB,IAAI;YACrD,MAAM1E,eAAewF,UAAUK,OAAO,IAAIZ,SAA+B5E,QAAQqF;QACnF,EAAE,OAAO/C,KAAK;YACZ,MAAMmD,SAAS/F,WAAW,MAAMkE,MAAM8B,IAAI,CAACL,OAAO,IAAI/C,MAAe,6CAA6C;YAClH,kIAAkI;YAClI,0FAA0F;YAC1F,IAAI,aAAa2C,IAAI,CAACN,MAAM,MAAM/E,YAAY6F,QAAQb,OAAOrD,IAAI,CAAC;YAClE,MAAMkE;QACR;IACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/sql.ts"],"sourcesContent":["import { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, NO_BUILD, parse, rowFormatOf, runSql } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst sqlCmd: Command = async (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.sql}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...NO_BUILD, ...FORMAT, ...CONFIG, preset: { type: 'string' } });\n const [sql, ...params] = positionals;\n if (!sql) ctx.usageError(usage);\n const format = rowFormatOf(values);\n const noBuild = values['no-build'] === true;\n const cfg = ctx.resolveConfig(values.config as string | undefined, { writeMigration: !noBuild, query: true });\n await runSql(cfg, sql, params, format, 'ad-hoc statement', noBuild, values.preset as string | undefined);\n};\nexport default sqlCmd;\n"],"names":["USAGE","CONFIG","FORMAT","NO_BUILD","parse","rowFormatOf","runSql","sqlCmd","ctx","usage","name","sql","values","positionals","argv","preset","type","params","usageError","format","noBuild","cfg","resolveConfig","config","writeMigration","query"],"mappings":"AAAA,SAASA,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,WAAW,EAAEC,MAAM,QAAQ,cAAc;AAGnF,MAAMC,SAAkB,OAAOC;IAC7B,MAAMC,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEV,MAAMW,GAAG,EAAE;IAC/C,MAAM,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGT,MAAMI,IAAIM,IAAI,EAAEL,OAAO;QAAE,GAAGN,QAAQ;QAAE,GAAGD,MAAM;QAAE,GAAGD,MAAM;QAAEc,QAAQ;YAAEC,MAAM;QAAS;IAAE;IACvH,MAAM,CAACL,KAAK,GAAGM,OAAO,GAAGJ;IACzB,IAAI,CAACF,KAAKH,IAAIU,UAAU,CAACT;IACzB,MAAMU,SAASd,YAAYO;IAC3B,MAAMQ,UAAUR,MAAM,CAAC,WAAW,KAAK;IACvC,MAAMS,MAAMb,IAAIc,aAAa,CAACV,OAAOW,MAAM,EAAwB;QAAEC,gBAAgB,CAACJ;QAASK,OAAO;IAAK;IAC3G,MAAMnB,OAAOe,KAAKV,KAAKM,QAAQE,QAAQ,oBAAoBC,SAASR,OAAOG,MAAM;AACnF;AACA,eAAeR,OAAO"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/cli/sql.ts"],"sourcesContent":["import { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, NO_BUILD, parse, rowFormatOf, runSql } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst sqlCmd: Command = async (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.sql}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...NO_BUILD, ...FORMAT, ...CONFIG, preset: { type: 'string' } });\n const [sql, ...params] = positionals;\n if (!sql) ctx.usageError(usage);\n const format = rowFormatOf(values);\n const noBuild = values['no-build'] === true;\n const cfg = ctx.resolveConfig(values.config as string | undefined, { writeMigration: !noBuild, query: true });\n await runSql(cfg, sql, params, format, 'ad-hoc statement', noBuild, values.preset as string | undefined);\n};\nexport default sqlCmd;\n"],"names":["USAGE","CONFIG","FORMAT","NO_BUILD","parse","rowFormatOf","runSql","sqlCmd","ctx","usage","name","sql","values","positionals","argv","preset","type","params","usageError","format","noBuild","cfg","resolveConfig","config","writeMigration","query"],"mappings":"AAAA,SAASA,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,WAAW,EAAEC,MAAM,QAAQ,cAAc;AAGnF,MAAMC,SAAkB,OAAOC;IAC7B,MAAMC,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEV,MAAMW,GAAG,EAAE;IAC/C,MAAM,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGT,MAAMI,IAAIM,IAAI,EAAEL,OAAO;QAAE,GAAGN,QAAQ;QAAE,GAAGD,MAAM;QAAE,GAAGD,MAAM;QAAEc,QAAQ;YAAEC,MAAM;QAAS;IAAE;IACvH,MAAM,CAACL,KAAK,GAAGM,OAAO,GAAGJ;IACzB,IAAI,CAACF,KAAKH,IAAIU,UAAU,CAACT;IACzB,MAAMU,SAASd,YAAYO;IAC3B,MAAMQ,UAAUR,MAAM,CAAC,WAAW,KAAK;IACvC,MAAMS,MAAMb,IAAIc,aAAa,CAACV,OAAOW,MAAM,EAAwB;QAAEC,gBAAgB,CAACJ;QAASK,OAAO;IAAK;IAC3G,MAAMnB,OAAOe,KAAKV,KAAKM,QAAQE,QAAQ,oBAAoBC,SAASR,OAAOG,MAAM;AACnF;AACA,eAAeR,OAAO"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/status.ts"],"sourcesContent":["import { dirname, join } from 'node:path';\nimport { presetCoverage } from '../commands/status.ts';\nimport { embedConfig, featureStates, STATE_DIR, SUPPORTED_CONFIG_VERSION } from '../config/index.ts';\nimport { languageDistribution } from '../embed/distribution.ts';\nimport { probeReachable } from '../embed/http.ts';\nimport { isDownloadable, MODEL_FILENAMES, modelDir, modelPresent, readLanguages } from '../embed/store.ts';\nimport { SenseError } from '../errors.ts';\nimport { featuresLine, presetsLines, stringifyJson } from '../output/output.ts';\nimport type { OpenResult } from '../store/index.ts';\nimport { docCount, getMeta, lexicalReadiness, openStore, storeFilename } from '../store/index.ts';\nimport type { Store } from '../store/types.ts';\nimport { readWatchClaim } from '../watch-claim.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// status names what you cannot read off the config file: locations sense chose, values it derived, state it stored. Config content itself is not echoed, since duplicating its globs here would create two places that disagree after an edit.\n// The exception is the embed block's url and key, whose effect is remote and otherwise invisible.\n\n// A failed or interrupted vector preparation can leave core and lexical state usable. Status is\n// observational, so it reports that pending capability instead of repairing it.\nasync function vectorState(store: Store): Promise<{ embedded: number; pending: number } | null> {\n try {\n const stmt = await store.prepare('SELECT COUNT(vector) AS embedded, COUNT(*) - COUNT(vector) AS pending FROM embeddings');\n return (await stmt.get()) as { embedded: number; pending: number };\n } catch {\n return null;\n }\n}\n\nasync function parseErrorCount(store: Store): Promise<number> {\n const stmt = await store.prepare(`SELECT COUNT(*) AS n FROM frontmatter WHERE \"_parse_error\" IS NOT NULL`);\n return ((await stmt.get()) as { n: number }).n;\n}\n\n// A URL can carry credentials in its userinfo (https://user:pass@host/v1). status output gets\n// pasted into issues and transcripts, so it is always safe to paste.\nexport function redactUrl(url: string): string {\n try {\n const parsed = new URL(url);\n if (!parsed.username && !parsed.password) return url;\n parsed.username = '';\n parsed.password = '';\n return `${parsed.toString().replace(/\\/$/, '')} (credentials redacted)`;\n } catch {\n return url;\n }\n}\n\n// A stopped Ollama/LM Studio/Cohere endpoint prints identically to a running one otherwise; any\n// HTTP response counts as reachable (probeReachable), so this only distinguishes up from down.\nasync function embedReachable(e: { provider: string; url?: string }): Promise<boolean | null> {\n if (e.provider === 'static' || (e.provider === 'openai' && !e.url)) return null;\n const base = (e.url ?? 'https://api.cohere.com').replace(/\\/+$/, '');\n return probeReachable(e.provider === 'openai' ? `${base}/models` : base);\n}\n\ntype LanguagesState = 'declared' | 'none' | 'unresolved' | null;\n\n// Config-declared languages win over the model card, for every provider, as registry.ts does.\n// A local-path model has no card by design, so it is never \"unresolved\": that means an HF id.\nfunction languagesInfo(e: NonNullable<ReturnType<typeof embedConfig>>): { languages: string[] | null; state: LanguagesState; source: 'config' | 'card' | null } {\n if (e.languages) return { languages: e.languages, state: 'declared', source: 'config' };\n if (e.provider !== 'static' || !isDownloadable(e.model)) return { languages: null, state: null, source: null };\n const cardLanguages = readLanguages(e.model);\n if (cardLanguages === undefined) return { languages: null, state: 'unresolved', source: null };\n if (cardLanguages.length === 0) return { languages: null, state: 'none', source: null };\n return { languages: cardLanguages, state: 'declared', source: 'card' };\n}\n\nconst status: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.status}`, { ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const cfg = ctx.resolveConfig(values.config as string | undefined, { writeMigration: false });\n const lexical = await lexicalReadiness(cfg);\n let opened: OpenResult;\n try {\n opened = await openStore(cfg, { build: false });\n } catch (err) {\n if (!(err instanceof SenseError) || err.code !== 'INDEX_NOT_READY') throw err;\n const configDir = cfg.configDir ?? cfg.rootDir ?? cfg.baseDir;\n const dbPath = join(configDir, STATE_DIR, storeFilename(cfg));\n const watcher = readWatchClaim(configDir);\n const result = {\n config: cfg.configPath,\n configVersion: SUPPORTED_CONFIG_VERSION,\n migratedFrom: cfg.migratedFrom ?? null,\n unknownConfigKeys: cfg.unknownKeys ?? null,\n tree: cfg.rootDir ?? cfg.baseDir,\n treeRoot: cfg.rootDir ?? cfg.baseDir,\n configDir,\n cache: dirname(dbPath),\n db: dbPath,\n indexReady: false,\n indexError: err.message,\n lexicalReady: lexical.ready,\n lexicalError: lexical.error,\n watcherPid: watcher ? String(watcher.pid) : null,\n watcherHeartbeatSecondsAgo: watcher ? Math.round((Date.now() - watcher.heartbeatMs) / 1000) : null,\n };\n if (format === 'json') {\n console.log(stringifyJson(result, 2));\n } else {\n const migrated = cfg.migratedFrom !== undefined ? `, migration from v${cfg.migratedFrom} pending` : '';\n console.log(`config: ${result.config} (v${SUPPORTED_CONFIG_VERSION}${migrated})`);\n console.log(`tree root: ${result.treeRoot}`);\n console.log(`configDir: ${result.configDir}`);\n console.log(`cache: ${result.cache}`);\n console.log(`index: not ready (${result.indexError})`);\n console.log(`lexical: ${result.lexicalReady ? 'ready' : `not ready (${result.lexicalError})`}`);\n const pid = result.watcherPid ? `pid ${result.watcherPid}, ` : '';\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: none' : `watcher: ${pid}last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n }\n return;\n }\n const { store, dbPath, warnings } = opened;\n try {\n printWarnings(warnings);\n\n const features = featureStates(cfg);\n const e = embedConfig(cfg);\n const hasModel = e ? modelPresent(cfg) : false;\n const reachable = e ? await embedReachable(e) : null;\n const vectors = e ? await vectorState(store) : null;\n const presets = await presetCoverage(store, cfg);\n const { languages: declaredLanguages, state: languagesState, source: languagesSource } = e ? languagesInfo(e) : { languages: null, state: null, source: null };\n const detectedLanguages = (await languageDistribution(store)) ?? null;\n // This is the compatible cache's stored version. Observational open refuses a mismatch rather\n // than rebuilding it before this read.\n const cacheSchema = await getMeta(store, 'schema_version');\n // Each store owns what it reports and how it is worded (Store.engineStatus); this command\n // prints entries generically, without branching on any store's name.\n const engine = await store.engineStatus();\n const watcher = readWatchClaim(cfg.configDir ?? cfg.rootDir ?? cfg.baseDir);\n // The env var holds the token; only its name and whether it is set are ever reported.\n const keyEnv = e?.key ? { name: e.key, set: (process.env[e.key] ?? '') !== '' } : null;\n const result = {\n config: cfg.configPath,\n configVersion: SUPPORTED_CONFIG_VERSION,\n migratedFrom: cfg.migratedFrom ?? null,\n unknownConfigKeys: cfg.unknownKeys ?? null,\n tree: cfg.rootDir ?? cfg.baseDir,\n treeRoot: cfg.rootDir ?? cfg.baseDir,\n configDir: cfg.configDir ?? cfg.baseDir,\n cache: dirname(dbPath),\n db: dbPath,\n indexReady: true,\n indexError: null,\n lexicalReady: lexical.ready,\n lexicalError: lexical.error,\n cacheSchema,\n docs: await docCount(store),\n unparseableFrontmatter: await parseErrorCount(store),\n features: features.on,\n featuresOff: features.off,\n embed: e ? { provider: e.provider, model: e.model, dir: e.provider === 'static' ? modelDir(e.model) : null, url: e.url ? redactUrl(e.url) : null, reachable, keyEnv, downloaded: hasModel, languages: declaredLanguages, languagesState, detectedLanguages, ...(vectors ?? {}) } : null,\n presets,\n queries: Object.keys(cfg.queries ?? {}).length,\n watcherPid: watcher ? String(watcher.pid) : null,\n watcherHeartbeatSecondsAgo: watcher ? Math.round((Date.now() - watcher.heartbeatMs) / 1000) : null,\n engine,\n };\n\n if (format === 'json') {\n console.log(stringifyJson(result, 2));\n } else {\n const migrated = cfg.migratedFrom !== undefined ? `, migration from v${cfg.migratedFrom} applied in memory` : '';\n console.log(`config: ${result.config} (v${SUPPORTED_CONFIG_VERSION}${migrated})`);\n // A load-time stderr warning has scrolled away by the time anyone looks here.\n if (cfg.unknownKeys) console.log(` unknown keys, ignored: ${cfg.unknownKeys.join(', ')}`);\n console.log(`tree root: ${result.treeRoot}`);\n console.log(`configDir: ${result.configDir}`);\n console.log(`cache: ${result.cache} (schema ${result.cacheSchema}; ${ctx.name} build --force to recreate)`);\n console.log(`lexical: ${result.lexicalReady ? 'ready' : `not ready (${result.lexicalError})`}`);\n console.log(`docs: ${result.docs}${result.unparseableFrontmatter > 0 ? ` (${result.unparseableFrontmatter} with unparseable frontmatter: WHERE _parse_error IS NOT NULL)` : ''}`);\n console.log('');\n console.log(featuresLine(features));\n // One authoritative block, off states included: an absent model reads as a degraded search,\n // not as an empty corpus.\n if (!e) console.log('embed: off (no preset asks for vectors)');\n else {\n console.log(`embed: ${e.provider} ${e.model}`);\n if (e.provider === 'static') console.log(` model: ${modelDir(e.model)} (${hasModel ? 'present' : `missing, ${isDownloadable(e.model) ? `fetches when build, watch, or a vector query needs it; run \\`${ctx.name} download\\` to prefetch` : `no ${MODEL_FILENAMES} in that directory`}`})`);\n if (declaredLanguages && languagesSource === 'config') console.log(` languages: ${declaredLanguages.join(', ')} (declared in embed.languages)`);\n else if (declaredLanguages && languagesSource === 'card') console.log(` languages: ${declaredLanguages.join(', ')} (declared by the model card)`);\n else if (languagesState === 'none') console.log(' languages: none declared by the model card');\n else if (languagesState === 'unresolved') console.log(` languages: unresolved (model card unreachable; run \\`${ctx.name} download\\`)`);\n // Cohere defaults to api.cohere.com with no url in the config; show it anyway so the\n // reachability probe below has something to name.\n if (e.url || reachable !== null) {\n const shown = e.url ? redactUrl(e.url) : 'https://api.cohere.com (default)';\n console.log(` url: ${shown}${reachable === null ? '' : reachable ? ' (reachable)' : ' (unreachable)'}`);\n }\n if (keyEnv) console.log(` key: env ${keyEnv.name} (${keyEnv.set ? 'set' : 'NOT SET'})`);\n if (!hasModel) console.log(' vectors: unavailable until the model is present; semantic queries fail, while lexical-only presets remain usable');\n else if (vectors) console.log(` vectors: ${vectors.embedded} embedded, ${vectors.pending} pending${vectors.pending > 0 ? ` (run \\`${ctx.name} build\\` to prepare all configured vectors)` : ''}`);\n if (detectedLanguages) {\n const total = Object.values(detectedLanguages).reduce((a, b) => a + b, 0);\n const breakdown = Object.entries(detectedLanguages)\n .sort((a, b) => b[1] - a[1])\n .map(([code, n]) => `${code} ${Math.round((n / total) * 100)}%`)\n .join(', ');\n console.log(` detected: ${breakdown} (${total} chunks classified)`);\n }\n }\n console.log('');\n for (const line of presetsLines(presets)) console.log(line);\n console.log('');\n console.log(`queries: ${result.queries} saved (${ctx.name} --list)`);\n const pid = result.watcherPid ? `pid ${result.watcherPid}, ` : '';\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: none' : `watcher: ${pid}last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n for (const [key, value] of Object.entries(result.engine)) console.log(`${`${store.name}:`.padEnd(10)}${key} ${value}`);\n }\n } finally {\n await store.close();\n }\n};\nexport default status;\n"],"names":["dirname","join","presetCoverage","embedConfig","featureStates","STATE_DIR","SUPPORTED_CONFIG_VERSION","languageDistribution","probeReachable","isDownloadable","MODEL_FILENAMES","modelDir","modelPresent","readLanguages","SenseError","featuresLine","presetsLines","stringifyJson","docCount","getMeta","lexicalReadiness","openStore","storeFilename","readWatchClaim","USAGE","CONFIG","FORMAT","formatOf","parse","printWarnings","vectorState","store","stmt","prepare","get","parseErrorCount","n","redactUrl","url","parsed","URL","username","password","toString","replace","embedReachable","e","provider","base","languagesInfo","languages","state","source","model","cardLanguages","undefined","length","status","ctx","values","argv","name","format","cfg","resolveConfig","config","writeMigration","lexical","opened","build","err","code","configDir","rootDir","baseDir","dbPath","watcher","result","configPath","configVersion","migratedFrom","unknownConfigKeys","unknownKeys","tree","treeRoot","cache","db","indexReady","indexError","message","lexicalReady","ready","lexicalError","error","watcherPid","String","pid","watcherHeartbeatSecondsAgo","Math","round","Date","now","heartbeatMs","console","log","migrated","warnings","process","features","hasModel","reachable","vectors","presets","declaredLanguages","languagesState","languagesSource","detectedLanguages","cacheSchema","engine","engineStatus","keyEnv","key","set","env","docs","unparseableFrontmatter","on","featuresOff","off","embed","dir","downloaded","queries","Object","keys","shown","embedded","pending","total","reduce","a","b","breakdown","entries","sort","map","line","value","padEnd","close"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/cli/status.ts"],"sourcesContent":["import { dirname, join } from 'node:path';\nimport { presetCoverage } from '../commands/status.ts';\nimport { embedConfig, featureStates, STATE_DIR, SUPPORTED_CONFIG_VERSION } from '../config/index.ts';\nimport { languageDistribution } from '../embed/distribution.ts';\nimport { probeReachable } from '../embed/http.ts';\nimport { isDownloadable, MODEL_FILENAMES, modelDir, modelPresent, readLanguages } from '../embed/store.ts';\nimport { SenseError } from '../errors.ts';\nimport { featuresLine, presetsLines, stringifyJson } from '../output/output.ts';\nimport type { OpenResult } from '../store/index.ts';\nimport { docCount, getMeta, lexicalReadiness, openStore, storeFilename } from '../store/index.ts';\nimport type { Store } from '../store/types.ts';\nimport { readWatchClaim } from '../watch-claim.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// status names what you cannot read off the config file: locations sense chose, values it derived, state it stored. Config content itself is not echoed, since duplicating its globs here would create two places that disagree after an edit.\n// The exception is the embed block's url and key, whose effect is remote and otherwise invisible.\n\n// A failed or interrupted vector preparation can leave core and lexical state usable. Status is\n// observational, so it reports that pending capability instead of repairing it.\nasync function vectorState(store: Store): Promise<{ embedded: number; pending: number } | null> {\n try {\n const stmt = await store.prepare('SELECT COUNT(vector) AS embedded, COUNT(*) - COUNT(vector) AS pending FROM embeddings');\n return (await stmt.get()) as { embedded: number; pending: number };\n } catch {\n return null;\n }\n}\n\nasync function parseErrorCount(store: Store): Promise<number> {\n const stmt = await store.prepare(`SELECT COUNT(*) AS n FROM frontmatter WHERE \"_parse_error\" IS NOT NULL`);\n return ((await stmt.get()) as { n: number }).n;\n}\n\n// A URL can carry credentials in its userinfo (https://user:pass@host/v1). status output gets\n// pasted into issues and transcripts, so it is always safe to paste.\nexport function redactUrl(url: string): string {\n try {\n const parsed = new URL(url);\n if (!parsed.username && !parsed.password) return url;\n parsed.username = '';\n parsed.password = '';\n return `${parsed.toString().replace(/\\/$/, '')} (credentials redacted)`;\n } catch {\n return url;\n }\n}\n\n// A stopped Ollama/LM Studio/Cohere endpoint prints identically to a running one otherwise; any\n// HTTP response counts as reachable (probeReachable), so this only distinguishes up from down.\nasync function embedReachable(e: { provider: string; url?: string }): Promise<boolean | null> {\n if (e.provider === 'static' || (e.provider === 'openai' && !e.url)) return null;\n const base = (e.url ?? 'https://api.cohere.com').replace(/\\/+$/, '');\n return probeReachable(e.provider === 'openai' ? `${base}/models` : base);\n}\n\ntype LanguagesState = 'declared' | 'none' | 'unresolved' | null;\n\n// Config-declared languages win over the model card, for every provider, as registry.ts does.\n// A local-path model has no card by design, so it is never \"unresolved\": that means an HF id.\nfunction languagesInfo(e: NonNullable<ReturnType<typeof embedConfig>>): { languages: string[] | null; state: LanguagesState; source: 'config' | 'card' | null } {\n if (e.languages) return { languages: e.languages, state: 'declared', source: 'config' };\n if (e.provider !== 'static' || !isDownloadable(e.model)) return { languages: null, state: null, source: null };\n const cardLanguages = readLanguages(e.model);\n if (cardLanguages === undefined) return { languages: null, state: 'unresolved', source: null };\n if (cardLanguages.length === 0) return { languages: null, state: 'none', source: null };\n return { languages: cardLanguages, state: 'declared', source: 'card' };\n}\n\nconst status: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.status}`, { ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const cfg = ctx.resolveConfig(values.config as string | undefined, { writeMigration: false });\n const lexical = await lexicalReadiness(cfg);\n let opened: OpenResult;\n try {\n opened = await openStore(cfg, { build: false });\n } catch (err) {\n if (!(err instanceof SenseError) || err.code !== 'INDEX_NOT_READY') throw err;\n const configDir = cfg.configDir ?? cfg.rootDir ?? cfg.baseDir;\n const dbPath = join(configDir, STATE_DIR, storeFilename(cfg));\n const watcher = readWatchClaim(configDir);\n const result = {\n config: cfg.configPath,\n configVersion: SUPPORTED_CONFIG_VERSION,\n migratedFrom: cfg.migratedFrom ?? null,\n unknownConfigKeys: cfg.unknownKeys ?? null,\n tree: cfg.rootDir ?? cfg.baseDir,\n treeRoot: cfg.rootDir ?? cfg.baseDir,\n configDir,\n cache: dirname(dbPath),\n db: dbPath,\n indexReady: false,\n indexError: err.message,\n lexicalReady: lexical.ready,\n lexicalError: lexical.error,\n watcherPid: watcher ? String(watcher.pid) : null,\n watcherHeartbeatSecondsAgo: watcher ? Math.round((Date.now() - watcher.heartbeatMs) / 1000) : null,\n };\n if (format === 'json') {\n console.log(stringifyJson(result, 2));\n } else {\n const migrated = cfg.migratedFrom !== undefined ? `, migration from v${cfg.migratedFrom} pending` : '';\n console.log(`config: ${result.config} (v${SUPPORTED_CONFIG_VERSION}${migrated})`);\n console.log(`tree root: ${result.treeRoot}`);\n console.log(`configDir: ${result.configDir}`);\n console.log(`cache: ${result.cache}`);\n console.log(`index: not ready (${result.indexError})`);\n console.log(`lexical: ${result.lexicalReady ? 'ready' : `not ready (${result.lexicalError})`}`);\n const pid = result.watcherPid ? `pid ${result.watcherPid}, ` : '';\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: none' : `watcher: ${pid}last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n }\n return;\n }\n const { store, dbPath, warnings } = opened;\n try {\n printWarnings(warnings);\n\n const features = featureStates(cfg);\n const e = embedConfig(cfg);\n const hasModel = e ? modelPresent(cfg) : false;\n const reachable = e ? await embedReachable(e) : null;\n const vectors = e ? await vectorState(store) : null;\n const presets = await presetCoverage(store, cfg);\n const { languages: declaredLanguages, state: languagesState, source: languagesSource } = e ? languagesInfo(e) : { languages: null, state: null, source: null };\n const detectedLanguages = (await languageDistribution(store)) ?? null;\n // This is the compatible cache's stored version. Observational open refuses a mismatch rather\n // than rebuilding it before this read.\n const cacheSchema = await getMeta(store, 'schema_version');\n // Each store owns what it reports and how it is worded (Store.engineStatus); this command\n // prints entries generically, without branching on any store's name.\n const engine = await store.engineStatus();\n const watcher = readWatchClaim(cfg.configDir ?? cfg.rootDir ?? cfg.baseDir);\n // The env var holds the token; only its name and whether it is set are ever reported.\n const keyEnv = e?.key ? { name: e.key, set: (process.env[e.key] ?? '') !== '' } : null;\n const result = {\n config: cfg.configPath,\n configVersion: SUPPORTED_CONFIG_VERSION,\n migratedFrom: cfg.migratedFrom ?? null,\n unknownConfigKeys: cfg.unknownKeys ?? null,\n tree: cfg.rootDir ?? cfg.baseDir,\n treeRoot: cfg.rootDir ?? cfg.baseDir,\n configDir: cfg.configDir ?? cfg.baseDir,\n cache: dirname(dbPath),\n db: dbPath,\n indexReady: true,\n indexError: null,\n lexicalReady: lexical.ready,\n lexicalError: lexical.error,\n cacheSchema,\n docs: await docCount(store),\n unparseableFrontmatter: await parseErrorCount(store),\n features: features.on,\n featuresOff: features.off,\n embed: e ? { provider: e.provider, model: e.model, dir: e.provider === 'static' ? modelDir(e.model) : null, url: e.url ? redactUrl(e.url) : null, reachable, keyEnv, downloaded: hasModel, languages: declaredLanguages, languagesState, detectedLanguages, ...(vectors ?? {}) } : null,\n presets,\n queries: Object.keys(cfg.queries ?? {}).length,\n watcherPid: watcher ? String(watcher.pid) : null,\n watcherHeartbeatSecondsAgo: watcher ? Math.round((Date.now() - watcher.heartbeatMs) / 1000) : null,\n engine,\n };\n\n if (format === 'json') {\n console.log(stringifyJson(result, 2));\n } else {\n const migrated = cfg.migratedFrom !== undefined ? `, migration from v${cfg.migratedFrom} applied in memory` : '';\n console.log(`config: ${result.config} (v${SUPPORTED_CONFIG_VERSION}${migrated})`);\n // A load-time stderr warning has scrolled away by the time anyone looks here.\n if (cfg.unknownKeys) console.log(` unknown keys, ignored: ${cfg.unknownKeys.join(', ')}`);\n console.log(`tree root: ${result.treeRoot}`);\n console.log(`configDir: ${result.configDir}`);\n console.log(`cache: ${result.cache} (schema ${result.cacheSchema}; ${ctx.name} build --force to recreate)`);\n console.log(`lexical: ${result.lexicalReady ? 'ready' : `not ready (${result.lexicalError})`}`);\n console.log(`docs: ${result.docs}${result.unparseableFrontmatter > 0 ? ` (${result.unparseableFrontmatter} with unparseable frontmatter: WHERE _parse_error IS NOT NULL)` : ''}`);\n console.log('');\n console.log(featuresLine(features));\n // One authoritative block, off states included: an absent model reads as a degraded search,\n // not as an empty corpus.\n if (!e) console.log('embed: off (no preset asks for vectors)');\n else {\n console.log(`embed: ${e.provider} ${e.model}`);\n if (e.provider === 'static') console.log(` model: ${modelDir(e.model)} (${hasModel ? 'present' : `missing, ${isDownloadable(e.model) ? `fetches when build, watch, or a vector query needs it; run \\`${ctx.name} download\\` to prefetch` : `no ${MODEL_FILENAMES} in that directory`}`})`);\n if (declaredLanguages && languagesSource === 'config') console.log(` languages: ${declaredLanguages.join(', ')} (declared in embed.languages)`);\n else if (declaredLanguages && languagesSource === 'card') console.log(` languages: ${declaredLanguages.join(', ')} (declared by the model card)`);\n else if (languagesState === 'none') console.log(' languages: none declared by the model card');\n else if (languagesState === 'unresolved') console.log(` languages: unresolved (model card unreachable; run \\`${ctx.name} download\\`)`);\n // Cohere defaults to api.cohere.com with no url in the config; show it anyway so the\n // reachability probe below has something to name.\n if (e.url || reachable !== null) {\n const shown = e.url ? redactUrl(e.url) : 'https://api.cohere.com (default)';\n console.log(` url: ${shown}${reachable === null ? '' : reachable ? ' (reachable)' : ' (unreachable)'}`);\n }\n if (keyEnv) console.log(` key: env ${keyEnv.name} (${keyEnv.set ? 'set' : 'NOT SET'})`);\n if (!hasModel) console.log(' vectors: unavailable until the model is present; semantic queries fail, while lexical-only presets remain usable');\n else if (vectors) console.log(` vectors: ${vectors.embedded} embedded, ${vectors.pending} pending${vectors.pending > 0 ? ` (run \\`${ctx.name} build\\` to prepare all configured vectors)` : ''}`);\n if (detectedLanguages) {\n const total = Object.values(detectedLanguages).reduce((a, b) => a + b, 0);\n const breakdown = Object.entries(detectedLanguages)\n .sort((a, b) => b[1] - a[1])\n .map(([code, n]) => `${code} ${Math.round((n / total) * 100)}%`)\n .join(', ');\n console.log(` detected: ${breakdown} (${total} chunks classified)`);\n }\n }\n console.log('');\n for (const line of presetsLines(presets)) console.log(line);\n console.log('');\n console.log(`queries: ${result.queries} saved (${ctx.name} --list)`);\n const pid = result.watcherPid ? `pid ${result.watcherPid}, ` : '';\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: none' : `watcher: ${pid}last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n for (const [key, value] of Object.entries(result.engine)) console.log(`${`${store.name}:`.padEnd(10)}${key} ${value}`);\n }\n } finally {\n await store.close();\n }\n};\nexport default status;\n"],"names":["dirname","join","presetCoverage","embedConfig","featureStates","STATE_DIR","SUPPORTED_CONFIG_VERSION","languageDistribution","probeReachable","isDownloadable","MODEL_FILENAMES","modelDir","modelPresent","readLanguages","SenseError","featuresLine","presetsLines","stringifyJson","docCount","getMeta","lexicalReadiness","openStore","storeFilename","readWatchClaim","USAGE","CONFIG","FORMAT","formatOf","parse","printWarnings","vectorState","store","stmt","prepare","get","parseErrorCount","n","redactUrl","url","parsed","URL","username","password","toString","replace","embedReachable","e","provider","base","languagesInfo","languages","state","source","model","cardLanguages","undefined","length","status","ctx","values","argv","name","format","cfg","resolveConfig","config","writeMigration","lexical","opened","build","err","code","configDir","rootDir","baseDir","dbPath","watcher","result","configPath","configVersion","migratedFrom","unknownConfigKeys","unknownKeys","tree","treeRoot","cache","db","indexReady","indexError","message","lexicalReady","ready","lexicalError","error","watcherPid","String","pid","watcherHeartbeatSecondsAgo","Math","round","Date","now","heartbeatMs","console","log","migrated","warnings","process","features","hasModel","reachable","vectors","presets","declaredLanguages","languagesState","languagesSource","detectedLanguages","cacheSchema","engine","engineStatus","keyEnv","key","set","env","docs","unparseableFrontmatter","on","featuresOff","off","embed","dir","downloaded","queries","Object","keys","shown","embedded","pending","total","reduce","a","b","breakdown","entries","sort","map","line","value","padEnd","close"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/types.ts"],"sourcesContent":["import type { LoadConfigOptions, ResolvedConfig } from '../config/index.ts';\n\n// Handed to every command; each command parses its own argv via shared.ts's `parse`.\nexport interface Ctx {\n name: string;\n argv: string[]; // argv after the command word\n resolveConfig(configPath?: string, options?: LoadConfigOptions & { query?: boolean }): ResolvedConfig;\n usageError(message: string): never;\n}\n\nexport type Command = (ctx: Ctx) => Promise<void> | void;\n"],"names":[],"mappings":"AAUA,WAAyD"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/cli/types.ts"],"sourcesContent":["import type { LoadConfigOptions, ResolvedConfig } from '../config/index.ts';\n\n// Handed to every command; each command parses its own argv via shared.ts's `parse`.\nexport interface Ctx {\n name: string;\n argv: string[]; // argv after the command word\n resolveConfig(configPath?: string, options?: LoadConfigOptions & { query?: boolean }): ResolvedConfig;\n usageError(message: string): never;\n}\n\nexport type Command = (ctx: Ctx) => Promise<void> | void;\n"],"names":[],"mappings":"AAUA,WAAyD"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/watch.ts"],"sourcesContent":["import type { WatchEvent } from '../watch.ts';\nimport { runWatch } from '../watch.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst watch: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.watch}`, { force: { type: 'boolean', default: false }, ...CONFIG });\n await runWatch(ctx.resolveConfig(values.config as string | undefined), {\n force: values.force as boolean,\n onEvent: (event: WatchEvent) => {\n if (event.type === 'started') {\n console.log(`${ctx.name} watch: watching ${event.rootDir}`);\n console.log(`${ctx.name} watch: db ${event.dbPath}`);\n } else if (event.type === 'reconciled') {\n printWarnings(event.warnings);\n if (event.parsed > 0) console.log(`${ctx.name} watch: reconciled, ${event.parsed} file(s) reparsed (${event.total} total)`);\n } else {\n console.error(`${ctx.name} watch: reconcile error: ${event.message}`);\n }\n },\n });\n};\nexport default watch;\n"],"names":["runWatch","USAGE","CONFIG","parse","printWarnings","watch","ctx","values","argv","name","force","type","default","resolveConfig","config","onEvent","event","console","log","rootDir","dbPath","warnings","parsed","total","error","message"],"mappings":"AACA,SAASA,QAAQ,QAAQ,cAAc;AACvC,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,KAAK,EAAEC,aAAa,QAAQ,cAAc;AAG3D,MAAMC,QAAiB,OAAOC;IAC5B,MAAM,EAAEC,MAAM,EAAE,GAAGJ,MAAMG,IAAIE,IAAI,EAAE,CAAC,OAAO,EAAEF,IAAIG,IAAI,CAAC,CAAC,EAAER,MAAMI,KAAK,EAAE,EAAE;QAAEK,OAAO;YAAEC,MAAM;YAAWC,SAAS;QAAM;QAAG,GAAGV,MAAM;IAAC;IAChI,MAAMF,SAASM,IAAIO,aAAa,CAACN,OAAOO,MAAM,GAAyB;QACrEJ,OAAOH,OAAOG,KAAK;QACnBK,SAAS,CAACC;YACR,IAAIA,MAAML,IAAI,KAAK,WAAW;gBAC5BM,QAAQC,GAAG,CAAC,GAAGZ,IAAIG,IAAI,CAAC,iBAAiB,EAAEO,MAAMG,OAAO,EAAE;gBAC1DF,QAAQC,GAAG,CAAC,GAAGZ,IAAIG,IAAI,CAAC,WAAW,EAAEO,MAAMI,MAAM,EAAE;YACrD,OAAO,IAAIJ,MAAML,IAAI,KAAK,cAAc;gBACtCP,cAAcY,MAAMK,QAAQ;gBAC5B,IAAIL,MAAMM,MAAM,GAAG,GAAGL,QAAQC,GAAG,CAAC,GAAGZ,IAAIG,IAAI,CAAC,oBAAoB,EAAEO,MAAMM,MAAM,CAAC,mBAAmB,EAAEN,MAAMO,KAAK,CAAC,OAAO,CAAC;YAC5H,OAAO;gBACLN,QAAQO,KAAK,CAAC,GAAGlB,IAAIG,IAAI,CAAC,yBAAyB,EAAEO,MAAMS,OAAO,EAAE;YACtE;QACF;IACF;AACF;AACA,eAAepB,MAAM"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/cli/watch.ts"],"sourcesContent":["import type { WatchEvent } from '../watch.ts';\nimport { runWatch } from '../watch.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst watch: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.watch}`, { force: { type: 'boolean', default: false }, ...CONFIG });\n await runWatch(ctx.resolveConfig(values.config as string | undefined), {\n force: values.force as boolean,\n onEvent: (event: WatchEvent) => {\n if (event.type === 'started') {\n console.log(`${ctx.name} watch: watching ${event.rootDir}`);\n console.log(`${ctx.name} watch: db ${event.dbPath}`);\n } else if (event.type === 'reconciled') {\n printWarnings(event.warnings);\n if (event.parsed > 0) console.log(`${ctx.name} watch: reconciled, ${event.parsed} file(s) reparsed (${event.total} total)`);\n } else {\n console.error(`${ctx.name} watch: reconcile error: ${event.message}`);\n }\n },\n });\n};\nexport default watch;\n"],"names":["runWatch","USAGE","CONFIG","parse","printWarnings","watch","ctx","values","argv","name","force","type","default","resolveConfig","config","onEvent","event","console","log","rootDir","dbPath","warnings","parsed","total","error","message"],"mappings":"AACA,SAASA,QAAQ,QAAQ,cAAc;AACvC,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,KAAK,EAAEC,aAAa,QAAQ,cAAc;AAG3D,MAAMC,QAAiB,OAAOC;IAC5B,MAAM,EAAEC,MAAM,EAAE,GAAGJ,MAAMG,IAAIE,IAAI,EAAE,CAAC,OAAO,EAAEF,IAAIG,IAAI,CAAC,CAAC,EAAER,MAAMI,KAAK,EAAE,EAAE;QAAEK,OAAO;YAAEC,MAAM;YAAWC,SAAS;QAAM;QAAG,GAAGV,MAAM;IAAC;IAChI,MAAMF,SAASM,IAAIO,aAAa,CAACN,OAAOO,MAAM,GAAyB;QACrEJ,OAAOH,OAAOG,KAAK;QACnBK,SAAS,CAACC;YACR,IAAIA,MAAML,IAAI,KAAK,WAAW;gBAC5BM,QAAQC,GAAG,CAAC,GAAGZ,IAAIG,IAAI,CAAC,iBAAiB,EAAEO,MAAMG,OAAO,EAAE;gBAC1DF,QAAQC,GAAG,CAAC,GAAGZ,IAAIG,IAAI,CAAC,WAAW,EAAEO,MAAMI,MAAM,EAAE;YACrD,OAAO,IAAIJ,MAAML,IAAI,KAAK,cAAc;gBACtCP,cAAcY,MAAMK,QAAQ;gBAC5B,IAAIL,MAAMM,MAAM,GAAG,GAAGL,QAAQC,GAAG,CAAC,GAAGZ,IAAIG,IAAI,CAAC,oBAAoB,EAAEO,MAAMM,MAAM,CAAC,mBAAmB,EAAEN,MAAMO,KAAK,CAAC,OAAO,CAAC;YAC5H,OAAO;gBACLN,QAAQO,KAAK,CAAC,GAAGlB,IAAIG,IAAI,CAAC,yBAAyB,EAAEO,MAAMS,OAAO,EAAE;YACtE;QACF;IACF;AACF;AACA,eAAepB,MAAM"}
package/dist/esm/cli.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { createRequire } from 'node:module';
2
2
  import { parseArgs } from 'node:util';
3
+ import { ERROR_CODE, USAGE_CODE } from './cli/constants.js';
3
4
  import { COMMANDS, USAGE } from './cli/index.js';
4
5
  import { loadConfig, SUPPORTED_CONFIG_VERSION } from './config/index.js';
5
6
  // Parsing and dispatch only; commands lazy-load from src/cli/, so nothing heavy is imported
@@ -43,14 +44,14 @@ function resolveConfigFor(name, configPath, options = {}) {
43
44
  }
44
45
  return cfg;
45
46
  }
46
- // Thrown errors -> exit 1 with the message verbatim; usage errors exit 2 directly.
47
+ // Thrown errors exit with ERROR_CODE and the message verbatim; usage errors exit with USAGE_CODE.
47
48
  export default async function cli(argv, name) {
48
49
  // A closed pipe reader's EPIPE arrives async, after the write loop returns: console.log absorbs it, process.stdout.write (streaming formats) does not, so an unhandled listener kills the process.
49
50
  // A throw here is uncaught (async); process.exit() would skip `sense watch`'s cleanup, leaving a heartbeat behind that makes a dead watcher look alive.
50
51
  process.stdout.on('error', (err)=>{
51
52
  if (err.code === 'EPIPE') return;
52
53
  console.error(`sense: ${err.message}`);
53
- process.exitCode = 1;
54
+ process.exitCode = ERROR_CODE;
54
55
  });
55
56
  const first = argv[0];
56
57
  // No command word, or the first token looks like a flag: the only flags this level knows.
@@ -83,7 +84,7 @@ export default async function cli(argv, name) {
83
84
  } catch (err) {
84
85
  console.error(err.message);
85
86
  console.error(usage(name));
86
- process.exit(2);
87
+ process.exit(USAGE_CODE);
87
88
  }
88
89
  try {
89
90
  if (values.version) {
@@ -105,12 +106,12 @@ export default async function cli(argv, name) {
105
106
  }
106
107
  } catch (err) {
107
108
  console.error(err.message);
108
- process.exit(1);
109
+ process.exit(ERROR_CODE);
109
110
  }
110
111
  console.error(usage(name));
111
- process.exit(2);
112
+ process.exit(USAGE_CODE);
112
113
  }
113
- // Breaking renames get one release of a pointer instead of an "unknown" error: find ->
114
+ // Renamed verbs get a pointer to their current name instead of the unknown-entry error: find ->
114
115
  // search, and query -> sql (which took its name back from the search sense of "query").
115
116
  const RENAMED = {
116
117
  find: 'search',
@@ -119,7 +120,7 @@ export default async function cli(argv, name) {
119
120
  if (RENAMED[first]) {
120
121
  console.error(`${name}: ${first} is now ${RENAMED[first]}`);
121
122
  console.error(usage(name));
122
- process.exit(2);
123
+ process.exit(USAGE_CODE);
123
124
  }
124
125
  const ctx = {
125
126
  name,
@@ -127,7 +128,7 @@ export default async function cli(argv, name) {
127
128
  resolveConfig: (configPath, options)=>resolveConfigFor(name, configPath, options),
128
129
  usageError (message) {
129
130
  console.error(message);
130
- process.exit(2);
131
+ process.exit(USAGE_CODE);
131
132
  }
132
133
  };
133
134
  try {
@@ -136,6 +137,6 @@ export default async function cli(argv, name) {
136
137
  else await (await import('./cli/named.js')).default(ctx, first);
137
138
  } catch (err) {
138
139
  console.error(err.message);
139
- process.exit(1);
140
+ process.exit(ERROR_CODE);
140
141
  }
141
142
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { parseArgs } from 'node:util';\nimport { COMMANDS, USAGE } from './cli/index.ts';\nimport type { Ctx } from './cli/types.ts';\nimport type { LoadConfigOptions } from './config/index.ts';\nimport { loadConfig, SUPPORTED_CONFIG_VERSION } from './config/index.ts';\n\n// Parsing and dispatch only; commands lazy-load from src/cli/, so nothing heavy is imported\n// here. Flags parse per command -- this file handles only --version/--help/--list/--config.\n\n// Works from dist/cjs and dist/esm alike: walk up past the dist type-marker package.json.\nfunction packageVersion(): string {\n const load = createRequire(import.meta.url);\n for (const rel of ['../package.json', '../../package.json', '../../../package.json']) {\n try {\n const pkg = load(rel) as { name?: string; version?: string };\n if (pkg.name === 'sensemaking' && pkg.version) return pkg.version;\n } catch {}\n }\n return 'unknown';\n}\n\nfunction usage(name: string): string {\n const lines = Object.values(USAGE).map((u) => ` ${name} ${u}`);\n return [`usage: ${name} <name> [params...] [--format table|json|csv] [--config path]`, ...lines, ` ${name} --list`, ` ${name} --version`].join('\\n');\n}\n\nfunction resolveConfigFor(name: string, configPath: string | undefined, options: LoadConfigOptions & { query?: boolean } = {}) {\n // Read the query policy before allowing a migration to write configuration state.\n let cfg = loadConfig(configPath, options.query ? { writeMigration: false } : options);\n const writeMigration = options.writeMigration !== false && (!options.query || cfg.build !== false);\n if (options.query && writeMigration && cfg.migratedFrom !== undefined) cfg = loadConfig(configPath);\n if (cfg.migratedFrom !== undefined) {\n console.warn(\n !writeMigration\n ? `${name}: ${cfg.configPath} needs migration from config version ${cfg.migratedFrom} to ${SUPPORTED_CONFIG_VERSION}; using the migrated form in memory only (run ${name} build to update the file)`\n : `${name}: migrated ${cfg.configPath} from config version ${cfg.migratedFrom} to ${SUPPORTED_CONFIG_VERSION}`\n );\n }\n if (cfg.unknownKeys !== undefined) {\n console.warn(`${name}: ${cfg.configPath} sets ${cfg.unknownKeys.join(', ')}, which this build does not read (no effect); see schema.json for the keys it does`);\n }\n return cfg;\n}\n\n// Thrown errors -> exit 1 with the message verbatim; usage errors exit 2 directly.\nexport default async function cli(argv: string[], name: string): Promise<void> {\n // A closed pipe reader's EPIPE arrives async, after the write loop returns: console.log absorbs it, process.stdout.write (streaming formats) does not, so an unhandled listener kills the process.\n // A throw here is uncaught (async); process.exit() would skip `sense watch`'s cleanup, leaving a heartbeat behind that makes a dead watcher look alive.\n process.stdout.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EPIPE') return;\n console.error(`sense: ${err.message}`);\n process.exitCode = 1;\n });\n\n const first = argv[0];\n\n // No command word, or the first token looks like a flag: the only flags this level knows.\n if (!first || first.startsWith('-')) {\n let values: Record<string, string | boolean | undefined>;\n try {\n ({ values } = parseArgs({\n args: argv,\n options: {\n version: { type: 'boolean', default: false, short: 'v' },\n help: { type: 'boolean', default: false, short: 'h' },\n list: { type: 'boolean', default: false },\n config: { type: 'string' },\n },\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage(name));\n process.exit(2);\n }\n\n try {\n if (values.version) {\n console.log(packageVersion());\n return;\n }\n if (values.help) {\n console.log(usage(name));\n return;\n }\n if (values.list) {\n const queries = resolveConfigFor(name, values.config as string | undefined).queries;\n for (const queryName of Object.keys(queries).sort()) {\n // Every entry names its verb, so --list can label both kinds rather than only\n // marking the exception.\n console.log(`${queryName} (${'search' in queries[queryName] ? 'search' : 'sql'})`);\n }\n return;\n }\n } catch (err) {\n console.error((err as Error).message);\n process.exit(1);\n }\n\n console.error(usage(name));\n process.exit(2);\n }\n\n // Breaking renames get one release of a pointer instead of an \"unknown\" error: find ->\n // search, and query -> sql (which took its name back from the search sense of \"query\").\n const RENAMED: Record<string, string> = { find: 'search', query: 'sql' };\n if (RENAMED[first]) {\n console.error(`${name}: ${first} is now ${RENAMED[first]}`);\n console.error(usage(name));\n process.exit(2);\n }\n\n const ctx: Ctx = {\n name,\n argv: argv.slice(1),\n resolveConfig: (configPath, options) => resolveConfigFor(name, configPath, options),\n usageError(message) {\n console.error(message);\n process.exit(2);\n },\n };\n\n try {\n const load = COMMANDS[first];\n if (load) await (await load()).default(ctx);\n else await (await import('./cli/named.ts')).default(ctx, first);\n } catch (err) {\n console.error((err as Error).message);\n process.exit(1);\n }\n}\n"],"names":["createRequire","parseArgs","COMMANDS","USAGE","loadConfig","SUPPORTED_CONFIG_VERSION","packageVersion","load","url","rel","pkg","name","version","usage","lines","Object","values","map","u","join","resolveConfigFor","configPath","options","cfg","query","writeMigration","build","migratedFrom","undefined","console","warn","unknownKeys","cli","argv","process","stdout","on","err","code","error","message","exitCode","first","startsWith","args","type","default","short","help","list","config","allowPositionals","exit","log","queries","queryName","keys","sort","RENAMED","find","ctx","slice","resolveConfig","usageError"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/cli.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { parseArgs } from 'node:util';\nimport { ERROR_CODE, USAGE_CODE } from './cli/constants.ts';\nimport { COMMANDS, USAGE } from './cli/index.ts';\nimport type { Ctx } from './cli/types.ts';\nimport type { LoadConfigOptions } from './config/index.ts';\nimport { loadConfig, SUPPORTED_CONFIG_VERSION } from './config/index.ts';\n\n// Parsing and dispatch only; commands lazy-load from src/cli/, so nothing heavy is imported\n// here. Flags parse per command -- this file handles only --version/--help/--list/--config.\n\n// Works from dist/cjs and dist/esm alike: walk up past the dist type-marker package.json.\nfunction packageVersion(): string {\n const load = createRequire(import.meta.url);\n for (const rel of ['../package.json', '../../package.json', '../../../package.json']) {\n try {\n const pkg = load(rel) as { name?: string; version?: string };\n if (pkg.name === 'sensemaking' && pkg.version) return pkg.version;\n } catch {}\n }\n return 'unknown';\n}\n\nfunction usage(name: string): string {\n const lines = Object.values(USAGE).map((u) => ` ${name} ${u}`);\n return [`usage: ${name} <name> [params...] [--format table|json|csv] [--config path]`, ...lines, ` ${name} --list`, ` ${name} --version`].join('\\n');\n}\n\nfunction resolveConfigFor(name: string, configPath: string | undefined, options: LoadConfigOptions & { query?: boolean } = {}) {\n // Read the query policy before allowing a migration to write configuration state.\n let cfg = loadConfig(configPath, options.query ? { writeMigration: false } : options);\n const writeMigration = options.writeMigration !== false && (!options.query || cfg.build !== false);\n if (options.query && writeMigration && cfg.migratedFrom !== undefined) cfg = loadConfig(configPath);\n if (cfg.migratedFrom !== undefined) {\n console.warn(\n !writeMigration\n ? `${name}: ${cfg.configPath} needs migration from config version ${cfg.migratedFrom} to ${SUPPORTED_CONFIG_VERSION}; using the migrated form in memory only (run ${name} build to update the file)`\n : `${name}: migrated ${cfg.configPath} from config version ${cfg.migratedFrom} to ${SUPPORTED_CONFIG_VERSION}`\n );\n }\n if (cfg.unknownKeys !== undefined) {\n console.warn(`${name}: ${cfg.configPath} sets ${cfg.unknownKeys.join(', ')}, which this build does not read (no effect); see schema.json for the keys it does`);\n }\n return cfg;\n}\n\n// Thrown errors exit with ERROR_CODE and the message verbatim; usage errors exit with USAGE_CODE.\nexport default async function cli(argv: string[], name: string): Promise<void> {\n // A closed pipe reader's EPIPE arrives async, after the write loop returns: console.log absorbs it, process.stdout.write (streaming formats) does not, so an unhandled listener kills the process.\n // A throw here is uncaught (async); process.exit() would skip `sense watch`'s cleanup, leaving a heartbeat behind that makes a dead watcher look alive.\n process.stdout.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EPIPE') return;\n console.error(`sense: ${err.message}`);\n process.exitCode = ERROR_CODE;\n });\n\n const first = argv[0];\n\n // No command word, or the first token looks like a flag: the only flags this level knows.\n if (!first || first.startsWith('-')) {\n let values: Record<string, string | boolean | undefined>;\n try {\n ({ values } = parseArgs({\n args: argv,\n options: {\n version: { type: 'boolean', default: false, short: 'v' },\n help: { type: 'boolean', default: false, short: 'h' },\n list: { type: 'boolean', default: false },\n config: { type: 'string' },\n },\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage(name));\n process.exit(USAGE_CODE);\n }\n\n try {\n if (values.version) {\n console.log(packageVersion());\n return;\n }\n if (values.help) {\n console.log(usage(name));\n return;\n }\n if (values.list) {\n const queries = resolveConfigFor(name, values.config as string | undefined).queries;\n for (const queryName of Object.keys(queries).sort()) {\n // Every entry names its verb, so --list can label both kinds rather than only\n // marking the exception.\n console.log(`${queryName} (${'search' in queries[queryName] ? 'search' : 'sql'})`);\n }\n return;\n }\n } catch (err) {\n console.error((err as Error).message);\n process.exit(ERROR_CODE);\n }\n\n console.error(usage(name));\n process.exit(USAGE_CODE);\n }\n\n // Renamed verbs get a pointer to their current name instead of the unknown-entry error: find ->\n // search, and query -> sql (which took its name back from the search sense of \"query\").\n const RENAMED: Record<string, string> = { find: 'search', query: 'sql' };\n if (RENAMED[first]) {\n console.error(`${name}: ${first} is now ${RENAMED[first]}`);\n console.error(usage(name));\n process.exit(USAGE_CODE);\n }\n\n const ctx: Ctx = {\n name,\n argv: argv.slice(1),\n resolveConfig: (configPath, options) => resolveConfigFor(name, configPath, options),\n usageError(message) {\n console.error(message);\n process.exit(USAGE_CODE);\n },\n };\n\n try {\n const load = COMMANDS[first];\n if (load) await (await load()).default(ctx);\n else await (await import('./cli/named.ts')).default(ctx, first);\n } catch (err) {\n console.error((err as Error).message);\n process.exit(ERROR_CODE);\n }\n}\n"],"names":["createRequire","parseArgs","ERROR_CODE","USAGE_CODE","COMMANDS","USAGE","loadConfig","SUPPORTED_CONFIG_VERSION","packageVersion","load","url","rel","pkg","name","version","usage","lines","Object","values","map","u","join","resolveConfigFor","configPath","options","cfg","query","writeMigration","build","migratedFrom","undefined","console","warn","unknownKeys","cli","argv","process","stdout","on","err","code","error","message","exitCode","first","startsWith","args","type","default","short","help","list","config","allowPositionals","exit","log","queries","queryName","keys","sort","RENAMED","find","ctx","slice","resolveConfig","usageError"],"mappings":"AAAA,SAASA,aAAa,QAAQ,cAAc;AAC5C,SAASC,SAAS,QAAQ,YAAY;AACtC,SAASC,UAAU,EAAEC,UAAU,QAAQ,qBAAqB;AAC5D,SAASC,QAAQ,EAAEC,KAAK,QAAQ,iBAAiB;AAGjD,SAASC,UAAU,EAAEC,wBAAwB,QAAQ,oBAAoB;AAEzE,4FAA4F;AAC5F,4FAA4F;AAE5F,0FAA0F;AAC1F,SAASC;IACP,MAAMC,OAAOT,cAAc,YAAYU,GAAG;IAC1C,KAAK,MAAMC,OAAO;QAAC;QAAmB;QAAsB;KAAwB,CAAE;QACpF,IAAI;YACF,MAAMC,MAAMH,KAAKE;YACjB,IAAIC,IAAIC,IAAI,KAAK,iBAAiBD,IAAIE,OAAO,EAAE,OAAOF,IAAIE,OAAO;QACnE,EAAE,OAAM,CAAC;IACX;IACA,OAAO;AACT;AAEA,SAASC,MAAMF,IAAY;IACzB,MAAMG,QAAQC,OAAOC,MAAM,CAACb,OAAOc,GAAG,CAAC,CAACC,IAAM,CAAC,OAAO,EAAEP,KAAK,CAAC,EAAEO,GAAG;IACnE,OAAO;QAAC,CAAC,OAAO,EAAEP,KAAK,6DAA6D,CAAC;WAAKG;QAAO,CAAC,OAAO,EAAEH,KAAK,OAAO,CAAC;QAAE,CAAC,OAAO,EAAEA,KAAK,UAAU,CAAC;KAAC,CAACQ,IAAI,CAAC;AAC7J;AAEA,SAASC,iBAAiBT,IAAY,EAAEU,UAA8B,EAAEC,UAAmD,CAAC,CAAC;IAC3H,kFAAkF;IAClF,IAAIC,MAAMnB,WAAWiB,YAAYC,QAAQE,KAAK,GAAG;QAAEC,gBAAgB;IAAM,IAAIH;IAC7E,MAAMG,iBAAiBH,QAAQG,cAAc,KAAK,SAAU,CAAA,CAACH,QAAQE,KAAK,IAAID,IAAIG,KAAK,KAAK,KAAI;IAChG,IAAIJ,QAAQE,KAAK,IAAIC,kBAAkBF,IAAII,YAAY,KAAKC,WAAWL,MAAMnB,WAAWiB;IACxF,IAAIE,IAAII,YAAY,KAAKC,WAAW;QAClCC,QAAQC,IAAI,CACV,CAACL,iBACG,GAAGd,KAAK,EAAE,EAAEY,IAAIF,UAAU,CAAC,qCAAqC,EAAEE,IAAII,YAAY,CAAC,IAAI,EAAEtB,yBAAyB,8CAA8C,EAAEM,KAAK,0BAA0B,CAAC,GAClM,GAAGA,KAAK,WAAW,EAAEY,IAAIF,UAAU,CAAC,qBAAqB,EAAEE,IAAII,YAAY,CAAC,IAAI,EAAEtB,0BAA0B;IAEpH;IACA,IAAIkB,IAAIQ,WAAW,KAAKH,WAAW;QACjCC,QAAQC,IAAI,CAAC,GAAGnB,KAAK,EAAE,EAAEY,IAAIF,UAAU,CAAC,MAAM,EAAEE,IAAIQ,WAAW,CAACZ,IAAI,CAAC,MAAM,kFAAkF,CAAC;IAChK;IACA,OAAOI;AACT;AAEA,kGAAkG;AAClG,eAAe,eAAeS,IAAIC,IAAc,EAAEtB,IAAY;IAC5D,mMAAmM;IACnM,wJAAwJ;IACxJuB,QAAQC,MAAM,CAACC,EAAE,CAAC,SAAS,CAACC;QAC1B,IAAIA,IAAIC,IAAI,KAAK,SAAS;QAC1BT,QAAQU,KAAK,CAAC,CAAC,OAAO,EAAEF,IAAIG,OAAO,EAAE;QACrCN,QAAQO,QAAQ,GAAGzC;IACrB;IAEA,MAAM0C,QAAQT,IAAI,CAAC,EAAE;IAErB,0FAA0F;IAC1F,IAAI,CAACS,SAASA,MAAMC,UAAU,CAAC,MAAM;QACnC,IAAI3B;QACJ,IAAI;YACD,CAAA,EAAEA,MAAM,EAAE,GAAGjB,UAAU;gBACtB6C,MAAMX;gBACNX,SAAS;oBACPV,SAAS;wBAAEiC,MAAM;wBAAWC,SAAS;wBAAOC,OAAO;oBAAI;oBACvDC,MAAM;wBAAEH,MAAM;wBAAWC,SAAS;wBAAOC,OAAO;oBAAI;oBACpDE,MAAM;wBAAEJ,MAAM;wBAAWC,SAAS;oBAAM;oBACxCI,QAAQ;wBAAEL,MAAM;oBAAS;gBAC3B;gBACAM,kBAAkB;YACpB,EAAC;QACH,EAAE,OAAOd,KAAK;YACZR,QAAQU,KAAK,CAAC,AAACF,IAAcG,OAAO;YACpCX,QAAQU,KAAK,CAAC1B,MAAMF;YACpBuB,QAAQkB,IAAI,CAACnD;QACf;QAEA,IAAI;YACF,IAAIe,OAAOJ,OAAO,EAAE;gBAClBiB,QAAQwB,GAAG,CAAC/C;gBACZ;YACF;YACA,IAAIU,OAAOgC,IAAI,EAAE;gBACfnB,QAAQwB,GAAG,CAACxC,MAAMF;gBAClB;YACF;YACA,IAAIK,OAAOiC,IAAI,EAAE;gBACf,MAAMK,UAAUlC,iBAAiBT,MAAMK,OAAOkC,MAAM,EAAwBI,OAAO;gBACnF,KAAK,MAAMC,aAAaxC,OAAOyC,IAAI,CAACF,SAASG,IAAI,GAAI;oBACnD,8EAA8E;oBAC9E,yBAAyB;oBACzB5B,QAAQwB,GAAG,CAAC,GAAGE,UAAU,GAAG,EAAE,YAAYD,OAAO,CAACC,UAAU,GAAG,WAAW,MAAM,CAAC,CAAC;gBACpF;gBACA;YACF;QACF,EAAE,OAAOlB,KAAK;YACZR,QAAQU,KAAK,CAAC,AAACF,IAAcG,OAAO;YACpCN,QAAQkB,IAAI,CAACpD;QACf;QAEA6B,QAAQU,KAAK,CAAC1B,MAAMF;QACpBuB,QAAQkB,IAAI,CAACnD;IACf;IAEA,gGAAgG;IAChG,wFAAwF;IACxF,MAAMyD,UAAkC;QAAEC,MAAM;QAAUnC,OAAO;IAAM;IACvE,IAAIkC,OAAO,CAAChB,MAAM,EAAE;QAClBb,QAAQU,KAAK,CAAC,GAAG5B,KAAK,EAAE,EAAE+B,MAAM,QAAQ,EAAEgB,OAAO,CAAChB,MAAM,EAAE;QAC1Db,QAAQU,KAAK,CAAC1B,MAAMF;QACpBuB,QAAQkB,IAAI,CAACnD;IACf;IAEA,MAAM2D,MAAW;QACfjD;QACAsB,MAAMA,KAAK4B,KAAK,CAAC;QACjBC,eAAe,CAACzC,YAAYC,UAAYF,iBAAiBT,MAAMU,YAAYC;QAC3EyC,YAAWvB,OAAO;YAChBX,QAAQU,KAAK,CAACC;YACdN,QAAQkB,IAAI,CAACnD;QACf;IACF;IAEA,IAAI;QACF,MAAMM,OAAOL,QAAQ,CAACwC,MAAM;QAC5B,IAAInC,MAAM,MAAM,AAAC,CAAA,MAAMA,MAAK,EAAGuC,OAAO,CAACc;aAClC,MAAM,AAAC,CAAA,MAAM,MAAM,CAAC,iBAAgB,EAAGd,OAAO,CAACc,KAAKlB;IAC3D,EAAE,OAAOL,KAAK;QACZR,QAAQU,KAAK,CAAC,AAACF,IAAcG,OAAO;QACpCN,QAAQkB,IAAI,CAACpD;IACf;AACF"}
@@ -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, 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":["mapTree","findPath","peek","resolveNote","relatedNotes","scopedPaths","search","presetCoverage"],"mappings":"AAAA,2EAA2E;AAC3E,gFAAgF;AAGhF,SAASA,OAAO,QAAQ,WAAW;AAEnC,SAASC,QAAQ,QAAQ,YAAY;AAErC,SAASC,IAAI,EAAEC,WAAW,QAAQ,YAAY;AAE9C,SAASC,YAAY,QAAQ,eAAe;AAC5C,SAASC,WAAW,QAAQ,aAAa;AAEzC,SAASC,MAAM,QAAQ,cAAc;AAErC,SAASC,cAAc,QAAQ,cAAc"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/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":["mapTree","findPath","peek","resolveNote","relatedNotes","scopedPaths","search","presetCoverage"],"mappings":"AAAA,2EAA2E;AAC3E,gFAAgF;AAGhF,SAASA,OAAO,QAAQ,WAAW;AAEnC,SAASC,QAAQ,QAAQ,YAAY;AAErC,SAASC,IAAI,EAAEC,WAAW,QAAQ,YAAY;AAE9C,SAASC,YAAY,QAAQ,eAAe;AAC5C,SAASC,WAAW,QAAQ,aAAa;AAEzC,SAASC,MAAM,QAAQ,cAAc;AAErC,SAASC,cAAc,QAAQ,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/map.ts"],"sourcesContent":["import type { FeatureName, ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { featureEnabled, featureStates } from '../config/index.ts';\nimport { serialQuery } from '../lib/serial-query.ts';\nimport type { FieldStat, Store } from '../store/types.ts';\nimport { INTERNAL_COLUMNS, scopedPaths, setupMapScope } from './scope.ts';\nimport { assertQuerySnapshot } from './snapshot.ts';\nimport type { PresetCoverage } from './status.ts';\nimport { presetCoverage } from './status.ts';\n\nexport interface TreeMap {\n docs: { count: number; bytes: number };\n fields: TreeMapField[]; // top 20 by coverage; fieldsTotal carries the real count\n fieldsTotal: number;\n features: { on: FeatureName[]; off: FeatureName[] };\n presets: PresetCoverage[];\n hubs: TreeMapHub[];\n recent: TreeMapRecent[];\n recentCaveat: string | null;\n}\n\nexport type TreeMapField = FieldStat;\n\nexport type TreeMapHub = {\n path: string;\n rank: number;\n title: string;\n};\n\nexport type TreeMapRecent = {\n path: string;\n modified: string;\n};\n\n// A result row is capped at SQLITE_MAX_COLUMN (2000, default); two aggregate expressions per\n// field keeps a chunk's row width safely under that regardless of how many fields the tree has.\nconst MAP_COLUMN_CHUNK = 300;\n\n// \"YYYY-MM-DD HH:MM:SS\" UTC, the exact shape sqlite's datetime(ms / 1000, 'unixepoch') prints;\n// formatted in JS so the query stays dialect-free.\nfunction utcSecond(ms: number): string {\n return new Date(ms).toISOString().slice(0, 19).replace('T', ' ');\n}\n\nfunction chunk<T>(items: T[], size: number): T[][] {\n const out: T[][] = [];\n for (let i = 0; i < items.length; i += size) out.push(items.slice(i, i + size));\n return out;\n}\n\n// What is this scope: fixed-size output regardless of tree size. Coverage and features stay\n// global -- they describe the tree, not the current question.\nexport function mapTree(store: Store, cfg: ResolvedConfig, overrides: SearchOverrides = {}): Promise<TreeMap> {\n return serialQuery(store, () => mapIndexed(store, cfg, overrides));\n}\n\nasync function mapIndexed(store: Store, cfg: ResolvedConfig, overrides: SearchOverrides): Promise<TreeMap> {\n return store.transaction(async () => {\n await assertQuerySnapshot(store, cfg);\n await setupMapScope(store, await scopedPaths(store, cfg, overrides));\n const scopeWhere = 'WHERE \"path\" IN (SELECT \"path\" FROM _map_scope)';\n const scopeAnd = 'AND f.\"path\" IN (SELECT \"path\" FROM _map_scope)';\n\n const docs = (await (await store.prepare(`SELECT COUNT(*) AS count, COALESCE(SUM(\"_size\"), 0) AS bytes FROM frontmatter ${scopeWhere}`)).get()) as { count: number; bytes: number };\n\n const columns = (await store.docs.columns()).filter((name) => !INTERNAL_COLUMNS.has(name));\n // Observed types, not declared: a field can be text in most notes and numeric in a few, so\n // every distinct type observed across the scope is reported, not just the first.\n const allFields: FieldStat[] = [];\n for (const group of chunk(columns, MAP_COLUMN_CHUNK)) allFields.push(...(await store.docs.fieldStats(group, scopeWhere)));\n allFields.sort((a, b) => b.coverage - a.coverage);\n const fields = allFields.slice(0, 20);\n\n const hubs = featureEnabled(cfg, 'rank')\n ? ((await (await store.prepare(`SELECT f.\"path\" AS path, round(f.\"_rank\" * 100, 2) AS rank, content.title FROM frontmatter f JOIN content ON content.path = f.\"path\" WHERE f.\"_rank\" IS NOT NULL ${scopeAnd} ORDER BY f.\"_rank\" DESC, f.\"path\" ASC LIMIT 8`)).all()) as TreeMapHub[])\n : [];\n\n const recent = ((await (await store.prepare(`SELECT \"path\", \"_mtime\" AS mtime FROM frontmatter ${scopeWhere} ORDER BY \"_mtime\" DESC, \"path\" ASC LIMIT 5`)).all()) as Array<{ path: string; mtime: number }>).map((r) => ({ path: r.path, modified: utcSecond(r.mtime) }));\n\n // A fresh clone/copy stamps files with checkout time, not edit history; second granularity\n // matches the `recent` table above and is coarse enough to catch that without an exact-ms match.\n const topSecond = (await (await store.prepare(`SELECT COUNT(*) AS n FROM frontmatter ${scopeWhere} GROUP BY CAST(\"_mtime\" / 1000 AS INTEGER) ORDER BY n DESC LIMIT 1`)).get()) as { n: number } | undefined;\n const recentCaveat = topSecond && docs.count > 1 && topSecond.n > docs.count / 2 ? `${topSecond.n} of ${docs.count} files share one modified second, so recency likely reflects a checkout or copy, not edit history` : null;\n\n return { docs, fields, fieldsTotal: allFields.length, features: featureStates(cfg), presets: await presetCoverage(store, cfg), hubs, recent, recentCaveat };\n });\n}\n"],"names":["featureEnabled","featureStates","serialQuery","INTERNAL_COLUMNS","scopedPaths","setupMapScope","assertQuerySnapshot","presetCoverage","MAP_COLUMN_CHUNK","utcSecond","ms","Date","toISOString","slice","replace","chunk","items","size","out","i","length","push","mapTree","store","cfg","overrides","mapIndexed","transaction","scopeWhere","scopeAnd","docs","prepare","get","columns","filter","name","has","allFields","group","fieldStats","sort","a","b","coverage","fields","hubs","all","recent","map","r","path","modified","mtime","topSecond","recentCaveat","count","n","fieldsTotal","features","presets"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/commands/map.ts"],"sourcesContent":["import type { FeatureName, ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { featureEnabled, featureStates } from '../config/index.ts';\nimport { serialQuery } from '../lib/serial-query.ts';\nimport type { FieldStat, Store } from '../store/types.ts';\nimport { INTERNAL_COLUMNS, scopedPaths, setupMapScope } from './scope.ts';\nimport { assertQuerySnapshot } from './snapshot.ts';\nimport type { PresetCoverage } from './status.ts';\nimport { presetCoverage } from './status.ts';\n\nexport interface TreeMap {\n docs: { count: number; bytes: number };\n fields: TreeMapField[]; // top 20 by coverage; fieldsTotal carries the real count\n fieldsTotal: number;\n features: { on: FeatureName[]; off: FeatureName[] };\n presets: PresetCoverage[];\n hubs: TreeMapHub[];\n recent: TreeMapRecent[];\n recentCaveat: string | null;\n}\n\nexport type TreeMapField = FieldStat;\n\nexport type TreeMapHub = {\n path: string;\n rank: number;\n title: string;\n};\n\nexport type TreeMapRecent = {\n path: string;\n modified: string;\n};\n\n// A result row is capped at SQLITE_MAX_COLUMN (2000, default); two aggregate expressions per\n// field keeps a chunk's row width safely under that regardless of how many fields the tree has.\nconst MAP_COLUMN_CHUNK = 300;\n\n// \"YYYY-MM-DD HH:MM:SS\" UTC, the exact shape sqlite's datetime(ms / 1000, 'unixepoch') prints;\n// formatted in JS so the query stays dialect-free.\nfunction utcSecond(ms: number): string {\n return new Date(ms).toISOString().slice(0, 19).replace('T', ' ');\n}\n\nfunction chunk<T>(items: T[], size: number): T[][] {\n const out: T[][] = [];\n for (let i = 0; i < items.length; i += size) out.push(items.slice(i, i + size));\n return out;\n}\n\n// What is this scope: fixed-size output regardless of tree size. Coverage and features stay\n// global -- they describe the tree, not the current question.\nexport function mapTree(store: Store, cfg: ResolvedConfig, overrides: SearchOverrides = {}): Promise<TreeMap> {\n return serialQuery(store, () => mapIndexed(store, cfg, overrides));\n}\n\nasync function mapIndexed(store: Store, cfg: ResolvedConfig, overrides: SearchOverrides): Promise<TreeMap> {\n return store.transaction(async () => {\n await assertQuerySnapshot(store, cfg);\n await setupMapScope(store, await scopedPaths(store, cfg, overrides));\n const scopeWhere = 'WHERE \"path\" IN (SELECT \"path\" FROM _map_scope)';\n const scopeAnd = 'AND f.\"path\" IN (SELECT \"path\" FROM _map_scope)';\n\n const docs = (await (await store.prepare(`SELECT COUNT(*) AS count, COALESCE(SUM(\"_size\"), 0) AS bytes FROM frontmatter ${scopeWhere}`)).get()) as { count: number; bytes: number };\n\n const columns = (await store.docs.columns()).filter((name) => !INTERNAL_COLUMNS.has(name));\n // Observed types, not declared: a field can be text in most notes and numeric in a few, so\n // every distinct type observed across the scope is reported, not just the first.\n const allFields: FieldStat[] = [];\n for (const group of chunk(columns, MAP_COLUMN_CHUNK)) allFields.push(...(await store.docs.fieldStats(group, scopeWhere)));\n allFields.sort((a, b) => b.coverage - a.coverage);\n const fields = allFields.slice(0, 20);\n\n const hubs = featureEnabled(cfg, 'rank')\n ? ((await (await store.prepare(`SELECT f.\"path\" AS path, round(f.\"_rank\" * 100, 2) AS rank, content.title FROM frontmatter f JOIN content ON content.path = f.\"path\" WHERE f.\"_rank\" IS NOT NULL ${scopeAnd} ORDER BY f.\"_rank\" DESC, f.\"path\" ASC LIMIT 8`)).all()) as TreeMapHub[])\n : [];\n\n const recent = ((await (await store.prepare(`SELECT \"path\", \"_mtime\" AS mtime FROM frontmatter ${scopeWhere} ORDER BY \"_mtime\" DESC, \"path\" ASC LIMIT 5`)).all()) as Array<{ path: string; mtime: number }>).map((r) => ({ path: r.path, modified: utcSecond(r.mtime) }));\n\n // A fresh clone/copy stamps files with checkout time, not edit history; second granularity\n // matches the `recent` table above and is coarse enough to catch that without an exact-ms match.\n const topSecond = (await (await store.prepare(`SELECT COUNT(*) AS n FROM frontmatter ${scopeWhere} GROUP BY CAST(\"_mtime\" / 1000 AS INTEGER) ORDER BY n DESC LIMIT 1`)).get()) as { n: number } | undefined;\n const recentCaveat = topSecond && docs.count > 1 && topSecond.n > docs.count / 2 ? `${topSecond.n} of ${docs.count} files share one modified second, so recency likely reflects a checkout or copy, not edit history` : null;\n\n return { docs, fields, fieldsTotal: allFields.length, features: featureStates(cfg), presets: await presetCoverage(store, cfg), hubs, recent, recentCaveat };\n });\n}\n"],"names":["featureEnabled","featureStates","serialQuery","INTERNAL_COLUMNS","scopedPaths","setupMapScope","assertQuerySnapshot","presetCoverage","MAP_COLUMN_CHUNK","utcSecond","ms","Date","toISOString","slice","replace","chunk","items","size","out","i","length","push","mapTree","store","cfg","overrides","mapIndexed","transaction","scopeWhere","scopeAnd","docs","prepare","get","columns","filter","name","has","allFields","group","fieldStats","sort","a","b","coverage","fields","hubs","all","recent","map","r","path","modified","mtime","topSecond","recentCaveat","count","n","fieldsTotal","features","presets"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/path.ts"],"sourcesContent":["import type { ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { resolveSearch } from '../config/index.ts';\nimport { SenseError } from '../errors.ts';\nimport { findPathInSnapshot } from '../graph/traverse.ts';\nimport { serialQuery } from '../lib/serial-query.ts';\nimport type { Store } from '../store/types.ts';\nimport { resolveNote } from './peek.ts';\nimport { scopedPaths } from './scope.ts';\nimport { assertQuerySnapshot } from './snapshot.ts';\n\n/**\n * Options for {@link findPath}. Scope fields constrain intermediate nodes; `maxDepth` limits the\n * number of traversed links and must be a positive integer when supplied.\n */\nexport type PathOptions = Omit<SearchOverrides, 'k'> & {\n maxDepth?: number;\n};\n\n/**\n * Finds the shortest undirected link path between two indexed notes. Endpoints resolve across\n * the indexed tree and remain permitted outside the scope applied to intermediate nodes.\n */\nexport function findPath(store: Store, cfg: ResolvedConfig, fromArg: string, toArg: string, options: PathOptions = {}): Promise<string[] | null> {\n return serialQuery(store, () => findScopedPath(store, cfg, fromArg, toArg, options));\n}\n\nasync function findScopedPath(store: Store, cfg: ResolvedConfig, fromArg: string, toArg: string, options: PathOptions): Promise<string[] | null> {\n if (options.maxDepth !== undefined && (!Number.isFinite(options.maxDepth) || !Number.isInteger(options.maxDepth) || options.maxDepth <= 0)) {\n throw new SenseError('SEARCH_OPTION_INVALID', `path option \"maxDepth\" must be a positive finite integer, got ${String(options.maxDepth)}`);\n }\n // Validate the named preset before opening the snapshot; repeat it inside because preset_files\n // and the compatibility assertion below belong to the final published generation.\n resolveSearch(cfg, options);\n return store.transaction(async () => {\n await assertQuerySnapshot(store, cfg);\n resolveSearch(cfg, options);\n const paths = ((await (await store.prepare('SELECT \"path\" FROM frontmatter')).all()) as Array<{ path: string }>).map((row) => row.path);\n const from = resolveNote(paths, fromArg);\n const to = resolveNote(paths, toArg);\n const allowed = await scopedPaths(store, cfg, options);\n return findPathInSnapshot(store, from, to, { maxDepth: options.maxDepth, allowed });\n });\n}\n"],"names":["resolveSearch","SenseError","findPathInSnapshot","serialQuery","resolveNote","scopedPaths","assertQuerySnapshot","findPath","store","cfg","fromArg","toArg","options","findScopedPath","maxDepth","undefined","Number","isFinite","isInteger","String","transaction","paths","prepare","all","map","row","path","from","to","allowed"],"mappings":"AACA,SAASA,aAAa,QAAQ,qBAAqB;AACnD,SAASC,UAAU,QAAQ,eAAe;AAC1C,SAASC,kBAAkB,QAAQ,uBAAuB;AAC1D,SAASC,WAAW,QAAQ,yBAAyB;AAErD,SAASC,WAAW,QAAQ,YAAY;AACxC,SAASC,WAAW,QAAQ,aAAa;AACzC,SAASC,mBAAmB,QAAQ,gBAAgB;AAUpD;;;CAGC,GACD,OAAO,SAASC,SAASC,KAAY,EAAEC,GAAmB,EAAEC,OAAe,EAAEC,KAAa,EAAEC,UAAuB,CAAC,CAAC;IACnH,OAAOT,YAAYK,OAAO,IAAMK,eAAeL,OAAOC,KAAKC,SAASC,OAAOC;AAC7E;AAEA,eAAeC,eAAeL,KAAY,EAAEC,GAAmB,EAAEC,OAAe,EAAEC,KAAa,EAAEC,OAAoB;IACnH,IAAIA,QAAQE,QAAQ,KAAKC,aAAc,CAAA,CAACC,OAAOC,QAAQ,CAACL,QAAQE,QAAQ,KAAK,CAACE,OAAOE,SAAS,CAACN,QAAQE,QAAQ,KAAKF,QAAQE,QAAQ,IAAI,CAAA,GAAI;QAC1I,MAAM,IAAIb,WAAW,yBAAyB,CAAC,8DAA8D,EAAEkB,OAAOP,QAAQE,QAAQ,GAAG;IAC3I;IACA,+FAA+F;IAC/F,kFAAkF;IAClFd,cAAcS,KAAKG;IACnB,OAAOJ,MAAMY,WAAW,CAAC;QACvB,MAAMd,oBAAoBE,OAAOC;QACjCT,cAAcS,KAAKG;QACnB,MAAMS,QAAQ,AAAE,CAAA,MAAM,AAAC,CAAA,MAAMb,MAAMc,OAAO,CAAC,iCAAgC,EAAGC,GAAG,EAAC,EAA+BC,GAAG,CAAC,CAACC,MAAQA,IAAIC,IAAI;QACtI,MAAMC,OAAOvB,YAAYiB,OAAOX;QAChC,MAAMkB,KAAKxB,YAAYiB,OAAOV;QAC9B,MAAMkB,UAAU,MAAMxB,YAAYG,OAAOC,KAAKG;QAC9C,OAAOV,mBAAmBM,OAAOmB,MAAMC,IAAI;YAAEd,UAAUF,QAAQE,QAAQ;YAAEe;QAAQ;IACnF;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/commands/path.ts"],"sourcesContent":["import type { ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { resolveSearch } from '../config/index.ts';\nimport { SenseError } from '../errors.ts';\nimport { findPathInSnapshot } from '../graph/traverse.ts';\nimport { serialQuery } from '../lib/serial-query.ts';\nimport type { Store } from '../store/types.ts';\nimport { resolveNote } from './peek.ts';\nimport { scopedPaths } from './scope.ts';\nimport { assertQuerySnapshot } from './snapshot.ts';\n\n/**\n * Options for {@link findPath}. Scope fields constrain intermediate nodes; `maxDepth` limits the\n * number of traversed links and must be a positive integer when supplied.\n */\nexport type PathOptions = Omit<SearchOverrides, 'k'> & {\n maxDepth?: number;\n};\n\n/**\n * Finds the shortest undirected link path between two indexed notes. Endpoints resolve across\n * the indexed tree and remain permitted outside the scope applied to intermediate nodes.\n */\nexport function findPath(store: Store, cfg: ResolvedConfig, fromArg: string, toArg: string, options: PathOptions = {}): Promise<string[] | null> {\n return serialQuery(store, () => findScopedPath(store, cfg, fromArg, toArg, options));\n}\n\nasync function findScopedPath(store: Store, cfg: ResolvedConfig, fromArg: string, toArg: string, options: PathOptions): Promise<string[] | null> {\n if (options.maxDepth !== undefined && (!Number.isFinite(options.maxDepth) || !Number.isInteger(options.maxDepth) || options.maxDepth <= 0)) {\n throw new SenseError('SEARCH_OPTION_INVALID', `path option \"maxDepth\" must be a positive finite integer, got ${String(options.maxDepth)}`);\n }\n // Validate the named preset before opening the snapshot; repeat it inside because preset_files\n // and the compatibility assertion below belong to the final published generation.\n resolveSearch(cfg, options);\n return store.transaction(async () => {\n await assertQuerySnapshot(store, cfg);\n resolveSearch(cfg, options);\n const paths = ((await (await store.prepare('SELECT \"path\" FROM frontmatter')).all()) as Array<{ path: string }>).map((row) => row.path);\n const from = resolveNote(paths, fromArg);\n const to = resolveNote(paths, toArg);\n const allowed = await scopedPaths(store, cfg, options);\n return findPathInSnapshot(store, from, to, { maxDepth: options.maxDepth, allowed });\n });\n}\n"],"names":["resolveSearch","SenseError","findPathInSnapshot","serialQuery","resolveNote","scopedPaths","assertQuerySnapshot","findPath","store","cfg","fromArg","toArg","options","findScopedPath","maxDepth","undefined","Number","isFinite","isInteger","String","transaction","paths","prepare","all","map","row","path","from","to","allowed"],"mappings":"AACA,SAASA,aAAa,QAAQ,qBAAqB;AACnD,SAASC,UAAU,QAAQ,eAAe;AAC1C,SAASC,kBAAkB,QAAQ,uBAAuB;AAC1D,SAASC,WAAW,QAAQ,yBAAyB;AAErD,SAASC,WAAW,QAAQ,YAAY;AACxC,SAASC,WAAW,QAAQ,aAAa;AACzC,SAASC,mBAAmB,QAAQ,gBAAgB;AAUpD;;;CAGC,GACD,OAAO,SAASC,SAASC,KAAY,EAAEC,GAAmB,EAAEC,OAAe,EAAEC,KAAa,EAAEC,UAAuB,CAAC,CAAC;IACnH,OAAOT,YAAYK,OAAO,IAAMK,eAAeL,OAAOC,KAAKC,SAASC,OAAOC;AAC7E;AAEA,eAAeC,eAAeL,KAAY,EAAEC,GAAmB,EAAEC,OAAe,EAAEC,KAAa,EAAEC,OAAoB;IACnH,IAAIA,QAAQE,QAAQ,KAAKC,aAAc,CAAA,CAACC,OAAOC,QAAQ,CAACL,QAAQE,QAAQ,KAAK,CAACE,OAAOE,SAAS,CAACN,QAAQE,QAAQ,KAAKF,QAAQE,QAAQ,IAAI,CAAA,GAAI;QAC1I,MAAM,IAAIb,WAAW,yBAAyB,CAAC,8DAA8D,EAAEkB,OAAOP,QAAQE,QAAQ,GAAG;IAC3I;IACA,+FAA+F;IAC/F,kFAAkF;IAClFd,cAAcS,KAAKG;IACnB,OAAOJ,MAAMY,WAAW,CAAC;QACvB,MAAMd,oBAAoBE,OAAOC;QACjCT,cAAcS,KAAKG;QACnB,MAAMS,QAAQ,AAAE,CAAA,MAAM,AAAC,CAAA,MAAMb,MAAMc,OAAO,CAAC,iCAAgC,EAAGC,GAAG,EAAC,EAA+BC,GAAG,CAAC,CAACC,MAAQA,IAAIC,IAAI;QACtI,MAAMC,OAAOvB,YAAYiB,OAAOX;QAChC,MAAMkB,KAAKxB,YAAYiB,OAAOV;QAC9B,MAAMkB,UAAU,MAAMxB,YAAYG,OAAOC,KAAKG;QAC9C,OAAOV,mBAAmBM,OAAOmB,MAAMC,IAAI;YAAEd,UAAUF,QAAQE,QAAQ;YAAEe;QAAQ;IACnF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/peek.ts"],"sourcesContent":["import posix from 'node:path/posix';\nimport { estimateTokens } from '../chunk/index.ts';\nimport type { FeatureName, ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { featureEnabled } from '../config/index.ts';\nimport { SenseError } from '../errors.ts';\nimport { serialQuery } from '../lib/serial-query.ts';\nimport type { Row } from '../output/output.ts';\nimport type { Store } from '../store/types.ts';\nimport { INTERNAL_COLUMNS, materializeScope, scopedPaths } from './scope.ts';\nimport { assertQuerySnapshot } from './snapshot.ts';\n\n// Note resolution shared by peek and path: an exact path, or a unique basename (case\n// insensitive, .md stripped).\nexport function resolveNote(paths: string[], arg: string): string {\n const exact = paths.find((p) => p === arg);\n if (exact) return exact;\n const base = posix.basename(arg).replace(/\\.md$/i, '').toLowerCase();\n const matches = paths.filter((p) => posix.basename(p).replace(/\\.md$/i, '').toLowerCase() === base);\n if (matches.length === 1) return matches[0];\n if (matches.length > 1) throw new SenseError('NOTE_AMBIGUOUS', `\"${arg}\" is ambiguous: ${matches.join(', ')}`);\n throw new SenseError('NOTE_NOT_FOUND', `no note matches \"${arg}\"`);\n}\n\n/** Structured, bounded metadata returned by the root {@link peek} API. */\nexport interface Peek {\n path: string;\n tokens: number;\n frontmatter: Row;\n /** Set when frontmatter parsing failed, distinguishing that case from an empty block. */\n parseError: string | null;\n sections: PeekSection[];\n outbound: string[];\n backlinks: string[];\n unresolved: string[];\n /** Totals before each bounded list is truncated. */\n sectionsTotal: number;\n outboundTotal: number;\n backlinksTotal: number;\n unresolvedTotal: number;\n /** Disabled features whose result blocks are omitted rather than returned empty. */\n off: FeatureName[];\n}\n\n/** A section description, with an inclusive source line range and token estimate, not section prose. */\nexport interface PeekSection {\n level: number;\n heading: string;\n start_line: number;\n end_line: number;\n tokens: number;\n}\n\n/** Options for the root {@link peek} API. */\nexport interface PeekOptions extends SearchOverrides {\n /** Maximum section descriptions. Defaults to 20; must be a positive safe integer. */\n sectionCountLimit?: number;\n /** Maximum entries in each link group independently. Defaults to 20; must be a positive safe integer. */\n linkCountLimit?: number;\n}\n\nconst PEEK_COUNT_LIMIT = 20;\n\n/**\n * Returns indexed metadata for a note in scope. Exact excluded paths fail before scoped basename\n * resolution; resolved neighbors stay in scope, while unresolved written targets remain visible.\n */\nexport function peek(store: Store, cfg: ResolvedConfig, pathArg: string, overrides: PeekOptions = {}): Promise<Peek> {\n return serialQuery(store, () => peekIndexed(store, cfg, pathArg, overrides));\n}\n\nasync function peekIndexed(store: Store, cfg: ResolvedConfig, pathArg: string, overrides: PeekOptions): Promise<Peek> {\n for (const name of ['sectionCountLimit', 'linkCountLimit'] as const) {\n const value = overrides[name];\n if (value !== undefined && (!Number.isSafeInteger(value) || value <= 0)) {\n throw new SenseError('SEARCH_OPTION_INVALID', `peek option \"${name}\" must be a positive safe integer, got ${String(value)}`);\n }\n }\n const sectionCountLimit = overrides.sectionCountLimit ?? PEEK_COUNT_LIMIT;\n const linkCountLimit = overrides.linkCountLimit ?? PEEK_COUNT_LIMIT;\n return store.transaction(async () => {\n await assertQuerySnapshot(store, cfg);\n const pathsStmt = await store.prepare('SELECT \"path\" FROM frontmatter');\n const paths = ((await pathsStmt.all()) as Array<{ path: string }>).map((r) => r.path);\n const allowed = await scopedPaths(store, cfg, overrides);\n if (paths.includes(pathArg) && !allowed.has(pathArg)) {\n throw new SenseError('NOTE_NOT_FOUND', `note \"${pathArg}\" exists but is outside the current scope; change the preset, include/exclude patterns, or where condition`);\n }\n let path: string;\n try {\n path = resolveNote([...allowed], pathArg);\n } catch (err) {\n if (err instanceof SenseError && err.code === 'NOTE_NOT_FOUND') {\n let excludedPath: string;\n try {\n excludedPath = resolveNote(paths, pathArg);\n } catch (unscopedErr) {\n if (unscopedErr instanceof SenseError && unscopedErr.code === 'NOTE_AMBIGUOUS') {\n throw new SenseError('NOTE_NOT_FOUND', `no note in the current scope matches \"${pathArg}\"; indexed matches exist outside the scope, so change the preset, include/exclude patterns, or where condition`);\n }\n throw err;\n }\n throw new SenseError('NOTE_NOT_FOUND', `note \"${excludedPath}\" exists but is outside the current scope; change the preset, include/exclude patterns, or where condition`);\n }\n throw err;\n }\n\n const rowStmt = await store.prepare('SELECT * FROM frontmatter WHERE \"path\" = ?');\n const row = (await rowStmt.get(path)) as Row;\n const parseError = (row._parse_error as string | null) ?? null;\n const frontmatter: Row = {};\n for (const [key, value] of Object.entries(row)) {\n if (!INTERNAL_COLUMNS.has(key) && value !== null) frontmatter[key] = value;\n }\n\n let sectionsTotal = 0;\n let sections: PeekSection[] = [];\n if (featureEnabled(cfg, 'sections')) {\n sectionsTotal = ((await (await store.prepare('SELECT COUNT(*) AS n FROM sections WHERE \"path\" = ?')).get(path)) as { n: number }).n;\n sections = (await (await store.prepare('SELECT level, heading, start_line, end_line, tokens FROM sections WHERE \"path\" = ? ORDER BY idx LIMIT ?')).all(path, sectionCountLimit)) as PeekSection[];\n }\n\n let outbound: string[] = [];\n let backlinks: string[] = [];\n let unresolved: string[] = [];\n let outboundTotal = 0;\n let backlinksTotal = 0;\n let unresolvedTotal = 0;\n if (featureEnabled(cfg, 'links')) {\n await materializeScope(store, '_peek_scope', allowed);\n outboundTotal = ((await (await store.prepare('SELECT COUNT(DISTINCT dst) AS n FROM links WHERE src = ? AND dst != src AND dst IN (SELECT \"path\" FROM _peek_scope)')).get(path)) as { n: number }).n;\n // The first written target determines each resolved destination's position.\n outbound = ((await (await store.prepare('SELECT dst FROM links WHERE src = ? AND dst != src AND dst IN (SELECT \"path\" FROM _peek_scope) GROUP BY dst ORDER BY MIN(target) LIMIT ?')).all(path, linkCountLimit)) as Array<{ dst: string }>).map((r) => r.dst);\n unresolvedTotal = ((await (await store.prepare('SELECT COUNT(*) AS n FROM links WHERE src = ? AND dst IS NULL')).get(path)) as { n: number }).n;\n unresolved = ((await (await store.prepare('SELECT target FROM links WHERE src = ? AND dst IS NULL ORDER BY target LIMIT ?')).all(path, linkCountLimit)) as Array<{ target: string }>).map((r) => r.target);\n backlinksTotal = ((await (await store.prepare('SELECT COUNT(DISTINCT src) AS n FROM links WHERE dst = ? AND src != dst AND src IN (SELECT \"path\" FROM _peek_scope)')).get(path)) as { n: number }).n;\n backlinks = ((await (await store.prepare('SELECT DISTINCT src FROM links WHERE dst = ? AND src != dst AND src IN (SELECT \"path\" FROM _peek_scope) ORDER BY src LIMIT ?')).all(path, linkCountLimit)) as Array<{ src: string }>).map((r) => r.src);\n }\n\n // content.text is the stripped body already computed at reconcile time (no extra file read),\n // floored by the byte/4 estimate so stripped-away syntax and frontmatter can't vanish from the price.\n const body = ((await (await store.prepare('SELECT text FROM content WHERE \"path\" = ?')).get(path)) as { text: string } | undefined)?.text;\n const byteTokens = Math.ceil(((row._size as number) ?? 0) / 4);\n const tokens = body !== undefined ? Math.max(Math.ceil(estimateTokens(body)), byteTokens) : byteTokens;\n\n return {\n path,\n tokens,\n frontmatter,\n parseError,\n sections,\n outbound,\n backlinks,\n unresolved,\n sectionsTotal,\n outboundTotal,\n backlinksTotal,\n unresolvedTotal,\n off: (['sections', 'links'] as FeatureName[]).filter((name) => !featureEnabled(cfg, name)),\n };\n });\n}\n"],"names":["posix","estimateTokens","featureEnabled","SenseError","serialQuery","INTERNAL_COLUMNS","materializeScope","scopedPaths","assertQuerySnapshot","resolveNote","paths","arg","exact","find","p","base","basename","replace","toLowerCase","matches","filter","length","join","PEEK_COUNT_LIMIT","peek","store","cfg","pathArg","overrides","peekIndexed","name","value","undefined","Number","isSafeInteger","String","sectionCountLimit","linkCountLimit","transaction","row","pathsStmt","prepare","all","map","r","path","allowed","includes","has","err","code","excludedPath","unscopedErr","rowStmt","get","parseError","_parse_error","frontmatter","key","Object","entries","sectionsTotal","sections","n","outbound","backlinks","unresolved","outboundTotal","backlinksTotal","unresolvedTotal","dst","target","src","body","text","byteTokens","Math","ceil","_size","tokens","max","off"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/commands/peek.ts"],"sourcesContent":["import posix from 'node:path/posix';\nimport { estimateTokens } from '../chunk/index.ts';\nimport type { FeatureName, ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { featureEnabled } from '../config/index.ts';\nimport { SenseError } from '../errors.ts';\nimport { serialQuery } from '../lib/serial-query.ts';\nimport type { Row } from '../output/output.ts';\nimport type { Store } from '../store/types.ts';\nimport { INTERNAL_COLUMNS, materializeScope, scopedPaths } from './scope.ts';\nimport { assertQuerySnapshot } from './snapshot.ts';\n\n// Note resolution shared by peek and path: an exact path, or a unique basename (case\n// insensitive, .md stripped).\nexport function resolveNote(paths: string[], arg: string): string {\n const exact = paths.find((p) => p === arg);\n if (exact) return exact;\n const base = posix.basename(arg).replace(/\\.md$/i, '').toLowerCase();\n const matches = paths.filter((p) => posix.basename(p).replace(/\\.md$/i, '').toLowerCase() === base);\n if (matches.length === 1) return matches[0];\n if (matches.length > 1) throw new SenseError('NOTE_AMBIGUOUS', `\"${arg}\" is ambiguous: ${matches.join(', ')}`);\n throw new SenseError('NOTE_NOT_FOUND', `no note matches \"${arg}\"`);\n}\n\n/** Structured, bounded metadata returned by the root {@link peek} API. */\nexport interface Peek {\n path: string;\n tokens: number;\n frontmatter: Row;\n /** Set when frontmatter parsing failed, distinguishing that case from an empty block. */\n parseError: string | null;\n sections: PeekSection[];\n outbound: string[];\n backlinks: string[];\n unresolved: string[];\n /** Totals before each bounded list is truncated. */\n sectionsTotal: number;\n outboundTotal: number;\n backlinksTotal: number;\n unresolvedTotal: number;\n /** Disabled features whose result blocks are omitted rather than returned empty. */\n off: FeatureName[];\n}\n\n/** A section description, with an inclusive source line range and token estimate, not section prose. */\nexport interface PeekSection {\n level: number;\n heading: string;\n start_line: number;\n end_line: number;\n tokens: number;\n}\n\n/** Options for the root {@link peek} API. */\nexport interface PeekOptions extends SearchOverrides {\n /** Maximum section descriptions. Defaults to 20; must be a positive safe integer. */\n sectionCountLimit?: number;\n /** Maximum entries in each link group independently. Defaults to 20; must be a positive safe integer. */\n linkCountLimit?: number;\n}\n\nconst PEEK_COUNT_LIMIT = 20;\n\n/**\n * Returns indexed metadata for a note in scope. Exact excluded paths fail before scoped basename\n * resolution; resolved neighbors stay in scope, while unresolved written targets remain visible.\n */\nexport function peek(store: Store, cfg: ResolvedConfig, pathArg: string, overrides: PeekOptions = {}): Promise<Peek> {\n return serialQuery(store, () => peekIndexed(store, cfg, pathArg, overrides));\n}\n\nasync function peekIndexed(store: Store, cfg: ResolvedConfig, pathArg: string, overrides: PeekOptions): Promise<Peek> {\n for (const name of ['sectionCountLimit', 'linkCountLimit'] as const) {\n const value = overrides[name];\n if (value !== undefined && (!Number.isSafeInteger(value) || value <= 0)) {\n throw new SenseError('SEARCH_OPTION_INVALID', `peek option \"${name}\" must be a positive safe integer, got ${String(value)}`);\n }\n }\n const sectionCountLimit = overrides.sectionCountLimit ?? PEEK_COUNT_LIMIT;\n const linkCountLimit = overrides.linkCountLimit ?? PEEK_COUNT_LIMIT;\n return store.transaction(async () => {\n await assertQuerySnapshot(store, cfg);\n const pathsStmt = await store.prepare('SELECT \"path\" FROM frontmatter');\n const paths = ((await pathsStmt.all()) as Array<{ path: string }>).map((r) => r.path);\n const allowed = await scopedPaths(store, cfg, overrides);\n if (paths.includes(pathArg) && !allowed.has(pathArg)) {\n throw new SenseError('NOTE_NOT_FOUND', `note \"${pathArg}\" exists but is outside the current scope; change the preset, include/exclude patterns, or where condition`);\n }\n let path: string;\n try {\n path = resolveNote([...allowed], pathArg);\n } catch (err) {\n if (err instanceof SenseError && err.code === 'NOTE_NOT_FOUND') {\n let excludedPath: string;\n try {\n excludedPath = resolveNote(paths, pathArg);\n } catch (unscopedErr) {\n if (unscopedErr instanceof SenseError && unscopedErr.code === 'NOTE_AMBIGUOUS') {\n throw new SenseError('NOTE_NOT_FOUND', `no note in the current scope matches \"${pathArg}\"; indexed matches exist outside the scope, so change the preset, include/exclude patterns, or where condition`);\n }\n throw err;\n }\n throw new SenseError('NOTE_NOT_FOUND', `note \"${excludedPath}\" exists but is outside the current scope; change the preset, include/exclude patterns, or where condition`);\n }\n throw err;\n }\n\n const rowStmt = await store.prepare('SELECT * FROM frontmatter WHERE \"path\" = ?');\n const row = (await rowStmt.get(path)) as Row;\n const parseError = (row._parse_error as string | null) ?? null;\n const frontmatter: Row = {};\n for (const [key, value] of Object.entries(row)) {\n if (!INTERNAL_COLUMNS.has(key) && value !== null) frontmatter[key] = value;\n }\n\n let sectionsTotal = 0;\n let sections: PeekSection[] = [];\n if (featureEnabled(cfg, 'sections')) {\n sectionsTotal = ((await (await store.prepare('SELECT COUNT(*) AS n FROM sections WHERE \"path\" = ?')).get(path)) as { n: number }).n;\n sections = (await (await store.prepare('SELECT level, heading, start_line, end_line, tokens FROM sections WHERE \"path\" = ? ORDER BY idx LIMIT ?')).all(path, sectionCountLimit)) as PeekSection[];\n }\n\n let outbound: string[] = [];\n let backlinks: string[] = [];\n let unresolved: string[] = [];\n let outboundTotal = 0;\n let backlinksTotal = 0;\n let unresolvedTotal = 0;\n if (featureEnabled(cfg, 'links')) {\n await materializeScope(store, '_peek_scope', allowed);\n outboundTotal = ((await (await store.prepare('SELECT COUNT(DISTINCT dst) AS n FROM links WHERE src = ? AND dst != src AND dst IN (SELECT \"path\" FROM _peek_scope)')).get(path)) as { n: number }).n;\n // The first written target determines each resolved destination's position.\n outbound = ((await (await store.prepare('SELECT dst FROM links WHERE src = ? AND dst != src AND dst IN (SELECT \"path\" FROM _peek_scope) GROUP BY dst ORDER BY MIN(target) LIMIT ?')).all(path, linkCountLimit)) as Array<{ dst: string }>).map((r) => r.dst);\n unresolvedTotal = ((await (await store.prepare('SELECT COUNT(*) AS n FROM links WHERE src = ? AND dst IS NULL')).get(path)) as { n: number }).n;\n unresolved = ((await (await store.prepare('SELECT target FROM links WHERE src = ? AND dst IS NULL ORDER BY target LIMIT ?')).all(path, linkCountLimit)) as Array<{ target: string }>).map((r) => r.target);\n backlinksTotal = ((await (await store.prepare('SELECT COUNT(DISTINCT src) AS n FROM links WHERE dst = ? AND src != dst AND src IN (SELECT \"path\" FROM _peek_scope)')).get(path)) as { n: number }).n;\n backlinks = ((await (await store.prepare('SELECT DISTINCT src FROM links WHERE dst = ? AND src != dst AND src IN (SELECT \"path\" FROM _peek_scope) ORDER BY src LIMIT ?')).all(path, linkCountLimit)) as Array<{ src: string }>).map((r) => r.src);\n }\n\n // content.text is the stripped body already computed at reconcile time (no extra file read),\n // floored by the byte/4 estimate so stripped-away syntax and frontmatter can't vanish from the price.\n const body = ((await (await store.prepare('SELECT text FROM content WHERE \"path\" = ?')).get(path)) as { text: string } | undefined)?.text;\n const byteTokens = Math.ceil(((row._size as number) ?? 0) / 4);\n const tokens = body !== undefined ? Math.max(Math.ceil(estimateTokens(body)), byteTokens) : byteTokens;\n\n return {\n path,\n tokens,\n frontmatter,\n parseError,\n sections,\n outbound,\n backlinks,\n unresolved,\n sectionsTotal,\n outboundTotal,\n backlinksTotal,\n unresolvedTotal,\n off: (['sections', 'links'] as FeatureName[]).filter((name) => !featureEnabled(cfg, name)),\n };\n });\n}\n"],"names":["posix","estimateTokens","featureEnabled","SenseError","serialQuery","INTERNAL_COLUMNS","materializeScope","scopedPaths","assertQuerySnapshot","resolveNote","paths","arg","exact","find","p","base","basename","replace","toLowerCase","matches","filter","length","join","PEEK_COUNT_LIMIT","peek","store","cfg","pathArg","overrides","peekIndexed","name","value","undefined","Number","isSafeInteger","String","sectionCountLimit","linkCountLimit","transaction","row","pathsStmt","prepare","all","map","r","path","allowed","includes","has","err","code","excludedPath","unscopedErr","rowStmt","get","parseError","_parse_error","frontmatter","key","Object","entries","sectionsTotal","sections","n","outbound","backlinks","unresolved","outboundTotal","backlinksTotal","unresolvedTotal","dst","target","src","body","text","byteTokens","Math","ceil","_size","tokens","max","off"],"mappings":"AAAA,OAAOA,WAAW,kBAAkB;AACpC,SAASC,cAAc,QAAQ,oBAAoB;AAEnD,SAASC,cAAc,QAAQ,qBAAqB;AACpD,SAASC,UAAU,QAAQ,eAAe;AAC1C,SAASC,WAAW,QAAQ,yBAAyB;AAGrD,SAASC,gBAAgB,EAAEC,gBAAgB,EAAEC,WAAW,QAAQ,aAAa;AAC7E,SAASC,mBAAmB,QAAQ,gBAAgB;AAEpD,qFAAqF;AACrF,8BAA8B;AAC9B,OAAO,SAASC,YAAYC,KAAe,EAAEC,GAAW;IACtD,MAAMC,QAAQF,MAAMG,IAAI,CAAC,CAACC,IAAMA,MAAMH;IACtC,IAAIC,OAAO,OAAOA;IAClB,MAAMG,OAAOf,MAAMgB,QAAQ,CAACL,KAAKM,OAAO,CAAC,UAAU,IAAIC,WAAW;IAClE,MAAMC,UAAUT,MAAMU,MAAM,CAAC,CAACN,IAAMd,MAAMgB,QAAQ,CAACF,GAAGG,OAAO,CAAC,UAAU,IAAIC,WAAW,OAAOH;IAC9F,IAAII,QAAQE,MAAM,KAAK,GAAG,OAAOF,OAAO,CAAC,EAAE;IAC3C,IAAIA,QAAQE,MAAM,GAAG,GAAG,MAAM,IAAIlB,WAAW,kBAAkB,CAAC,CAAC,EAAEQ,IAAI,gBAAgB,EAAEQ,QAAQG,IAAI,CAAC,OAAO;IAC7G,MAAM,IAAInB,WAAW,kBAAkB,CAAC,iBAAiB,EAAEQ,IAAI,CAAC,CAAC;AACnE;AAuCA,MAAMY,mBAAmB;AAEzB;;;CAGC,GACD,OAAO,SAASC,KAAKC,KAAY,EAAEC,GAAmB,EAAEC,OAAe,EAAEC,YAAyB,CAAC,CAAC;IAClG,OAAOxB,YAAYqB,OAAO,IAAMI,YAAYJ,OAAOC,KAAKC,SAASC;AACnE;AAEA,eAAeC,YAAYJ,KAAY,EAAEC,GAAmB,EAAEC,OAAe,EAAEC,SAAsB;QAOzEA,8BACHA;IAPvB,KAAK,MAAME,QAAQ;QAAC;QAAqB;KAAiB,CAAW;QACnE,MAAMC,QAAQH,SAAS,CAACE,KAAK;QAC7B,IAAIC,UAAUC,aAAc,CAAA,CAACC,OAAOC,aAAa,CAACH,UAAUA,SAAS,CAAA,GAAI;YACvE,MAAM,IAAI5B,WAAW,yBAAyB,CAAC,aAAa,EAAE2B,KAAK,uCAAuC,EAAEK,OAAOJ,QAAQ;QAC7H;IACF;IACA,MAAMK,qBAAoBR,+BAAAA,UAAUQ,iBAAiB,cAA3BR,0CAAAA,+BAA+BL;IACzD,MAAMc,kBAAiBT,4BAAAA,UAAUS,cAAc,cAAxBT,uCAAAA,4BAA4BL;IACnD,OAAOE,MAAMa,WAAW,CAAC;YA6BHC,mBAiCWA;YADhB;QA5Df,MAAM/B,oBAAoBiB,OAAOC;QACjC,MAAMc,YAAY,MAAMf,MAAMgB,OAAO,CAAC;QACtC,MAAM/B,QAAQ,AAAE,CAAA,MAAM8B,UAAUE,GAAG,EAAC,EAA+BC,GAAG,CAAC,CAACC,IAAMA,EAAEC,IAAI;QACpF,MAAMC,UAAU,MAAMvC,YAAYkB,OAAOC,KAAKE;QAC9C,IAAIlB,MAAMqC,QAAQ,CAACpB,YAAY,CAACmB,QAAQE,GAAG,CAACrB,UAAU;YACpD,MAAM,IAAIxB,WAAW,kBAAkB,CAAC,MAAM,EAAEwB,QAAQ,0GAA0G,CAAC;QACrK;QACA,IAAIkB;QACJ,IAAI;YACFA,OAAOpC,YAAY;mBAAIqC;aAAQ,EAAEnB;QACnC,EAAE,OAAOsB,KAAK;YACZ,IAAIA,eAAe9C,cAAc8C,IAAIC,IAAI,KAAK,kBAAkB;gBAC9D,IAAIC;gBACJ,IAAI;oBACFA,eAAe1C,YAAYC,OAAOiB;gBACpC,EAAE,OAAOyB,aAAa;oBACpB,IAAIA,uBAAuBjD,cAAciD,YAAYF,IAAI,KAAK,kBAAkB;wBAC9E,MAAM,IAAI/C,WAAW,kBAAkB,CAAC,sCAAsC,EAAEwB,QAAQ,8GAA8G,CAAC;oBACzM;oBACA,MAAMsB;gBACR;gBACA,MAAM,IAAI9C,WAAW,kBAAkB,CAAC,MAAM,EAAEgD,aAAa,0GAA0G,CAAC;YAC1K;YACA,MAAMF;QACR;QAEA,MAAMI,UAAU,MAAM5B,MAAMgB,OAAO,CAAC;QACpC,MAAMF,MAAO,MAAMc,QAAQC,GAAG,CAACT;QAC/B,MAAMU,cAAchB,oBAAAA,IAAIiB,YAAY,cAAhBjB,+BAAAA,oBAAsC;QAC1D,MAAMkB,cAAmB,CAAC;QAC1B,KAAK,MAAM,CAACC,KAAK3B,MAAM,IAAI4B,OAAOC,OAAO,CAACrB,KAAM;YAC9C,IAAI,CAAClC,iBAAiB2C,GAAG,CAACU,QAAQ3B,UAAU,MAAM0B,WAAW,CAACC,IAAI,GAAG3B;QACvE;QAEA,IAAI8B,gBAAgB;QACpB,IAAIC,WAA0B,EAAE;QAChC,IAAI5D,eAAewB,KAAK,aAAa;YACnCmC,gBAAgB,AAAE,CAAA,MAAM,AAAC,CAAA,MAAMpC,MAAMgB,OAAO,CAAC,sDAAqD,EAAGa,GAAG,CAACT,KAAI,EAAqBkB,CAAC;YACnID,WAAY,MAAM,AAAC,CAAA,MAAMrC,MAAMgB,OAAO,CAAC,0GAAyG,EAAGC,GAAG,CAACG,MAAMT;QAC/J;QAEA,IAAI4B,WAAqB,EAAE;QAC3B,IAAIC,YAAsB,EAAE;QAC5B,IAAIC,aAAuB,EAAE;QAC7B,IAAIC,gBAAgB;QACpB,IAAIC,iBAAiB;QACrB,IAAIC,kBAAkB;QACtB,IAAInE,eAAewB,KAAK,UAAU;YAChC,MAAMpB,iBAAiBmB,OAAO,eAAeqB;YAC7CqB,gBAAgB,AAAE,CAAA,MAAM,AAAC,CAAA,MAAM1C,MAAMgB,OAAO,CAAC,sHAAqH,EAAGa,GAAG,CAACT,KAAI,EAAqBkB,CAAC;YACnM,4EAA4E;YAC5EC,WAAW,AAAE,CAAA,MAAM,AAAC,CAAA,MAAMvC,MAAMgB,OAAO,CAAC,2IAA0I,EAAGC,GAAG,CAACG,MAAMR,eAAc,EAA8BM,GAAG,CAAC,CAACC,IAAMA,EAAE0B,GAAG;YAC3PD,kBAAkB,AAAE,CAAA,MAAM,AAAC,CAAA,MAAM5C,MAAMgB,OAAO,CAAC,gEAA+D,EAAGa,GAAG,CAACT,KAAI,EAAqBkB,CAAC;YAC/IG,aAAa,AAAE,CAAA,MAAM,AAAC,CAAA,MAAMzC,MAAMgB,OAAO,CAAC,iFAAgF,EAAGC,GAAG,CAACG,MAAMR,eAAc,EAAiCM,GAAG,CAAC,CAACC,IAAMA,EAAE2B,MAAM;YACzMH,iBAAiB,AAAE,CAAA,MAAM,AAAC,CAAA,MAAM3C,MAAMgB,OAAO,CAAC,sHAAqH,EAAGa,GAAG,CAACT,KAAI,EAAqBkB,CAAC;YACpME,YAAY,AAAE,CAAA,MAAM,AAAC,CAAA,MAAMxC,MAAMgB,OAAO,CAAC,+HAA8H,EAAGC,GAAG,CAACG,MAAMR,eAAc,EAA8BM,GAAG,CAAC,CAACC,IAAMA,EAAE4B,GAAG;QAClP;QAEA,6FAA6F;QAC7F,sGAAsG;QACtG,MAAMC,QAAS,QAAA,MAAM,AAAC,CAAA,MAAMhD,MAAMgB,OAAO,CAAC,4CAA2C,EAAGa,GAAG,CAACT,mBAA7E,4BAAF,AAAE,MAAsH6B,IAAI;QACzI,MAAMC,aAAaC,KAAKC,IAAI,CAAC,EAAEtC,aAAAA,IAAIuC,KAAK,cAATvC,wBAAAA,aAAwB,KAAK;QAC5D,MAAMwC,SAASN,SAASzC,YAAY4C,KAAKI,GAAG,CAACJ,KAAKC,IAAI,CAAC5E,eAAewE,QAAQE,cAAcA;QAE5F,OAAO;YACL9B;YACAkC;YACAtB;YACAF;YACAO;YACAE;YACAC;YACAC;YACAL;YACAM;YACAC;YACAC;YACAY,KAAK,AAAC;gBAAC;gBAAY;aAAQ,CAAmB7D,MAAM,CAAC,CAACU,OAAS,CAAC5B,eAAewB,KAAKI;QACtF;IACF;AACF"}