sensemaking 0.17.1 → 0.18.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 (425) hide show
  1. package/README.md +15 -13
  2. package/dist/cjs/cli/map.js +144 -3
  3. package/dist/cjs/cli/map.js.map +1 -1
  4. package/dist/cjs/cli/named.js +19 -11
  5. package/dist/cjs/cli/named.js.map +1 -1
  6. package/dist/cjs/cli/path.js +186 -26
  7. package/dist/cjs/cli/path.js.map +1 -1
  8. package/dist/cjs/cli/peek.js +145 -4
  9. package/dist/cjs/cli/peek.js.map +1 -1
  10. package/dist/cjs/cli/related.js +2 -2
  11. package/dist/cjs/cli/related.js.map +1 -1
  12. package/dist/cjs/cli/search.js +2 -2
  13. package/dist/cjs/cli/search.js.map +1 -1
  14. package/dist/cjs/cli/shared.d.cts +3 -3
  15. package/dist/cjs/cli/shared.d.ts +3 -3
  16. package/dist/cjs/cli/shared.js +156 -58
  17. package/dist/cjs/cli/shared.js.map +1 -1
  18. package/dist/cjs/cli/sql.js +151 -10
  19. package/dist/cjs/cli/sql.js.map +1 -1
  20. package/dist/cjs/cli/status.js +177 -52
  21. package/dist/cjs/cli/status.js.map +1 -1
  22. package/dist/cjs/commands/map.d.cts +2 -2
  23. package/dist/cjs/commands/map.d.ts +2 -2
  24. package/dist/cjs/commands/map.js +373 -67
  25. package/dist/cjs/commands/map.js.map +1 -1
  26. package/dist/cjs/commands/peek.d.cts +2 -2
  27. package/dist/cjs/commands/peek.d.ts +2 -2
  28. package/dist/cjs/commands/peek.js +321 -79
  29. package/dist/cjs/commands/peek.js.map +1 -1
  30. package/dist/cjs/commands/related.d.cts +2 -2
  31. package/dist/cjs/commands/related.d.ts +2 -2
  32. package/dist/cjs/commands/related.js +55 -10
  33. package/dist/cjs/commands/related.js.map +1 -1
  34. package/dist/cjs/commands/scope.d.cts +7 -7
  35. package/dist/cjs/commands/scope.d.ts +7 -7
  36. package/dist/cjs/commands/scope.js +382 -45
  37. package/dist/cjs/commands/scope.js.map +1 -1
  38. package/dist/cjs/commands/search.d.cts +2 -2
  39. package/dist/cjs/commands/search.d.ts +2 -2
  40. package/dist/cjs/commands/search.js +292 -99
  41. package/dist/cjs/commands/search.js.map +1 -1
  42. package/dist/cjs/commands/signals.d.cts +4 -10
  43. package/dist/cjs/commands/signals.d.ts +4 -10
  44. package/dist/cjs/commands/signals.js +91 -45
  45. package/dist/cjs/commands/signals.js.map +1 -1
  46. package/dist/cjs/commands/status.d.cts +2 -2
  47. package/dist/cjs/commands/status.d.ts +2 -2
  48. package/dist/cjs/commands/status.js +247 -10
  49. package/dist/cjs/commands/status.js.map +1 -1
  50. package/dist/cjs/config/access.d.cts +1 -0
  51. package/dist/cjs/config/access.d.ts +1 -0
  52. package/dist/cjs/config/access.js +7 -0
  53. package/dist/cjs/config/access.js.map +1 -1
  54. package/dist/cjs/config/index.d.cts +1 -1
  55. package/dist/cjs/config/index.d.ts +1 -1
  56. package/dist/cjs/config/index.js +3 -0
  57. package/dist/cjs/config/index.js.map +1 -1
  58. package/dist/cjs/config/types.d.cts +1 -0
  59. package/dist/cjs/config/types.d.ts +1 -0
  60. package/dist/cjs/config/types.js.map +1 -1
  61. package/dist/cjs/config/validate.js +10 -1
  62. package/dist/cjs/config/validate.js.map +1 -1
  63. package/dist/cjs/embed/distribution.d.cts +3 -3
  64. package/dist/cjs/embed/distribution.d.ts +3 -3
  65. package/dist/cjs/embed/distribution.js +162 -6
  66. package/dist/cjs/embed/distribution.js.map +1 -1
  67. package/dist/cjs/embed/langfit.d.cts +2 -2
  68. package/dist/cjs/embed/langfit.d.ts +2 -2
  69. package/dist/cjs/embed/langfit.js +57 -44
  70. package/dist/cjs/embed/langfit.js.map +1 -1
  71. package/dist/cjs/embed/query.d.cts +6 -13
  72. package/dist/cjs/embed/query.d.ts +6 -13
  73. package/dist/cjs/embed/query.js +56 -168
  74. package/dist/cjs/embed/query.js.map +1 -1
  75. package/dist/cjs/embed/types.d.cts +1 -0
  76. package/dist/cjs/embed/types.d.ts +1 -0
  77. package/dist/cjs/embed/types.js +11 -2
  78. package/dist/cjs/embed/types.js.map +1 -1
  79. package/dist/cjs/errors.d.cts +1 -1
  80. package/dist/cjs/errors.d.ts +1 -1
  81. package/dist/cjs/errors.js.map +1 -1
  82. package/dist/cjs/features/embed.js +218 -11
  83. package/dist/cjs/features/embed.js.map +1 -1
  84. package/dist/cjs/features/index.d.cts +1 -1
  85. package/dist/cjs/features/index.d.ts +1 -1
  86. package/dist/cjs/features/index.js +6 -0
  87. package/dist/cjs/features/index.js.map +1 -1
  88. package/dist/cjs/features/links.d.cts +7 -2
  89. package/dist/cjs/features/links.d.ts +7 -2
  90. package/dist/cjs/features/links.js +710 -198
  91. package/dist/cjs/features/links.js.map +1 -1
  92. package/dist/cjs/features/rank.js +231 -31
  93. package/dist/cjs/features/rank.js.map +1 -1
  94. package/dist/cjs/features/sections.js +218 -8
  95. package/dist/cjs/features/sections.js.map +1 -1
  96. package/dist/cjs/features/tags.js +236 -40
  97. package/dist/cjs/features/tags.js.map +1 -1
  98. package/dist/cjs/features/types.d.cts +9 -5
  99. package/dist/cjs/features/types.d.ts +9 -5
  100. package/dist/cjs/graph/traverse.d.cts +2 -2
  101. package/dist/cjs/graph/traverse.d.ts +2 -2
  102. package/dist/cjs/graph/traverse.js +321 -42
  103. package/dist/cjs/graph/traverse.js.map +1 -1
  104. package/dist/cjs/index.d.cts +3 -2
  105. package/dist/cjs/index.d.ts +3 -2
  106. package/dist/cjs/index.js +2 -2
  107. package/dist/cjs/index.js.map +1 -1
  108. package/dist/cjs/lib/guarded-tick.d.cts +1 -0
  109. package/dist/cjs/lib/guarded-tick.d.ts +1 -0
  110. package/dist/cjs/lib/guarded-tick.js +19 -0
  111. package/dist/cjs/lib/guarded-tick.js.map +1 -0
  112. package/dist/cjs/output/column-hint.d.cts +1 -2
  113. package/dist/cjs/output/column-hint.d.ts +1 -2
  114. package/dist/cjs/output/column-hint.js +1 -4
  115. package/dist/cjs/output/column-hint.js.map +1 -1
  116. package/dist/cjs/output/output.d.cts +2 -1
  117. package/dist/cjs/output/output.d.ts +2 -1
  118. package/dist/cjs/output/output.js +515 -97
  119. package/dist/cjs/output/output.js.map +1 -1
  120. package/dist/cjs/scan/frontmatter.js.map +1 -1
  121. package/dist/cjs/scan/index.js.map +1 -1
  122. package/dist/cjs/scan/reparse.d.cts +10 -0
  123. package/dist/cjs/scan/reparse.d.ts +10 -0
  124. package/dist/cjs/scan/reparse.js +104 -0
  125. package/dist/cjs/scan/reparse.js.map +1 -0
  126. package/dist/cjs/store/duckdb/batch.d.cts +16 -0
  127. package/dist/cjs/store/duckdb/batch.d.ts +16 -0
  128. package/dist/cjs/store/duckdb/batch.js +208 -0
  129. package/dist/cjs/store/duckdb/batch.js.map +1 -0
  130. package/dist/cjs/store/duckdb/connection.d.cts +5 -0
  131. package/dist/cjs/store/duckdb/connection.d.ts +5 -0
  132. package/dist/cjs/store/duckdb/connection.js +772 -0
  133. package/dist/cjs/store/duckdb/connection.js.map +1 -0
  134. package/dist/cjs/store/duckdb/lexical.d.cts +10 -0
  135. package/dist/cjs/store/duckdb/lexical.d.ts +10 -0
  136. package/dist/cjs/store/duckdb/lexical.js +502 -0
  137. package/dist/cjs/store/duckdb/lexical.js.map +1 -0
  138. package/dist/cjs/store/duckdb/native.d.cts +3 -0
  139. package/dist/cjs/store/duckdb/native.d.ts +3 -0
  140. package/dist/cjs/store/duckdb/native.js +360 -0
  141. package/dist/cjs/store/duckdb/native.js.map +1 -0
  142. package/dist/cjs/store/duckdb/open.d.cts +12 -0
  143. package/dist/cjs/store/duckdb/open.d.ts +12 -0
  144. package/dist/cjs/store/duckdb/open.js +501 -0
  145. package/dist/cjs/store/duckdb/open.js.map +1 -0
  146. package/dist/cjs/store/duckdb/reconcile.d.cts +6 -0
  147. package/dist/cjs/store/duckdb/reconcile.d.ts +6 -0
  148. package/dist/cjs/store/duckdb/reconcile.js +753 -0
  149. package/dist/cjs/store/duckdb/reconcile.js.map +1 -0
  150. package/dist/cjs/store/duckdb/sql-functions.d.cts +2 -0
  151. package/dist/cjs/store/duckdb/sql-functions.d.ts +2 -0
  152. package/dist/cjs/store/duckdb/sql-functions.js +203 -0
  153. package/dist/cjs/store/duckdb/sql-functions.js.map +1 -0
  154. package/dist/cjs/store/duckdb/store.d.cts +5 -0
  155. package/dist/cjs/store/duckdb/store.d.ts +5 -0
  156. package/dist/cjs/store/duckdb/store.js +504 -0
  157. package/dist/cjs/store/duckdb/store.js.map +1 -0
  158. package/dist/cjs/store/duckdb/vectors.d.cts +9 -0
  159. package/dist/cjs/store/duckdb/vectors.d.ts +9 -0
  160. package/dist/cjs/store/duckdb/vectors.js +502 -0
  161. package/dist/cjs/store/duckdb/vectors.js.map +1 -0
  162. package/dist/cjs/store/index.d.cts +7 -0
  163. package/dist/cjs/store/index.d.ts +7 -0
  164. package/dist/cjs/store/index.js +201 -0
  165. package/dist/cjs/store/index.js.map +1 -0
  166. package/dist/cjs/store/meta.d.cts +3 -0
  167. package/dist/cjs/store/meta.d.ts +3 -0
  168. package/dist/cjs/store/meta.js +215 -0
  169. package/dist/cjs/store/meta.js.map +1 -0
  170. package/dist/cjs/store/shared.d.cts +5 -0
  171. package/dist/cjs/store/shared.d.ts +5 -0
  172. package/dist/cjs/store/shared.js +252 -0
  173. package/dist/cjs/store/shared.js.map +1 -0
  174. package/dist/cjs/store/sql-functions.d.cts +2 -0
  175. package/dist/cjs/store/sql-functions.d.ts +2 -0
  176. package/dist/cjs/store/sql-functions.js +48 -0
  177. package/dist/cjs/store/sql-functions.js.map +1 -0
  178. package/dist/cjs/store/sqlite/connection.d.cts +3 -0
  179. package/dist/cjs/store/sqlite/connection.d.ts +3 -0
  180. package/dist/cjs/store/sqlite/connection.js +516 -0
  181. package/dist/cjs/store/sqlite/connection.js.map +1 -0
  182. package/dist/cjs/store/sqlite/lexical.d.cts +2 -0
  183. package/dist/cjs/store/sqlite/lexical.d.ts +2 -0
  184. package/dist/cjs/store/sqlite/lexical.js +177 -0
  185. package/dist/cjs/store/sqlite/lexical.js.map +1 -0
  186. package/dist/cjs/{db → store/sqlite}/open.d.cts +5 -5
  187. package/dist/cjs/{db → store/sqlite}/open.d.ts +5 -5
  188. package/dist/cjs/store/sqlite/open.js +604 -0
  189. package/dist/cjs/store/sqlite/open.js.map +1 -0
  190. package/dist/cjs/store/sqlite/reconcile.d.cts +10 -0
  191. package/dist/cjs/store/sqlite/reconcile.d.ts +10 -0
  192. package/dist/cjs/store/sqlite/reconcile.js +1020 -0
  193. package/dist/cjs/store/sqlite/reconcile.js.map +1 -0
  194. package/dist/cjs/store/sqlite/sql-functions.js +34 -0
  195. package/dist/cjs/store/sqlite/sql-functions.js.map +1 -0
  196. package/dist/cjs/store/sqlite/store.d.cts +5 -0
  197. package/dist/cjs/store/sqlite/store.d.ts +5 -0
  198. package/dist/cjs/store/sqlite/store.js +588 -0
  199. package/dist/cjs/store/sqlite/store.js.map +1 -0
  200. package/dist/cjs/store/sqlite/vectors.d.cts +13 -0
  201. package/dist/cjs/store/sqlite/vectors.d.ts +13 -0
  202. package/dist/cjs/store/sqlite/vectors.js +470 -0
  203. package/dist/cjs/store/sqlite/vectors.js.map +1 -0
  204. package/dist/cjs/store/transaction.d.cts +5 -0
  205. package/dist/cjs/store/transaction.d.ts +5 -0
  206. package/dist/cjs/store/transaction.js +297 -0
  207. package/dist/cjs/store/transaction.js.map +1 -0
  208. package/dist/cjs/store/types.d.cts +91 -0
  209. package/dist/cjs/store/types.d.ts +91 -0
  210. package/dist/cjs/store/types.js +15 -0
  211. package/dist/cjs/store/types.js.map +1 -0
  212. package/dist/cjs/watch.d.cts +3 -0
  213. package/dist/cjs/watch.d.ts +3 -0
  214. package/dist/cjs/watch.js +215 -73
  215. package/dist/cjs/watch.js.map +1 -1
  216. package/dist/esm/cli/map.js +4 -4
  217. package/dist/esm/cli/map.js.map +1 -1
  218. package/dist/esm/cli/named.js +2 -2
  219. package/dist/esm/cli/named.js.map +1 -1
  220. package/dist/esm/cli/path.js +4 -4
  221. package/dist/esm/cli/path.js.map +1 -1
  222. package/dist/esm/cli/peek.js +4 -4
  223. package/dist/esm/cli/peek.js.map +1 -1
  224. package/dist/esm/cli/related.js +2 -2
  225. package/dist/esm/cli/related.js.map +1 -1
  226. package/dist/esm/cli/search.js +1 -1
  227. package/dist/esm/cli/search.js.map +1 -1
  228. package/dist/esm/cli/shared.d.ts +3 -3
  229. package/dist/esm/cli/shared.js +17 -17
  230. package/dist/esm/cli/shared.js.map +1 -1
  231. package/dist/esm/cli/sql.js +2 -2
  232. package/dist/esm/cli/sql.js.map +1 -1
  233. package/dist/esm/cli/status.js +23 -22
  234. package/dist/esm/cli/status.js.map +1 -1
  235. package/dist/esm/commands/map.d.ts +2 -2
  236. package/dist/esm/commands/map.js +51 -41
  237. package/dist/esm/commands/map.js.map +1 -1
  238. package/dist/esm/commands/peek.d.ts +2 -2
  239. package/dist/esm/commands/peek.js +58 -50
  240. package/dist/esm/commands/peek.js.map +1 -1
  241. package/dist/esm/commands/related.d.ts +2 -2
  242. package/dist/esm/commands/related.js +9 -9
  243. package/dist/esm/commands/related.js.map +1 -1
  244. package/dist/esm/commands/scope.d.ts +7 -7
  245. package/dist/esm/commands/scope.js +28 -17
  246. package/dist/esm/commands/scope.js.map +1 -1
  247. package/dist/esm/commands/search.d.ts +2 -2
  248. package/dist/esm/commands/search.js +42 -35
  249. package/dist/esm/commands/search.js.map +1 -1
  250. package/dist/esm/commands/signals.d.ts +4 -10
  251. package/dist/esm/commands/signals.js +17 -13
  252. package/dist/esm/commands/signals.js.map +1 -1
  253. package/dist/esm/commands/status.d.ts +2 -2
  254. package/dist/esm/commands/status.js +13 -7
  255. package/dist/esm/commands/status.js.map +1 -1
  256. package/dist/esm/config/access.d.ts +1 -0
  257. package/dist/esm/config/access.js +5 -0
  258. package/dist/esm/config/access.js.map +1 -1
  259. package/dist/esm/config/index.d.ts +1 -1
  260. package/dist/esm/config/index.js +1 -1
  261. package/dist/esm/config/index.js.map +1 -1
  262. package/dist/esm/config/types.d.ts +1 -0
  263. package/dist/esm/config/types.js.map +1 -1
  264. package/dist/esm/config/validate.js +10 -1
  265. package/dist/esm/config/validate.js.map +1 -1
  266. package/dist/esm/embed/distribution.d.ts +3 -3
  267. package/dist/esm/embed/distribution.js +5 -5
  268. package/dist/esm/embed/distribution.js.map +1 -1
  269. package/dist/esm/embed/langfit.d.ts +2 -2
  270. package/dist/esm/embed/langfit.js +4 -4
  271. package/dist/esm/embed/langfit.js.map +1 -1
  272. package/dist/esm/embed/query.d.ts +6 -13
  273. package/dist/esm/embed/query.js +23 -84
  274. package/dist/esm/embed/query.js.map +1 -1
  275. package/dist/esm/embed/types.d.ts +1 -0
  276. package/dist/esm/embed/types.js +5 -3
  277. package/dist/esm/embed/types.js.map +1 -1
  278. package/dist/esm/errors.d.ts +1 -1
  279. package/dist/esm/errors.js.map +1 -1
  280. package/dist/esm/features/embed.js +22 -10
  281. package/dist/esm/features/embed.js.map +1 -1
  282. package/dist/esm/features/index.d.ts +1 -1
  283. package/dist/esm/features/index.js +1 -1
  284. package/dist/esm/features/index.js.map +1 -1
  285. package/dist/esm/features/links.d.ts +7 -2
  286. package/dist/esm/features/links.js +124 -97
  287. package/dist/esm/features/links.js.map +1 -1
  288. package/dist/esm/features/rank.js +15 -8
  289. package/dist/esm/features/rank.js.map +1 -1
  290. package/dist/esm/features/sections.js +20 -7
  291. package/dist/esm/features/sections.js.map +1 -1
  292. package/dist/esm/features/tags.js +19 -18
  293. package/dist/esm/features/tags.js.map +1 -1
  294. package/dist/esm/features/types.d.ts +9 -5
  295. package/dist/esm/features/types.js +1 -1
  296. package/dist/esm/features/types.js.map +1 -1
  297. package/dist/esm/graph/traverse.d.ts +2 -2
  298. package/dist/esm/graph/traverse.js +26 -23
  299. package/dist/esm/graph/traverse.js.map +1 -1
  300. package/dist/esm/index.d.ts +3 -2
  301. package/dist/esm/index.js +1 -1
  302. package/dist/esm/index.js.map +1 -1
  303. package/dist/esm/lib/guarded-tick.d.ts +1 -0
  304. package/dist/esm/lib/guarded-tick.js +8 -0
  305. package/dist/esm/lib/guarded-tick.js.map +1 -0
  306. package/dist/esm/output/column-hint.d.ts +1 -2
  307. package/dist/esm/output/column-hint.js +3 -2
  308. package/dist/esm/output/column-hint.js.map +1 -1
  309. package/dist/esm/output/output.d.ts +2 -1
  310. package/dist/esm/output/output.js +27 -23
  311. package/dist/esm/output/output.js.map +1 -1
  312. package/dist/esm/scan/frontmatter.js +1 -1
  313. package/dist/esm/scan/frontmatter.js.map +1 -1
  314. package/dist/esm/scan/index.js +1 -1
  315. package/dist/esm/scan/index.js.map +1 -1
  316. package/dist/esm/scan/reparse.d.ts +10 -0
  317. package/dist/esm/scan/reparse.js +30 -0
  318. package/dist/esm/scan/reparse.js.map +1 -0
  319. package/dist/esm/store/duckdb/batch.d.ts +16 -0
  320. package/dist/esm/store/duckdb/batch.js +96 -0
  321. package/dist/esm/store/duckdb/batch.js.map +1 -0
  322. package/dist/esm/store/duckdb/connection.d.ts +5 -0
  323. package/dist/esm/store/duckdb/connection.js +97 -0
  324. package/dist/esm/store/duckdb/connection.js.map +1 -0
  325. package/dist/esm/store/duckdb/lexical.d.ts +10 -0
  326. package/dist/esm/store/duckdb/lexical.js +163 -0
  327. package/dist/esm/store/duckdb/lexical.js.map +1 -0
  328. package/dist/esm/store/duckdb/native.d.ts +3 -0
  329. package/dist/esm/store/duckdb/native.js +96 -0
  330. package/dist/esm/store/duckdb/native.js.map +1 -0
  331. package/dist/esm/store/duckdb/open.d.ts +12 -0
  332. package/dist/esm/store/duckdb/open.js +127 -0
  333. package/dist/esm/store/duckdb/open.js.map +1 -0
  334. package/dist/esm/store/duckdb/reconcile.d.ts +6 -0
  335. package/dist/esm/store/duckdb/reconcile.js +141 -0
  336. package/dist/esm/store/duckdb/reconcile.js.map +1 -0
  337. package/dist/esm/store/duckdb/sql-functions.d.ts +2 -0
  338. package/dist/esm/store/duckdb/sql-functions.js +56 -0
  339. package/dist/esm/store/duckdb/sql-functions.js.map +1 -0
  340. package/dist/esm/store/duckdb/store.d.ts +5 -0
  341. package/dist/esm/store/duckdb/store.js +104 -0
  342. package/dist/esm/store/duckdb/store.js.map +1 -0
  343. package/dist/esm/store/duckdb/vectors.d.ts +9 -0
  344. package/dist/esm/store/duckdb/vectors.js +171 -0
  345. package/dist/esm/store/duckdb/vectors.js.map +1 -0
  346. package/dist/esm/store/index.d.ts +7 -0
  347. package/dist/esm/store/index.js +35 -0
  348. package/dist/esm/store/index.js.map +1 -0
  349. package/dist/esm/store/meta.d.ts +3 -0
  350. package/dist/esm/store/meta.js +17 -0
  351. package/dist/esm/store/meta.js.map +1 -0
  352. package/dist/esm/store/shared.d.ts +5 -0
  353. package/dist/esm/store/shared.js +24 -0
  354. package/dist/esm/store/shared.js.map +1 -0
  355. package/dist/esm/store/sql-functions.d.ts +2 -0
  356. package/dist/esm/store/sql-functions.js +29 -0
  357. package/dist/esm/store/sql-functions.js.map +1 -0
  358. package/dist/esm/store/sqlite/connection.d.ts +3 -0
  359. package/dist/esm/store/sqlite/connection.js +50 -0
  360. package/dist/esm/store/sqlite/connection.js.map +1 -0
  361. package/dist/esm/store/sqlite/lexical.d.ts +2 -0
  362. package/dist/esm/store/sqlite/lexical.js +21 -0
  363. package/dist/esm/store/sqlite/lexical.js.map +1 -0
  364. package/dist/esm/{db → store/sqlite}/open.d.ts +5 -5
  365. package/dist/esm/store/sqlite/open.js +193 -0
  366. package/dist/esm/store/sqlite/open.js.map +1 -0
  367. package/dist/esm/store/sqlite/reconcile.d.ts +10 -0
  368. package/dist/esm/{db → store/sqlite}/reconcile.js +101 -99
  369. package/dist/esm/store/sqlite/reconcile.js.map +1 -0
  370. package/dist/esm/store/sqlite/sql-functions.js +23 -0
  371. package/dist/esm/store/sqlite/sql-functions.js.map +1 -0
  372. package/dist/esm/store/sqlite/store.d.ts +5 -0
  373. package/dist/esm/store/sqlite/store.js +82 -0
  374. package/dist/esm/store/sqlite/store.js.map +1 -0
  375. package/dist/esm/store/sqlite/vectors.d.ts +13 -0
  376. package/dist/esm/store/sqlite/vectors.js +90 -0
  377. package/dist/esm/store/sqlite/vectors.js.map +1 -0
  378. package/dist/esm/store/transaction.d.ts +5 -0
  379. package/dist/esm/store/transaction.js +57 -0
  380. package/dist/esm/store/transaction.js.map +1 -0
  381. package/dist/esm/store/types.d.ts +91 -0
  382. package/dist/esm/store/types.js +11 -0
  383. package/dist/esm/store/types.js.map +1 -0
  384. package/dist/esm/watch.d.ts +3 -0
  385. package/dist/esm/watch.js +39 -22
  386. package/dist/esm/watch.js.map +1 -1
  387. package/package.json +3 -1
  388. package/schema.json +5 -0
  389. package/skills/sense/EXAMPLES.md +3 -3
  390. package/skills/sense/SKILL.md +16 -14
  391. package/skills/sense-bases/EXAMPLES.md +2 -2
  392. package/skills/sense-bases/SKILL.md +6 -6
  393. package/skills/sense-setup/EXAMPLES.md +1 -1
  394. package/skills/sense-setup/SKILL.md +5 -4
  395. package/dist/cjs/db/index.d.cts +0 -4
  396. package/dist/cjs/db/index.d.ts +0 -4
  397. package/dist/cjs/db/index.js +0 -42
  398. package/dist/cjs/db/index.js.map +0 -1
  399. package/dist/cjs/db/open.js +0 -230
  400. package/dist/cjs/db/open.js.map +0 -1
  401. package/dist/cjs/db/reconcile.d.cts +0 -10
  402. package/dist/cjs/db/reconcile.d.ts +0 -10
  403. package/dist/cjs/db/reconcile.js +0 -579
  404. package/dist/cjs/db/reconcile.js.map +0 -1
  405. package/dist/cjs/db/shared.d.cts +0 -5
  406. package/dist/cjs/db/shared.d.ts +0 -5
  407. package/dist/cjs/db/shared.js +0 -45
  408. package/dist/cjs/db/shared.js.map +0 -1
  409. package/dist/cjs/db/sql-functions.js +0 -64
  410. package/dist/cjs/db/sql-functions.js.map +0 -1
  411. package/dist/esm/db/index.d.ts +0 -4
  412. package/dist/esm/db/index.js +0 -5
  413. package/dist/esm/db/index.js.map +0 -1
  414. package/dist/esm/db/open.js +0 -165
  415. package/dist/esm/db/open.js.map +0 -1
  416. package/dist/esm/db/reconcile.d.ts +0 -10
  417. package/dist/esm/db/reconcile.js.map +0 -1
  418. package/dist/esm/db/shared.d.ts +0 -5
  419. package/dist/esm/db/shared.js +0 -20
  420. package/dist/esm/db/shared.js.map +0 -1
  421. package/dist/esm/db/sql-functions.js +0 -47
  422. package/dist/esm/db/sql-functions.js.map +0 -1
  423. /package/dist/cjs/{db → store/sqlite}/sql-functions.d.cts +0 -0
  424. /package/dist/cjs/{db → store/sqlite}/sql-functions.d.ts +0 -0
  425. /package/dist/esm/{db → store/sqlite}/sql-functions.d.ts +0 -0
@@ -1,4 +1,4 @@
1
- export { anyPresetEmbeds, contentTokenize, embedConfig, embedEnabled, enabledFeatures, featureEnabled, featureSignature, featureStates, presetHasSignal, presetNames, presetSignals } from './access.js';
1
+ export { anyPresetEmbeds, contentTokenize, embedConfig, embedEnabled, enabledFeatures, featureEnabled, featureSignature, featureStates, presetHasSignal, presetNames, presetSignals, storeName } from './access.js';
2
2
  export type { InitOverrides } from './load.js';
3
3
  export { findConfigPath, initConfig, loadConfig, migrateConfig } from './load.js';
4
4
  export { resolvePreset, resolveSearch } from './resolve.js';
@@ -80,6 +80,9 @@ _export(exports, {
80
80
  },
81
81
  get resolveSearch () {
82
82
  return _resolvets.resolveSearch;
83
+ },
84
+ get storeName () {
85
+ return _accessts.storeName;
83
86
  }
84
87
  });
85
88
  var _accessts = require("./access.js");
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/config/index.ts"],"sourcesContent":["export { anyPresetEmbeds, contentTokenize, embedConfig, embedEnabled, enabledFeatures, featureEnabled, featureSignature, featureStates, presetHasSignal, presetNames, presetSignals } from './access.ts';\nexport type { InitOverrides } from './load.ts';\nexport { findConfigPath, initConfig, loadConfig, migrateConfig } from './load.ts';\nexport { resolvePreset, resolveSearch } from './resolve.ts';\nexport type { SignalName, SignalWeights } from './signals.ts';\nexport { SIGNAL_NAMES, SIGNAL_PREREQUISITES } from './signals.ts';\nexport type { Config, EffectiveSearch, EmbedConfig, FeatureName, Preset, ResolvedConfig, SavedQuery, SavedSearch, SearchOverrides } from './types.ts';\nexport { CONFIG_FILENAME, DEFAULT_EMBED_MODEL, STATE_DIR, SUPPORTED_CONFIG_VERSION } from './types.ts';\nexport { KNOWN_EMBED_KEYS } from './validate.ts';\n"],"names":["CONFIG_FILENAME","DEFAULT_EMBED_MODEL","KNOWN_EMBED_KEYS","SIGNAL_NAMES","SIGNAL_PREREQUISITES","STATE_DIR","SUPPORTED_CONFIG_VERSION","anyPresetEmbeds","contentTokenize","embedConfig","embedEnabled","enabledFeatures","featureEnabled","featureSignature","featureStates","findConfigPath","initConfig","loadConfig","migrateConfig","presetHasSignal","presetNames","presetSignals","resolvePreset","resolveSearch"],"mappings":";;;;;;;;;;;QAOSA;eAAAA,wBAAe;;QAAEC;eAAAA,4BAAmB;;QACpCC;eAAAA,4BAAgB;;QAHhBC;eAAAA,uBAAY;;QAAEC;eAAAA,+BAAoB;;QAEIC;eAAAA,kBAAS;;QAAEC;eAAAA,iCAAwB;;QAPzEC;eAAAA,yBAAe;;QAAEC;eAAAA,yBAAe;;QAAEC;eAAAA,qBAAW;;QAAEC;eAAAA,sBAAY;;QAAEC;eAAAA,yBAAe;;QAAEC;eAAAA,wBAAc;;QAAEC;eAAAA,0BAAgB;;QAAEC;eAAAA,uBAAa;;QAE7HC;eAAAA,sBAAc;;QAAEC;eAAAA,kBAAU;;QAAEC;eAAAA,kBAAU;;QAAEC;eAAAA,qBAAa;;QAF0EC;eAAAA,yBAAe;;QAAEC;eAAAA,qBAAW;;QAAEC;eAAAA,uBAAa;;QAG1KC;eAAAA,wBAAa;;QAAEC;eAAAA,wBAAa;;;wBAHsJ;sBAErH;yBACzB;yBAEM;uBAEuC;0BACzD"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/config/index.ts"],"sourcesContent":["export { anyPresetEmbeds, contentTokenize, embedConfig, embedEnabled, enabledFeatures, featureEnabled, featureSignature, featureStates, presetHasSignal, presetNames, presetSignals, storeName } from './access.ts';\nexport type { InitOverrides } from './load.ts';\nexport { findConfigPath, initConfig, loadConfig, migrateConfig } from './load.ts';\nexport { resolvePreset, resolveSearch } from './resolve.ts';\nexport type { SignalName, SignalWeights } from './signals.ts';\nexport { SIGNAL_NAMES, SIGNAL_PREREQUISITES } from './signals.ts';\nexport type { Config, EffectiveSearch, EmbedConfig, FeatureName, Preset, ResolvedConfig, SavedQuery, SavedSearch, SearchOverrides } from './types.ts';\nexport { CONFIG_FILENAME, DEFAULT_EMBED_MODEL, STATE_DIR, SUPPORTED_CONFIG_VERSION } from './types.ts';\nexport { KNOWN_EMBED_KEYS } from './validate.ts';\n"],"names":["CONFIG_FILENAME","DEFAULT_EMBED_MODEL","KNOWN_EMBED_KEYS","SIGNAL_NAMES","SIGNAL_PREREQUISITES","STATE_DIR","SUPPORTED_CONFIG_VERSION","anyPresetEmbeds","contentTokenize","embedConfig","embedEnabled","enabledFeatures","featureEnabled","featureSignature","featureStates","findConfigPath","initConfig","loadConfig","migrateConfig","presetHasSignal","presetNames","presetSignals","resolvePreset","resolveSearch","storeName"],"mappings":";;;;;;;;;;;QAOSA;eAAAA,wBAAe;;QAAEC;eAAAA,4BAAmB;;QACpCC;eAAAA,4BAAgB;;QAHhBC;eAAAA,uBAAY;;QAAEC;eAAAA,+BAAoB;;QAEIC;eAAAA,kBAAS;;QAAEC;eAAAA,iCAAwB;;QAPzEC;eAAAA,yBAAe;;QAAEC;eAAAA,yBAAe;;QAAEC;eAAAA,qBAAW;;QAAEC;eAAAA,sBAAY;;QAAEC;eAAAA,yBAAe;;QAAEC;eAAAA,wBAAc;;QAAEC;eAAAA,0BAAgB;;QAAEC;eAAAA,uBAAa;;QAE7HC;eAAAA,sBAAc;;QAAEC;eAAAA,kBAAU;;QAAEC;eAAAA,kBAAU;;QAAEC;eAAAA,qBAAa;;QAF0EC;eAAAA,yBAAe;;QAAEC;eAAAA,qBAAW;;QAAEC;eAAAA,uBAAa;;QAG1KC;eAAAA,wBAAa;;QAAEC;eAAAA,wBAAa;;QAHgJC;eAAAA,mBAAS;;;wBAAQ;sBAEhI;yBACzB;yBAEM;uBAEuC;0BACzD"}
@@ -45,6 +45,7 @@ export interface Config {
45
45
  content?: {
46
46
  tokenize?: string;
47
47
  };
48
+ store?: 'sqlite' | 'duckdb';
48
49
  queries: Record<string, SavedQuery>;
49
50
  }
50
51
  export interface ResolvedConfig extends Config {
@@ -45,6 +45,7 @@ export interface Config {
45
45
  content?: {
46
46
  tokenize?: string;
47
47
  };
48
+ store?: 'sqlite' | 'duckdb';
48
49
  queries: Record<string, SavedQuery>;
49
50
  }
50
51
  export interface ResolvedConfig extends Config {
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/config/types.ts"],"sourcesContent":["import type { SignalWeights } from './signals.ts';\n\nexport const CONFIG_FILENAME = 'sense.config.json';\nexport const STATE_DIR = '.sense';\n\n// Highest sense.config.json `version` this build understands. Older versions auto-migrate on load.\nexport const SUPPORTED_CONFIG_VERSION = 5;\n\n// Each feature owns its tables, parse-time extraction, and reconcile step; commands degrade when one is off.\n// links/sections/tags/rank are opt-out toggles in the top-level `features` block; embed is not a\n// member of that block -- it is on exactly when an `embed` block names a model.\nexport const FEATURE_NAMES = ['links', 'sections', 'tags', 'rank', 'embed'] as const;\nexport type FeatureName = (typeof FEATURE_NAMES)[number];\n\n// `embed` names the model and gives the tree vectors at all; a preset's `signals` says which\n// engines that scope's searches use.\nexport interface EmbedConfig {\n model?: string;\n provider?: 'static' | 'openai' | 'cohere';\n url?: string; // openai provider: OpenAI-compatible base URL, e.g. http://localhost:11434/v1\n key?: string; // openai/cohere provider: name of the env var holding the bearer token, if any\n languages?: string[]; // owner-declared model languages; enables the language-fit check where no card exists\n chunkTokens?: number; // chunk size ceiling in estimated tokens for small-context models; default 500\n}\n\nexport const DEFAULT_EMBED_MODEL = 'minishlab/potion-retrieval-32M';\n\n// A named, self-contained file-selection scope. include/exclude are globby patterns resolved\n// relative to the config file. No inheritance between presets -- every field a preset wants\n// it declares itself. Presets may overlap freely; they are views, not partitions.\nexport interface Preset {\n include: string[];\n exclude?: string[];\n k?: number; // result count for `search` scoped to this preset; default 10\n // Exhaustive when present: every signal this preset's searches compose, each mapped to\n // its RRF weight (a finite number > 0; presence is enablement). Absent means every signal\n // whose prerequisite holds, each at weight 1 -- words always, links when the feature is on,\n // vectors when the tree names a model. A layer searched for exact wording (ingested sources,\n // archives, generated output) declares {\"words\":1,\"links\":1} and costs no embedding at all.\n signals?: SignalWeights;\n where?: string; // standing SQL condition against frontmatter alias `f`\n}\n\n// A saved `search` invocation: `sense <name>` runs like\n// `sense search <search> [--preset] [--include] [--exclude] [--where] [--k]`.\nexport interface SavedSearch {\n search: string;\n preset?: string;\n include?: string[];\n exclude?: string[];\n where?: string;\n k?: number;\n}\n\n// An entry names the verb it runs, one to one with the commands: { sql } runs like\n// `sense sql`, { search } like `sense search`.\nexport type SavedQuery = { sql: string } | SavedSearch;\n\nexport interface Config {\n // Editor-only pointer to schema.json; never read by sense.\n $schema?: string;\n version?: number;\n // File selection, index-time, and per-preset search defaults. A file is indexed iff any\n // preset's include/exclude covers it (union). `default` is used when a command names no preset.\n presets: Record<string, Preset>;\n // Global feature defaults; absent block or key means enabled. embed is not a member here --\n // see the `embed` block.\n features?: { links?: boolean; sections?: boolean; tags?: boolean; rank?: boolean };\n // Names the embedding model. Present means every indexed file gets vectors; absent means none do.\n embed?: EmbedConfig;\n // Settings for the `content` FTS5 table. `tokenize` decides which languages the tree can be\n // word-searched in at all; changing it rebuilds the index.\n content?: { tokenize?: string };\n queries: Record<string, SavedQuery>;\n}\n\nexport interface ResolvedConfig extends Config {\n baseDir: string;\n configPath: string | null;\n // Keys the file declares that this build does not read; cli reports them.\n unknownKeys?: string[];\n // Set when loadConfig auto-migrated the file on disk; cli reports it.\n migratedFrom?: number;\n}\n\nexport interface SearchOverrides {\n preset?: string;\n k?: number;\n where?: string;\n include?: string[];\n exclude?: string[];\n noExclude?: boolean; // drop the preset's exclude for this command; --exclude still applies\n}\n\nexport interface EffectiveSearch {\n presetName: string;\n k: number;\n where?: string;\n include: string[];\n exclude?: string[];\n signals: SignalWeights; // this preset's effective signal weights\n}\n"],"names":["CONFIG_FILENAME","DEFAULT_EMBED_MODEL","FEATURE_NAMES","STATE_DIR","SUPPORTED_CONFIG_VERSION"],"mappings":";;;;;;;;;;;QAEaA;eAAAA;;QAuBAC;eAAAA;;QAdAC;eAAAA;;QARAC;eAAAA;;QAGAC;eAAAA;;;AAJN,IAAMJ,kBAAkB;AACxB,IAAMG,YAAY;AAGlB,IAAMC,2BAA2B;AAKjC,IAAMF,gBAAgB;IAAC;IAAS;IAAY;IAAQ;IAAQ;CAAQ;AAcpE,IAAMD,sBAAsB"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/config/types.ts"],"sourcesContent":["import type { SignalWeights } from './signals.ts';\n\nexport const CONFIG_FILENAME = 'sense.config.json';\nexport const STATE_DIR = '.sense';\n\n// Highest sense.config.json `version` this build understands. Older versions auto-migrate on load.\nexport const SUPPORTED_CONFIG_VERSION = 5;\n\n// Each feature owns its tables, parse-time extraction, and reconcile step; commands degrade when one is off.\n// links/sections/tags/rank are opt-out toggles in the top-level `features` block; embed is not a\n// member of that block -- it is on exactly when an `embed` block names a model.\nexport const FEATURE_NAMES = ['links', 'sections', 'tags', 'rank', 'embed'] as const;\nexport type FeatureName = (typeof FEATURE_NAMES)[number];\n\n// `embed` names the model and gives the tree vectors at all; a preset's `signals` says which\n// engines that scope's searches use.\nexport interface EmbedConfig {\n model?: string;\n provider?: 'static' | 'openai' | 'cohere';\n url?: string; // openai provider: OpenAI-compatible base URL, e.g. http://localhost:11434/v1\n key?: string; // openai/cohere provider: name of the env var holding the bearer token, if any\n languages?: string[]; // owner-declared model languages; enables the language-fit check where no card exists\n chunkTokens?: number; // chunk size ceiling in estimated tokens for small-context models; default 500\n}\n\nexport const DEFAULT_EMBED_MODEL = 'minishlab/potion-retrieval-32M';\n\n// A named, self-contained file-selection scope. include/exclude are globby patterns resolved\n// relative to the config file. No inheritance between presets -- every field a preset wants\n// it declares itself. Presets may overlap freely; they are views, not partitions.\nexport interface Preset {\n include: string[];\n exclude?: string[];\n k?: number; // result count for `search` scoped to this preset; default 10\n // Exhaustive when present: every signal this preset's searches compose, each mapped to\n // its RRF weight (a finite number > 0; presence is enablement). Absent means every signal\n // whose prerequisite holds, each at weight 1 -- words always, links when the feature is on,\n // vectors when the tree names a model. A layer searched for exact wording (ingested sources,\n // archives, generated output) declares {\"words\":1,\"links\":1} and costs no embedding at all.\n signals?: SignalWeights;\n where?: string; // standing SQL condition against frontmatter alias `f`\n}\n\n// A saved `search` invocation: `sense <name>` runs like\n// `sense search <search> [--preset] [--include] [--exclude] [--where] [--k]`.\nexport interface SavedSearch {\n search: string;\n preset?: string;\n include?: string[];\n exclude?: string[];\n where?: string;\n k?: number;\n}\n\n// An entry names the verb it runs, one to one with the commands: { sql } runs like\n// `sense sql`, { search } like `sense search`.\nexport type SavedQuery = { sql: string } | SavedSearch;\n\nexport interface Config {\n // Editor-only pointer to schema.json; never read by sense.\n $schema?: string;\n version?: number;\n // File selection, index-time, and per-preset search defaults. A file is indexed iff any\n // preset's include/exclude covers it (union). `default` is used when a command names no preset.\n presets: Record<string, Preset>;\n // Global feature defaults; absent block or key means enabled. embed is not a member here --\n // see the `embed` block.\n features?: { links?: boolean; sections?: boolean; tags?: boolean; rank?: boolean };\n // Names the embedding model. Present means every indexed file gets vectors; absent means none do.\n embed?: EmbedConfig;\n // Settings for the `content` FTS5 table. `tokenize` decides which languages the tree can be\n // word-searched in at all; changing it rebuilds the index.\n content?: { tokenize?: string };\n // Backing store engine for this tree; defaults to \"sqlite\" (zero-dependency). \"duckdb\" is an\n // optional dependency and, in this build, implements only the portable surface (frontmatter,\n // links, sections, tags, rank, raw sql) -- a config needing lexical or vector search under it fails at open.\n store?: 'sqlite' | 'duckdb';\n queries: Record<string, SavedQuery>;\n}\n\nexport interface ResolvedConfig extends Config {\n baseDir: string;\n configPath: string | null;\n // Keys the file declares that this build does not read; cli reports them.\n unknownKeys?: string[];\n // Set when loadConfig auto-migrated the file on disk; cli reports it.\n migratedFrom?: number;\n}\n\nexport interface SearchOverrides {\n preset?: string;\n k?: number;\n where?: string;\n include?: string[];\n exclude?: string[];\n noExclude?: boolean; // drop the preset's exclude for this command; --exclude still applies\n}\n\nexport interface EffectiveSearch {\n presetName: string;\n k: number;\n where?: string;\n include: string[];\n exclude?: string[];\n signals: SignalWeights; // this preset's effective signal weights\n}\n"],"names":["CONFIG_FILENAME","DEFAULT_EMBED_MODEL","FEATURE_NAMES","STATE_DIR","SUPPORTED_CONFIG_VERSION"],"mappings":";;;;;;;;;;;QAEaA;eAAAA;;QAuBAC;eAAAA;;QAdAC;eAAAA;;QARAC;eAAAA;;QAGAC;eAAAA;;;AAJN,IAAMJ,kBAAkB;AACxB,IAAMG,YAAY;AAGlB,IAAMC,2BAA2B;AAKjC,IAAMF,gBAAgB;IAAC;IAAS;IAAY;IAAQ;IAAQ;CAAQ;AAcpE,IAAMD,sBAAsB"}
@@ -83,6 +83,7 @@ var KNOWN_KEYS = new Set([
83
83
  'features',
84
84
  'embed',
85
85
  'content',
86
+ 'store',
86
87
  'queries'
87
88
  ]);
88
89
  var KNOWN_PRESET_KEYS = new Set([
@@ -135,7 +136,7 @@ function validateLegacyScan(parsed, configPath) {
135
136
  }
136
137
  }
137
138
  // Only the shape is checked here. Whether the linked SQLite accepts the tokenizer is settled
138
- // by probing it in db.ts, so this never has to carry a table of which version added what.
139
+ // by probing it in store/sqlite/open.ts, so this never has to carry a table of which version added what.
139
140
  function validateContentBlock(value, configPath) {
140
141
  if ((typeof value === "undefined" ? "undefined" : _type_of(value)) !== 'object' || value === null || Array.isArray(value)) {
141
142
  throw new _errorsts.SenseError('CONFIG_INVALID', "".concat(configPath, ": content must be an object of { tokenize?: string }"));
@@ -151,6 +152,11 @@ function validateContentBlock(value, configPath) {
151
152
  throw new _errorsts.SenseError('CONFIG_INVALID', "".concat(configPath, ': content.tokenize must be a non-empty string, e.g. "trigram" or "unicode61 tokenchars \'-_\'"'));
152
153
  }
153
154
  }
155
+ function validateStoreKey(value, configPath) {
156
+ if (value !== 'sqlite' && value !== 'duckdb') {
157
+ throw new _errorsts.SenseError('CONFIG_INVALID', "".concat(configPath, ': store must be "sqlite" or "duckdb"'));
158
+ }
159
+ }
154
160
  function validateFeaturesBlock(value, configPath) {
155
161
  if ((typeof value === "undefined" ? "undefined" : _type_of(value)) !== 'object' || value === null || Array.isArray(value)) {
156
162
  throw new _errorsts.SenseError('CONFIG_INVALID', "".concat(configPath, ": features must be an object of name -> boolean"));
@@ -448,6 +454,9 @@ function validateConfig(parsed, configPath) {
448
454
  if (cfg.content !== undefined) {
449
455
  validateContentBlock(cfg.content, configPath);
450
456
  }
457
+ if (cfg.store !== undefined) {
458
+ validateStoreKey(cfg.store, configPath);
459
+ }
451
460
  // vectors' prerequisite is a named model, checked here once embed is known valid (or absent).
452
461
  if (cfg.embed === undefined) {
453
462
  var _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = undefined;
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/config/validate.ts"],"sourcesContent":["import { SenseError } from '../errors.ts';\nimport { SIGNAL_NAMES, SIGNAL_PREREQUISITES, type SignalName } from './signals.ts';\nimport type { Config } from './types.ts';\n\n// Shape check for hand-edited files, so a typo names itself instead of surfacing as a\n// TypeError. Unknown top-level keys warn (forward compat); unknown keys inside a block error.\nconst KNOWN_KEYS = new Set(['$schema', 'version', 'presets', 'features', 'embed', 'content', 'queries']);\nconst KNOWN_PRESET_KEYS = new Set(['include', 'exclude', 'k', 'signals', 'where']);\nconst KNOWN_FEATURE_KEYS = new Set(['links', 'sections', 'tags', 'rank']);\n// Exported so a docs test can assert every key here has a schema.json property -- one source\n// of truth for what the embed block accepts, checked against the other for drift.\nexport const KNOWN_EMBED_KEYS = new Set(['model', 'provider', 'url', 'key', 'languages', 'chunkTokens']);\nconst KNOWN_CONTENT_KEYS = new Set(['tokenize']);\nconst SAVED_SEARCH_KEYS = new Set(['search', 'preset', 'include', 'exclude', 'where', 'k']);\n\nexport function unknownConfigKeys(cfg: Record<string, unknown>): string[] {\n return Object.keys(cfg).filter((k) => !KNOWN_KEYS.has(k));\n}\n\nfunction isNonEmptyStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.length > 0 && value.every((g) => typeof g === 'string' && g.length > 0);\n}\n\n// Pre-v3 shape check, just enough for migrateConfig to run safely (it reads scan.include\n// directly). The full v3 shape is checked by validateConfig once migration has produced it.\nexport function validateLegacyScan(parsed: unknown, configPath: string): void {\n const cfg = typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed) ? (parsed as Record<string, unknown>) : null;\n const scan = cfg?.scan as { include?: unknown } | undefined;\n if (!cfg || !scan || !isNonEmptyStringArray(scan.include)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: scan.include must be a non-empty array of glob strings`);\n }\n}\n\n// Only the shape is checked here. Whether the linked SQLite accepts the tokenizer is settled\n// by probing it in db.ts, so this never has to carry a table of which version added what.\nfunction validateContentBlock(value: unknown, configPath: string): void {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: content must be an object of { tokenize?: string }`);\n }\n const block = value as Record<string, unknown>;\n const unknown = Object.keys(block).filter((k) => !KNOWN_CONTENT_KEYS.has(k));\n if (unknown.length > 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: content has unknown key(s) ${unknown.join(', ')}; content takes tokenize`);\n }\n if (block.tokenize !== undefined && (typeof block.tokenize !== 'string' || block.tokenize.trim() === '')) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: content.tokenize must be a non-empty string, e.g. \"trigram\" or \"unicode61 tokenchars '-_'\"`);\n }\n}\n\nfunction validateFeaturesBlock(value: unknown, configPath: string): void {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: features must be an object of name -> boolean`);\n }\n const block = value as Record<string, unknown>;\n const unknown = Object.keys(block).filter((k) => !KNOWN_FEATURE_KEYS.has(k));\n if (unknown.length > 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: features has unknown key(s) ${unknown.join(', ')}; embed is not a features key -- see the top-level \"embed\" block`);\n }\n for (const [name, v] of Object.entries(block)) {\n if (typeof v !== 'boolean') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: features.${name} must be a boolean`);\n }\n }\n}\n\nfunction validateEmbedBlock(value: unknown, configPath: string): void {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed must be an object of { model?, provider?: \"static\"|\"openai\"|\"cohere\", url?, key? }`);\n }\n const embed = value as Record<string, unknown>;\n const unknown = Object.keys(embed).filter((k) => !KNOWN_EMBED_KEYS.has(k));\n if (unknown.length > 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed has unknown key(s) ${unknown.join(', ')}`);\n }\n if (embed.model !== undefined && typeof embed.model !== 'string') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.model must be a string`);\n }\n // The block exists to name a model; provider settings without one would read as \"vectors\n // configured\" while embedding stays off, which is the ambiguity v4 removed.\n if (embed.model === undefined || embed.model === '') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.model is required when the \"embed\" block is present (it is what turns vectors on); remove the block to index without vectors`);\n }\n if (embed.provider !== undefined && embed.provider !== 'static' && embed.provider !== 'openai' && embed.provider !== 'cohere') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.provider must be \"static\", \"openai\", or \"cohere\"`);\n }\n if (embed.url !== undefined && typeof embed.url !== 'string') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.url must be a string`);\n }\n if (embed.key !== undefined && typeof embed.key !== 'string') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.key must be a string`);\n }\n // openai has no default host, so a missing url would otherwise only surface at the first\n // vector search; a config error belongs at config time.\n if (embed.provider === 'openai' && (embed.url === undefined || embed.url === '')) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.provider \"openai\" requires embed.url (e.g. \"http://localhost:11434/v1\" for Ollama)`);\n }\n if (embed.languages !== undefined && (!Array.isArray(embed.languages) || embed.languages.length === 0 || embed.languages.some((l) => typeof l !== 'string' || l === ''))) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.languages must be a non-empty array of language tags (e.g. [\"en\", \"zh\"])`);\n }\n if (embed.chunkTokens !== undefined && (typeof embed.chunkTokens !== 'number' || !Number.isInteger(embed.chunkTokens) || embed.chunkTokens <= 0)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.chunkTokens must be a positive integer`);\n }\n}\n\nfunction isSignalName(value: unknown): value is SignalName {\n return typeof value === 'string' && (SIGNAL_NAMES as readonly string[]).includes(value);\n}\n\nfunction isSignalWeight(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value) && value > 0;\n}\n\n// Shape (an object of signal name -> weight) plus the one cross-signal prerequisite that\n// doesn't need the top-level embed block: links is seeded by word-match rows, so declaring it\n// without words is always empty.\nfunction validatePresetSignals(name: string, value: unknown, configPath: string): void {\n if (typeof value !== 'object' || value === null || Array.isArray(value) || Object.keys(value).length === 0) {\n throw new SenseError(\n 'CONFIG_INVALID',\n `${configPath}: presets.${name}.signals must be a non-empty object of signal name -> weight (a finite number > 0), naming ${SIGNAL_NAMES.join(', ')} -- a preset that searches nothing is a mistake; name at least \"words\", or omit \"signals\" to use every signal whose prerequisites hold at weight 1`\n );\n }\n const entries = Object.entries(value as Record<string, unknown>);\n const unknown = entries.filter(([k]) => !isSignalName(k)).map(([k]) => k);\n if (unknown.length > 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.signals names unknown signal(s) ${unknown.join(', ')}; valid signals are ${SIGNAL_NAMES.join(', ')}`);\n }\n for (const [signal, weight] of entries) {\n if (!isSignalWeight(weight)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.signals.${signal} must be a finite number > 0`);\n }\n }\n const names = new Set(entries.map(([k]) => k));\n for (const [signal, requires] of Object.entries(SIGNAL_PREREQUISITES) as Array<[SignalName, SignalName]>) {\n if (names.has(signal) && !names.has(requires)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.signals has \"${signal}\" without \"${requires}\"; add \"${requires}\" to presets.${name}.signals, or drop \"${signal}\"`);\n }\n }\n}\n\nfunction validatePreset(name: string, value: unknown, configPath: string): void {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name} must be an object`);\n }\n const preset = value as Record<string, unknown>;\n const unknown = Object.keys(preset).filter((k) => !KNOWN_PRESET_KEYS.has(k));\n if (unknown.length > 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name} has unknown key(s) ${unknown.join(', ')}; a preset takes include, exclude, k, signals, where`);\n }\n if (!isNonEmptyStringArray(preset.include)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.include must be a non-empty array of glob strings`);\n }\n if (preset.exclude !== undefined && !isNonEmptyStringArray(preset.exclude)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.exclude must be a non-empty array of glob strings`);\n }\n if (preset.signals !== undefined) validatePresetSignals(name, preset.signals, configPath);\n if (preset.k !== undefined && (typeof preset.k !== 'number' || !Number.isInteger(preset.k) || preset.k <= 0)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.k must be a positive integer`);\n }\n if (preset.where !== undefined && typeof preset.where !== 'string') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.where must be a SQL condition string`);\n }\n}\n\n// A queries.<name> entry: { sql } or a saved search { search, preset?, include?, exclude?, where?, k? }.\nfunction validateSavedQuery(name: string, value: unknown, configPath: string): void {\n // A bare string used to mean SQL. It now fails rather than being inferred: an entry says\n // which of the two verbs it runs, the same choice the CLI makes explicit.\n if (typeof value === 'string') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name} must say which verb it runs: { \"sql\": ${JSON.stringify(value.length > 40 ? `${value.slice(0, 37)}...` : value)} } to run it as SQL, or { \"search\": \"...\" } for a ranked search`);\n }\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name} must be { sql } or { search, preset?, include?, exclude?, where?, k? }`);\n }\n const entry = value as Record<string, unknown>;\n if ('sql' in entry) {\n const unknown = Object.keys(entry).filter((k) => k !== 'sql');\n if (unknown.length > 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name} has unknown key(s) ${unknown.join(', ')}; a { sql } query takes only sql`);\n }\n if (typeof entry.sql !== 'string' || entry.sql.trim() === '') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name}.sql must be a non-empty string`);\n }\n return;\n }\n if ('search' in entry) {\n const unknown = Object.keys(entry).filter((k) => !SAVED_SEARCH_KEYS.has(k));\n if (unknown.length > 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name} has unknown key(s) ${unknown.join(', ')}; a saved search takes search, preset, include, exclude, where, k`);\n }\n // A saved entry saves a question; a scope without a question is just flags.\n if (typeof entry.search !== 'string' || entry.search.trim() === '') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name}.search must be non-empty text`);\n }\n if (entry.preset !== undefined && (typeof entry.preset !== 'string' || entry.preset.length === 0)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name}.preset must be a preset name`);\n }\n if (entry.include !== undefined && !isNonEmptyStringArray(entry.include)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name}.include must be a non-empty array of glob strings`);\n }\n if (entry.exclude !== undefined && !isNonEmptyStringArray(entry.exclude)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name}.exclude must be a non-empty array of glob strings`);\n }\n if (entry.where !== undefined && typeof entry.where !== 'string') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name}.where must be a SQL condition string`);\n }\n if (entry.k !== undefined && (typeof entry.k !== 'number' || !Number.isInteger(entry.k) || entry.k <= 0)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name}.k must be a positive integer`);\n }\n return;\n }\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name} must be { sql } or { search, preset?, include?, exclude?, where?, k? }`);\n}\n\nexport function validateConfig(parsed: unknown, configPath: string): Config {\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: config must be a JSON object`);\n }\n const cfg = parsed as Record<string, unknown>;\n\n // `checks` is rejected by name, not warned: silence would hide that assertions are gone.\n if (cfg.checks !== undefined) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: checks was removed in v3 -- sense check no longer asserts on saved queries; a returned row set is the reader's judgment`);\n }\n\n const presets = cfg.presets as Record<string, unknown> | undefined;\n if (!presets || typeof presets !== 'object' || Array.isArray(presets) || Object.keys(presets).length === 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets must be a non-empty object of preset name -> { include, exclude?, k?, signals?, where? }`);\n }\n for (const [name, value] of Object.entries(presets)) {\n validatePreset(name, value, configPath);\n }\n if (presets.default === undefined) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets must include a \"default\" preset`);\n }\n\n if (cfg.queries === undefined) cfg.queries = {};\n if (typeof cfg.queries !== 'object' || cfg.queries === null || Array.isArray(cfg.queries)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries must be an object of name -> { sql } or { search }`);\n }\n const queries = cfg.queries as Record<string, unknown>;\n for (const [name, value] of Object.entries(queries)) {\n validateSavedQuery(name, value, configPath);\n }\n\n if (cfg.features !== undefined) {\n validateFeaturesBlock(cfg.features, configPath);\n }\n if (cfg.embed !== undefined) {\n validateEmbedBlock(cfg.embed, configPath);\n }\n if (cfg.content !== undefined) {\n validateContentBlock(cfg.content, configPath);\n }\n\n // vectors' prerequisite is a named model, checked here once embed is known valid (or absent).\n if (cfg.embed === undefined) {\n for (const [name, value] of Object.entries(presets)) {\n const signals = (value as Record<string, unknown>).signals as Record<string, unknown> | undefined;\n if (signals && 'vectors' in signals) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.signals includes \"vectors\", but no \"embed\" block names a model; add one, or drop \"vectors\" from presets.${name}.signals`);\n }\n }\n }\n\n return cfg as unknown as Config;\n}\n"],"names":["KNOWN_EMBED_KEYS","unknownConfigKeys","validateConfig","validateLegacyScan","KNOWN_KEYS","Set","KNOWN_PRESET_KEYS","KNOWN_FEATURE_KEYS","KNOWN_CONTENT_KEYS","SAVED_SEARCH_KEYS","cfg","Object","keys","filter","k","has","isNonEmptyStringArray","value","Array","isArray","length","every","g","parsed","configPath","scan","include","SenseError","validateContentBlock","block","unknown","join","tokenize","undefined","trim","validateFeaturesBlock","entries","name","v","validateEmbedBlock","embed","model","provider","url","key","languages","some","l","chunkTokens","Number","isInteger","isSignalName","SIGNAL_NAMES","includes","isSignalWeight","isFinite","validatePresetSignals","map","signal","weight","names","SIGNAL_PREREQUISITES","requires","validatePreset","preset","exclude","signals","where","validateSavedQuery","JSON","stringify","slice","entry","sql","search","checks","presets","default","queries","features","content"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/config/validate.ts"],"sourcesContent":["import { SenseError } from '../errors.ts';\nimport { SIGNAL_NAMES, SIGNAL_PREREQUISITES, type SignalName } from './signals.ts';\nimport type { Config } from './types.ts';\n\n// Shape check for hand-edited files, so a typo names itself instead of surfacing as a\n// TypeError. Unknown top-level keys warn (forward compat); unknown keys inside a block error.\nconst KNOWN_KEYS = new Set(['$schema', 'version', 'presets', 'features', 'embed', 'content', 'store', 'queries']);\nconst KNOWN_PRESET_KEYS = new Set(['include', 'exclude', 'k', 'signals', 'where']);\nconst KNOWN_FEATURE_KEYS = new Set(['links', 'sections', 'tags', 'rank']);\n// Exported so a docs test can assert every key here has a schema.json property -- one source\n// of truth for what the embed block accepts, checked against the other for drift.\nexport const KNOWN_EMBED_KEYS = new Set(['model', 'provider', 'url', 'key', 'languages', 'chunkTokens']);\nconst KNOWN_CONTENT_KEYS = new Set(['tokenize']);\nconst SAVED_SEARCH_KEYS = new Set(['search', 'preset', 'include', 'exclude', 'where', 'k']);\n\nexport function unknownConfigKeys(cfg: Record<string, unknown>): string[] {\n return Object.keys(cfg).filter((k) => !KNOWN_KEYS.has(k));\n}\n\nfunction isNonEmptyStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.length > 0 && value.every((g) => typeof g === 'string' && g.length > 0);\n}\n\n// Pre-v3 shape check, just enough for migrateConfig to run safely (it reads scan.include\n// directly). The full v3 shape is checked by validateConfig once migration has produced it.\nexport function validateLegacyScan(parsed: unknown, configPath: string): void {\n const cfg = typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed) ? (parsed as Record<string, unknown>) : null;\n const scan = cfg?.scan as { include?: unknown } | undefined;\n if (!cfg || !scan || !isNonEmptyStringArray(scan.include)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: scan.include must be a non-empty array of glob strings`);\n }\n}\n\n// Only the shape is checked here. Whether the linked SQLite accepts the tokenizer is settled\n// by probing it in store/sqlite/open.ts, so this never has to carry a table of which version added what.\nfunction validateContentBlock(value: unknown, configPath: string): void {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: content must be an object of { tokenize?: string }`);\n }\n const block = value as Record<string, unknown>;\n const unknown = Object.keys(block).filter((k) => !KNOWN_CONTENT_KEYS.has(k));\n if (unknown.length > 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: content has unknown key(s) ${unknown.join(', ')}; content takes tokenize`);\n }\n if (block.tokenize !== undefined && (typeof block.tokenize !== 'string' || block.tokenize.trim() === '')) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: content.tokenize must be a non-empty string, e.g. \"trigram\" or \"unicode61 tokenchars '-_'\"`);\n }\n}\n\nfunction validateStoreKey(value: unknown, configPath: string): void {\n if (value !== 'sqlite' && value !== 'duckdb') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: store must be \"sqlite\" or \"duckdb\"`);\n }\n}\n\nfunction validateFeaturesBlock(value: unknown, configPath: string): void {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: features must be an object of name -> boolean`);\n }\n const block = value as Record<string, unknown>;\n const unknown = Object.keys(block).filter((k) => !KNOWN_FEATURE_KEYS.has(k));\n if (unknown.length > 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: features has unknown key(s) ${unknown.join(', ')}; embed is not a features key -- see the top-level \"embed\" block`);\n }\n for (const [name, v] of Object.entries(block)) {\n if (typeof v !== 'boolean') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: features.${name} must be a boolean`);\n }\n }\n}\n\nfunction validateEmbedBlock(value: unknown, configPath: string): void {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed must be an object of { model?, provider?: \"static\"|\"openai\"|\"cohere\", url?, key? }`);\n }\n const embed = value as Record<string, unknown>;\n const unknown = Object.keys(embed).filter((k) => !KNOWN_EMBED_KEYS.has(k));\n if (unknown.length > 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed has unknown key(s) ${unknown.join(', ')}`);\n }\n if (embed.model !== undefined && typeof embed.model !== 'string') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.model must be a string`);\n }\n // The block exists to name a model; provider settings without one would read as \"vectors\n // configured\" while embedding stays off, which is the ambiguity v4 removed.\n if (embed.model === undefined || embed.model === '') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.model is required when the \"embed\" block is present (it is what turns vectors on); remove the block to index without vectors`);\n }\n if (embed.provider !== undefined && embed.provider !== 'static' && embed.provider !== 'openai' && embed.provider !== 'cohere') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.provider must be \"static\", \"openai\", or \"cohere\"`);\n }\n if (embed.url !== undefined && typeof embed.url !== 'string') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.url must be a string`);\n }\n if (embed.key !== undefined && typeof embed.key !== 'string') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.key must be a string`);\n }\n // openai has no default host, so a missing url would otherwise only surface at the first\n // vector search; a config error belongs at config time.\n if (embed.provider === 'openai' && (embed.url === undefined || embed.url === '')) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.provider \"openai\" requires embed.url (e.g. \"http://localhost:11434/v1\" for Ollama)`);\n }\n if (embed.languages !== undefined && (!Array.isArray(embed.languages) || embed.languages.length === 0 || embed.languages.some((l) => typeof l !== 'string' || l === ''))) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.languages must be a non-empty array of language tags (e.g. [\"en\", \"zh\"])`);\n }\n if (embed.chunkTokens !== undefined && (typeof embed.chunkTokens !== 'number' || !Number.isInteger(embed.chunkTokens) || embed.chunkTokens <= 0)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: embed.chunkTokens must be a positive integer`);\n }\n}\n\nfunction isSignalName(value: unknown): value is SignalName {\n return typeof value === 'string' && (SIGNAL_NAMES as readonly string[]).includes(value);\n}\n\nfunction isSignalWeight(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value) && value > 0;\n}\n\n// Shape (an object of signal name -> weight) plus the one cross-signal prerequisite that\n// doesn't need the top-level embed block: links is seeded by word-match rows, so declaring it\n// without words is always empty.\nfunction validatePresetSignals(name: string, value: unknown, configPath: string): void {\n if (typeof value !== 'object' || value === null || Array.isArray(value) || Object.keys(value).length === 0) {\n throw new SenseError(\n 'CONFIG_INVALID',\n `${configPath}: presets.${name}.signals must be a non-empty object of signal name -> weight (a finite number > 0), naming ${SIGNAL_NAMES.join(', ')} -- a preset that searches nothing is a mistake; name at least \"words\", or omit \"signals\" to use every signal whose prerequisites hold at weight 1`\n );\n }\n const entries = Object.entries(value as Record<string, unknown>);\n const unknown = entries.filter(([k]) => !isSignalName(k)).map(([k]) => k);\n if (unknown.length > 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.signals names unknown signal(s) ${unknown.join(', ')}; valid signals are ${SIGNAL_NAMES.join(', ')}`);\n }\n for (const [signal, weight] of entries) {\n if (!isSignalWeight(weight)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.signals.${signal} must be a finite number > 0`);\n }\n }\n const names = new Set(entries.map(([k]) => k));\n for (const [signal, requires] of Object.entries(SIGNAL_PREREQUISITES) as Array<[SignalName, SignalName]>) {\n if (names.has(signal) && !names.has(requires)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.signals has \"${signal}\" without \"${requires}\"; add \"${requires}\" to presets.${name}.signals, or drop \"${signal}\"`);\n }\n }\n}\n\nfunction validatePreset(name: string, value: unknown, configPath: string): void {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name} must be an object`);\n }\n const preset = value as Record<string, unknown>;\n const unknown = Object.keys(preset).filter((k) => !KNOWN_PRESET_KEYS.has(k));\n if (unknown.length > 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name} has unknown key(s) ${unknown.join(', ')}; a preset takes include, exclude, k, signals, where`);\n }\n if (!isNonEmptyStringArray(preset.include)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.include must be a non-empty array of glob strings`);\n }\n if (preset.exclude !== undefined && !isNonEmptyStringArray(preset.exclude)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.exclude must be a non-empty array of glob strings`);\n }\n if (preset.signals !== undefined) validatePresetSignals(name, preset.signals, configPath);\n if (preset.k !== undefined && (typeof preset.k !== 'number' || !Number.isInteger(preset.k) || preset.k <= 0)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.k must be a positive integer`);\n }\n if (preset.where !== undefined && typeof preset.where !== 'string') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.where must be a SQL condition string`);\n }\n}\n\n// A queries.<name> entry: { sql } or a saved search { search, preset?, include?, exclude?, where?, k? }.\nfunction validateSavedQuery(name: string, value: unknown, configPath: string): void {\n // A bare string used to mean SQL. It now fails rather than being inferred: an entry says\n // which of the two verbs it runs, the same choice the CLI makes explicit.\n if (typeof value === 'string') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name} must say which verb it runs: { \"sql\": ${JSON.stringify(value.length > 40 ? `${value.slice(0, 37)}...` : value)} } to run it as SQL, or { \"search\": \"...\" } for a ranked search`);\n }\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name} must be { sql } or { search, preset?, include?, exclude?, where?, k? }`);\n }\n const entry = value as Record<string, unknown>;\n if ('sql' in entry) {\n const unknown = Object.keys(entry).filter((k) => k !== 'sql');\n if (unknown.length > 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name} has unknown key(s) ${unknown.join(', ')}; a { sql } query takes only sql`);\n }\n if (typeof entry.sql !== 'string' || entry.sql.trim() === '') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name}.sql must be a non-empty string`);\n }\n return;\n }\n if ('search' in entry) {\n const unknown = Object.keys(entry).filter((k) => !SAVED_SEARCH_KEYS.has(k));\n if (unknown.length > 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name} has unknown key(s) ${unknown.join(', ')}; a saved search takes search, preset, include, exclude, where, k`);\n }\n // A saved entry saves a question; a scope without a question is just flags.\n if (typeof entry.search !== 'string' || entry.search.trim() === '') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name}.search must be non-empty text`);\n }\n if (entry.preset !== undefined && (typeof entry.preset !== 'string' || entry.preset.length === 0)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name}.preset must be a preset name`);\n }\n if (entry.include !== undefined && !isNonEmptyStringArray(entry.include)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name}.include must be a non-empty array of glob strings`);\n }\n if (entry.exclude !== undefined && !isNonEmptyStringArray(entry.exclude)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name}.exclude must be a non-empty array of glob strings`);\n }\n if (entry.where !== undefined && typeof entry.where !== 'string') {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name}.where must be a SQL condition string`);\n }\n if (entry.k !== undefined && (typeof entry.k !== 'number' || !Number.isInteger(entry.k) || entry.k <= 0)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name}.k must be a positive integer`);\n }\n return;\n }\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries.${name} must be { sql } or { search, preset?, include?, exclude?, where?, k? }`);\n}\n\nexport function validateConfig(parsed: unknown, configPath: string): Config {\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: config must be a JSON object`);\n }\n const cfg = parsed as Record<string, unknown>;\n\n // `checks` is rejected by name, not warned: silence would hide that assertions are gone.\n if (cfg.checks !== undefined) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: checks was removed in v3 -- sense check no longer asserts on saved queries; a returned row set is the reader's judgment`);\n }\n\n const presets = cfg.presets as Record<string, unknown> | undefined;\n if (!presets || typeof presets !== 'object' || Array.isArray(presets) || Object.keys(presets).length === 0) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets must be a non-empty object of preset name -> { include, exclude?, k?, signals?, where? }`);\n }\n for (const [name, value] of Object.entries(presets)) {\n validatePreset(name, value, configPath);\n }\n if (presets.default === undefined) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets must include a \"default\" preset`);\n }\n\n if (cfg.queries === undefined) cfg.queries = {};\n if (typeof cfg.queries !== 'object' || cfg.queries === null || Array.isArray(cfg.queries)) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: queries must be an object of name -> { sql } or { search }`);\n }\n const queries = cfg.queries as Record<string, unknown>;\n for (const [name, value] of Object.entries(queries)) {\n validateSavedQuery(name, value, configPath);\n }\n\n if (cfg.features !== undefined) {\n validateFeaturesBlock(cfg.features, configPath);\n }\n if (cfg.embed !== undefined) {\n validateEmbedBlock(cfg.embed, configPath);\n }\n if (cfg.content !== undefined) {\n validateContentBlock(cfg.content, configPath);\n }\n if (cfg.store !== undefined) {\n validateStoreKey(cfg.store, configPath);\n }\n\n // vectors' prerequisite is a named model, checked here once embed is known valid (or absent).\n if (cfg.embed === undefined) {\n for (const [name, value] of Object.entries(presets)) {\n const signals = (value as Record<string, unknown>).signals as Record<string, unknown> | undefined;\n if (signals && 'vectors' in signals) {\n throw new SenseError('CONFIG_INVALID', `${configPath}: presets.${name}.signals includes \"vectors\", but no \"embed\" block names a model; add one, or drop \"vectors\" from presets.${name}.signals`);\n }\n }\n }\n\n return cfg as unknown as Config;\n}\n"],"names":["KNOWN_EMBED_KEYS","unknownConfigKeys","validateConfig","validateLegacyScan","KNOWN_KEYS","Set","KNOWN_PRESET_KEYS","KNOWN_FEATURE_KEYS","KNOWN_CONTENT_KEYS","SAVED_SEARCH_KEYS","cfg","Object","keys","filter","k","has","isNonEmptyStringArray","value","Array","isArray","length","every","g","parsed","configPath","scan","include","SenseError","validateContentBlock","block","unknown","join","tokenize","undefined","trim","validateStoreKey","validateFeaturesBlock","entries","name","v","validateEmbedBlock","embed","model","provider","url","key","languages","some","l","chunkTokens","Number","isInteger","isSignalName","SIGNAL_NAMES","includes","isSignalWeight","isFinite","validatePresetSignals","map","signal","weight","names","SIGNAL_PREREQUISITES","requires","validatePreset","preset","exclude","signals","where","validateSavedQuery","JSON","stringify","slice","entry","sql","search","checks","presets","default","queries","features","content","store"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { DatabaseSync } from 'node:sqlite';
1
+ import type { Store } from '../store/types.js';
2
2
  export type LangCounts = Record<string, number>;
3
- export declare function languageDistribution(db: DatabaseSync): LangCounts | undefined;
4
- export declare function saveLanguageDistribution(db: DatabaseSync, counts: LangCounts): void;
3
+ export declare function languageDistribution(store: Store): Promise<LangCounts | undefined>;
4
+ export declare function saveLanguageDistribution(store: Store, counts: LangCounts): Promise<void>;
@@ -1,4 +1,4 @@
1
- import type { DatabaseSync } from 'node:sqlite';
1
+ import type { Store } from '../store/types.js';
2
2
  export type LangCounts = Record<string, number>;
3
- export declare function languageDistribution(db: DatabaseSync): LangCounts | undefined;
4
- export declare function saveLanguageDistribution(db: DatabaseSync, counts: LangCounts): void;
3
+ export declare function languageDistribution(store: Store): Promise<LangCounts | undefined>;
4
+ export declare function saveLanguageDistribution(store: Store, counts: LangCounts): Promise<void>;
@@ -16,15 +16,171 @@ _export(exports, {
16
16
  return saveLanguageDistribution;
17
17
  }
18
18
  });
19
- var _sharedts = require("../db/shared.js");
19
+ var _metats = require("../store/meta.js");
20
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
21
+ try {
22
+ var info = gen[key](arg);
23
+ var value = info.value;
24
+ } catch (error) {
25
+ reject(error);
26
+ return;
27
+ }
28
+ if (info.done) resolve(value);
29
+ else Promise.resolve(value).then(_next, _throw);
30
+ }
31
+ function _async_to_generator(fn) {
32
+ return function() {
33
+ var self = this, args = arguments;
34
+ return new Promise(function(resolve, reject) {
35
+ var gen = fn.apply(self, args);
36
+ function _next(value) {
37
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
38
+ }
39
+ function _throw(err) {
40
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
41
+ }
42
+ _next(undefined);
43
+ });
44
+ };
45
+ }
46
+ function _ts_generator(thisArg, body) {
47
+ var f, y, t, _ = {
48
+ label: 0,
49
+ sent: function() {
50
+ if (t[0] & 1) throw t[1];
51
+ return t[1];
52
+ },
53
+ trys: [],
54
+ ops: []
55
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
56
+ return d(g, "next", {
57
+ value: verb(0)
58
+ }), d(g, "throw", {
59
+ value: verb(1)
60
+ }), d(g, "return", {
61
+ value: verb(2)
62
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
63
+ value: function() {
64
+ return this;
65
+ }
66
+ }), g;
67
+ function verb(n) {
68
+ return function(v) {
69
+ return step([
70
+ n,
71
+ v
72
+ ]);
73
+ };
74
+ }
75
+ function step(op) {
76
+ if (f) throw new TypeError("Generator is already executing.");
77
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
78
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
79
+ if (y = 0, t) op = [
80
+ op[0] & 2,
81
+ t.value
82
+ ];
83
+ switch(op[0]){
84
+ case 0:
85
+ case 1:
86
+ t = op;
87
+ break;
88
+ case 4:
89
+ _.label++;
90
+ return {
91
+ value: op[1],
92
+ done: false
93
+ };
94
+ case 5:
95
+ _.label++;
96
+ y = op[1];
97
+ op = [
98
+ 0
99
+ ];
100
+ continue;
101
+ case 7:
102
+ op = _.ops.pop();
103
+ _.trys.pop();
104
+ continue;
105
+ default:
106
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
107
+ _ = 0;
108
+ continue;
109
+ }
110
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
111
+ _.label = op[1];
112
+ break;
113
+ }
114
+ if (op[0] === 6 && _.label < t[1]) {
115
+ _.label = t[1];
116
+ t = op;
117
+ break;
118
+ }
119
+ if (t && _.label < t[2]) {
120
+ _.label = t[2];
121
+ _.ops.push(op);
122
+ break;
123
+ }
124
+ if (t[2]) _.ops.pop();
125
+ _.trys.pop();
126
+ continue;
127
+ }
128
+ op = body.call(thisArg, _);
129
+ } catch (e) {
130
+ op = [
131
+ 6,
132
+ e
133
+ ];
134
+ y = 0;
135
+ } finally{
136
+ f = t = 0;
137
+ }
138
+ if (op[0] & 5) throw op[1];
139
+ return {
140
+ value: op[0] ? op[1] : void 0,
141
+ done: true
142
+ };
143
+ }
144
+ }
20
145
  // Split out of langfit.ts so reading the persisted counts (status.ts's only need) never pulls in
21
146
  // franc-min; only checkLanguageFit's classify path needs the classifier itself.
22
147
  var META_KEY = 'embed_languages';
23
- function languageDistribution(db) {
24
- var raw = (0, _sharedts.getMeta)(db, META_KEY);
25
- return raw ? JSON.parse(raw) : undefined;
148
+ function languageDistribution(store) {
149
+ return _async_to_generator(function() {
150
+ var raw;
151
+ return _ts_generator(this, function(_state) {
152
+ switch(_state.label){
153
+ case 0:
154
+ return [
155
+ 4,
156
+ (0, _metats.getMeta)(store, META_KEY)
157
+ ];
158
+ case 1:
159
+ raw = _state.sent();
160
+ return [
161
+ 2,
162
+ raw ? JSON.parse(raw) : undefined
163
+ ];
164
+ }
165
+ });
166
+ })();
26
167
  }
27
- function saveLanguageDistribution(db, counts) {
28
- (0, _sharedts.setMeta)(db, META_KEY, JSON.stringify(counts));
168
+ function saveLanguageDistribution(store, counts) {
169
+ return _async_to_generator(function() {
170
+ return _ts_generator(this, function(_state) {
171
+ switch(_state.label){
172
+ case 0:
173
+ return [
174
+ 4,
175
+ (0, _metats.setMeta)(store, META_KEY, JSON.stringify(counts))
176
+ ];
177
+ case 1:
178
+ _state.sent();
179
+ return [
180
+ 2
181
+ ];
182
+ }
183
+ });
184
+ })();
29
185
  }
30
186
  /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/embed/distribution.ts"],"sourcesContent":["import type { DatabaseSync } from 'node:sqlite';\nimport { getMeta, setMeta } from '../db/shared.ts';\n\n// Split out of langfit.ts so reading the persisted counts (status.ts's only need) never pulls in\n// franc-min; only checkLanguageFit's classify path needs the classifier itself.\nconst META_KEY = 'embed_languages';\n\nexport type LangCounts = Record<string, number>;\n\nexport function languageDistribution(db: DatabaseSync): LangCounts | undefined {\n const raw = getMeta(db, META_KEY);\n return raw ? JSON.parse(raw) : undefined;\n}\n\nexport function saveLanguageDistribution(db: DatabaseSync, counts: LangCounts): void {\n setMeta(db, META_KEY, JSON.stringify(counts));\n}\n"],"names":["languageDistribution","saveLanguageDistribution","META_KEY","db","raw","getMeta","JSON","parse","undefined","counts","setMeta","stringify"],"mappings":";;;;;;;;;;;QASgBA;eAAAA;;QAKAC;eAAAA;;;wBAbiB;AAEjC,iGAAiG;AACjG,gFAAgF;AAChF,IAAMC,WAAW;AAIV,SAASF,qBAAqBG,EAAgB;IACnD,IAAMC,MAAMC,IAAAA,iBAAO,EAACF,IAAID;IACxB,OAAOE,MAAME,KAAKC,KAAK,CAACH,OAAOI;AACjC;AAEO,SAASP,yBAAyBE,EAAgB,EAAEM,MAAkB;IAC3EC,IAAAA,iBAAO,EAACP,IAAID,UAAUI,KAAKK,SAAS,CAACF;AACvC"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/embed/distribution.ts"],"sourcesContent":["import { getMeta, setMeta } from '../store/meta.ts';\nimport type { Store } from '../store/types.ts';\n\n// Split out of langfit.ts so reading the persisted counts (status.ts's only need) never pulls in\n// franc-min; only checkLanguageFit's classify path needs the classifier itself.\nconst META_KEY = 'embed_languages';\n\nexport type LangCounts = Record<string, number>;\n\nexport async function languageDistribution(store: Store): Promise<LangCounts | undefined> {\n const raw = await getMeta(store, META_KEY);\n return raw ? JSON.parse(raw) : undefined;\n}\n\nexport async function saveLanguageDistribution(store: Store, counts: LangCounts): Promise<void> {\n await setMeta(store, META_KEY, JSON.stringify(counts));\n}\n"],"names":["languageDistribution","saveLanguageDistribution","META_KEY","store","raw","getMeta","JSON","parse","undefined","counts","setMeta","stringify"],"mappings":";;;;;;;;;;;QASsBA;eAAAA;;QAKAC;eAAAA;;;sBAdW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGjC,iGAAiG;AACjG,gFAAgF;AAChF,IAAMC,WAAW;AAIV,SAAeF,qBAAqBG,KAAY;;YAC/CC;;;;oBAAM;;wBAAMC,IAAAA,eAAO,EAACF,OAAOD;;;oBAA3BE,MAAM;oBACZ;;wBAAOA,MAAME,KAAKC,KAAK,CAACH,OAAOI;;;;IACjC;;AAEO,SAAeP,yBAAyBE,KAAY,EAAEM,MAAkB;;;;;oBAC7E;;wBAAMC,IAAAA,eAAO,EAACP,OAAOD,UAAUI,KAAKK,SAAS,CAACF;;;oBAA9C;;;;;;IACF"}
@@ -1,3 +1,3 @@
1
- import type { DatabaseSync } from 'node:sqlite';
1
+ import type { Store } from '../store/types.js';
2
2
  import type { EmbedProvider } from './types.js';
3
- export declare function checkLanguageFit(db: DatabaseSync, provider: EmbedProvider, texts: string[]): Promise<void>;
3
+ export declare function checkLanguageFit(store: Store, provider: EmbedProvider, texts: string[]): Promise<void>;
@@ -1,3 +1,3 @@
1
- import type { DatabaseSync } from 'node:sqlite';
1
+ import type { Store } from '../store/types.js';
2
2
  import type { EmbedProvider } from './types.js';
3
- export declare function checkLanguageFit(db: DatabaseSync, provider: EmbedProvider, texts: string[]): Promise<void>;
3
+ export declare function checkLanguageFit(store: Store, provider: EmbedProvider, texts: string[]): Promise<void>;
@@ -228,55 +228,68 @@ function classify(franc, text) {
228
228
  var code = franc(text.slice(0, SAMPLE_CHARS));
229
229
  return code === 'und' ? undefined : code;
230
230
  }
231
- function checkLanguageFit(db, provider, texts) {
231
+ function checkLanguageFit(store, provider, texts) {
232
232
  return _async_to_generator(function() {
233
- var _languageDistribution, franc, persisted, merged, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, text, _merged_code, code, total, declared, _Object_entries_sort_, majorityLang, majorityCount, pct;
233
+ var _ref, franc, persisted, merged, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, text, _merged_code, code, total, declared, _Object_entries_sort_, majorityLang, majorityCount, pct;
234
234
  return _ts_generator(this, function(_state) {
235
- if (texts.length === 0) return [
236
- 2
237
- ];
238
- franc = _require('franc-min').franc;
239
- persisted = (_languageDistribution = (0, _distributionts.languageDistribution)(db)) !== null && _languageDistribution !== void 0 ? _languageDistribution : {};
240
- merged = _object_spread({}, persisted);
241
- _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
242
- try {
243
- for(_iterator = texts[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
244
- text = _step.value;
245
- ;
246
- code = classify(franc, text);
247
- if (code) merged[code] = ((_merged_code = merged[code]) !== null && _merged_code !== void 0 ? _merged_code : 0) + 1;
248
- }
249
- } catch (err) {
250
- _didIteratorError = true;
251
- _iteratorError = err;
252
- } finally{
253
- try {
254
- if (!_iteratorNormalCompletion && _iterator.return != null) {
255
- _iterator.return();
235
+ switch(_state.label){
236
+ case 0:
237
+ if (texts.length === 0) return [
238
+ 2
239
+ ];
240
+ franc = _require('franc-min').franc;
241
+ return [
242
+ 4,
243
+ (0, _distributionts.languageDistribution)(store)
244
+ ];
245
+ case 1:
246
+ persisted = (_ref = _state.sent()) !== null && _ref !== void 0 ? _ref : {};
247
+ merged = _object_spread({}, persisted);
248
+ _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
249
+ try {
250
+ for(_iterator = texts[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
251
+ text = _step.value;
252
+ ;
253
+ code = classify(franc, text);
254
+ if (code) merged[code] = ((_merged_code = merged[code]) !== null && _merged_code !== void 0 ? _merged_code : 0) + 1;
255
+ }
256
+ } catch (err) {
257
+ _didIteratorError = true;
258
+ _iteratorError = err;
259
+ } finally{
260
+ try {
261
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
262
+ _iterator.return();
263
+ }
264
+ } finally{
265
+ if (_didIteratorError) {
266
+ throw _iteratorError;
267
+ }
268
+ }
256
269
  }
257
- } finally{
258
- if (_didIteratorError) {
259
- throw _iteratorError;
270
+ total = Object.values(merged).reduce(function(a, b) {
271
+ return a + b;
272
+ }, 0);
273
+ if (provider.languages && provider.languages.length > 0 && total >= MIN_CLASSIFIED) {
274
+ declared = new Set(provider.languages.map(_languagests.toIso3));
275
+ _Object_entries_sort_ = _sliced_to_array(Object.entries(merged).sort(function(a, b) {
276
+ return b[1] - a[1];
277
+ })[0], 2), majorityLang = _Object_entries_sort_[0], majorityCount = _Object_entries_sort_[1];
278
+ if (majorityCount / total >= 0.5 && !declared.has(majorityLang)) {
279
+ pct = Math.round(majorityCount / total * 100);
280
+ throw new _errorsts.SenseError('EMBED_MODEL_MISMATCH', "embed model ".concat(provider.id, " declares languages [").concat(provider.languages.join(', '), "], but ").concat(pct, "% of this tree's classified text is \"").concat(majorityLang, "\" (ISO 639-3), which is not among them; choose a model for this tree's languages: `sense init --model ...`, see the sense-setup skill or INTEGRATIONS.md"));
281
+ }
260
282
  }
261
- }
262
- }
263
- total = Object.values(merged).reduce(function(a, b) {
264
- return a + b;
265
- }, 0);
266
- if (provider.languages && provider.languages.length > 0 && total >= MIN_CLASSIFIED) {
267
- declared = new Set(provider.languages.map(_languagests.toIso3));
268
- _Object_entries_sort_ = _sliced_to_array(Object.entries(merged).sort(function(a, b) {
269
- return b[1] - a[1];
270
- })[0], 2), majorityLang = _Object_entries_sort_[0], majorityCount = _Object_entries_sort_[1];
271
- if (majorityCount / total >= 0.5 && !declared.has(majorityLang)) {
272
- pct = Math.round(majorityCount / total * 100);
273
- throw new _errorsts.SenseError('EMBED_MODEL_MISMATCH', "embed model ".concat(provider.id, " declares languages [").concat(provider.languages.join(', '), "], but ").concat(pct, "% of this tree's classified text is \"").concat(majorityLang, "\" (ISO 639-3), which is not among them; choose a model for this tree's languages: `sense init --model ...`, see the sense-setup skill or INTEGRATIONS.md"));
274
- }
283
+ return [
284
+ 4,
285
+ (0, _distributionts.saveLanguageDistribution)(store, merged)
286
+ ];
287
+ case 2:
288
+ _state.sent();
289
+ return [
290
+ 2
291
+ ];
275
292
  }
276
- (0, _distributionts.saveLanguageDistribution)(db, merged);
277
- return [
278
- 2
279
- ];
280
293
  });
281
294
  })();
282
295
  }