sensemaking 0.26.0 → 0.27.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (324) hide show
  1. package/README.md +36 -4
  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/download.js.map +1 -1
  11. package/dist/cjs/cli/index.d.cts +2 -2
  12. package/dist/cjs/cli/index.d.ts +2 -2
  13. package/dist/cjs/cli/index.js +2 -2
  14. package/dist/cjs/cli/index.js.map +1 -1
  15. package/dist/cjs/cli/init.js.map +1 -1
  16. package/dist/cjs/cli/map.js.map +1 -1
  17. package/dist/cjs/cli/named.js.map +1 -1
  18. package/dist/cjs/cli/path.js.map +1 -1
  19. package/dist/cjs/cli/peek.js +43 -2
  20. package/dist/cjs/cli/peek.js.map +1 -1
  21. package/dist/cjs/cli/related.js.map +1 -1
  22. package/dist/cjs/cli/search.js +38 -6
  23. package/dist/cjs/cli/search.js.map +1 -1
  24. package/dist/cjs/cli/shared.js.map +1 -1
  25. package/dist/cjs/cli/sql.js.map +1 -1
  26. package/dist/cjs/cli/status.js.map +1 -1
  27. package/dist/cjs/cli/watch.js.map +1 -1
  28. package/dist/cjs/cli.js.map +1 -1
  29. package/dist/cjs/commands/index.d.cts +2 -2
  30. package/dist/cjs/commands/index.d.ts +2 -2
  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.d.cts +9 -1
  35. package/dist/cjs/commands/peek.d.ts +9 -1
  36. package/dist/cjs/commands/peek.js +72 -29
  37. package/dist/cjs/commands/peek.js.map +1 -1
  38. package/dist/cjs/commands/related.js.map +1 -1
  39. package/dist/cjs/commands/scope.js.map +1 -1
  40. package/dist/cjs/commands/search.d.cts +6 -2
  41. package/dist/cjs/commands/search.d.ts +6 -2
  42. package/dist/cjs/commands/search.js +31 -4
  43. package/dist/cjs/commands/search.js.map +1 -1
  44. package/dist/cjs/commands/signals.d.cts +19 -5
  45. package/dist/cjs/commands/signals.d.ts +19 -5
  46. package/dist/cjs/commands/signals.js +64 -11
  47. package/dist/cjs/commands/signals.js.map +1 -1
  48. package/dist/cjs/commands/snapshot.js.map +1 -1
  49. package/dist/cjs/commands/status.js.map +1 -1
  50. package/dist/cjs/config/access.js.map +1 -1
  51. package/dist/cjs/config/index.js.map +1 -1
  52. package/dist/cjs/config/load.js +6 -0
  53. package/dist/cjs/config/load.js.map +1 -1
  54. package/dist/cjs/config/resolve.js.map +1 -1
  55. package/dist/cjs/config/signals.js.map +1 -1
  56. package/dist/cjs/config/types.js.map +1 -1
  57. package/dist/cjs/config/validate.js.map +1 -1
  58. package/dist/cjs/embed/cohere.js.map +1 -1
  59. package/dist/cjs/embed/distribution.js.map +1 -1
  60. package/dist/cjs/embed/endpoint.js.map +1 -1
  61. package/dist/cjs/embed/handoff.js.map +1 -1
  62. package/dist/cjs/embed/http.js.map +1 -1
  63. package/dist/cjs/embed/identity.js.map +1 -1
  64. package/dist/cjs/embed/langfit.js.map +1 -1
  65. package/dist/cjs/embed/languages.js.map +1 -1
  66. package/dist/cjs/embed/openai.js.map +1 -1
  67. package/dist/cjs/embed/query.js.map +1 -1
  68. package/dist/cjs/embed/registry.js.map +1 -1
  69. package/dist/cjs/embed/static.js.map +1 -1
  70. package/dist/cjs/embed/store.js.map +1 -1
  71. package/dist/cjs/embed/types.js.map +1 -1
  72. package/dist/cjs/errors.js.map +1 -1
  73. package/dist/cjs/features/embed.js.map +1 -1
  74. package/dist/cjs/features/fences.js.map +1 -1
  75. package/dist/cjs/features/index.js.map +1 -1
  76. package/dist/cjs/features/links.js.map +1 -1
  77. package/dist/cjs/features/rank.js.map +1 -1
  78. package/dist/cjs/features/sections.js.map +1 -1
  79. package/dist/cjs/features/tags.js.map +1 -1
  80. package/dist/cjs/graph/graph.js.map +1 -1
  81. package/dist/cjs/graph/traverse.js.map +1 -1
  82. package/dist/cjs/index.d.cts +1 -1
  83. package/dist/cjs/index.d.ts +1 -1
  84. package/dist/cjs/index.js.map +1 -1
  85. package/dist/cjs/lib/atomic-write.js.map +1 -1
  86. package/dist/cjs/lib/guarded-tick.js.map +1 -1
  87. package/dist/cjs/lib/serial-query.js.map +1 -1
  88. package/dist/cjs/lib/watch-notification.js.map +1 -1
  89. package/dist/cjs/lib/worker-file.js.map +1 -1
  90. package/dist/cjs/output/column-hint.js.map +1 -1
  91. package/dist/cjs/output/output.js.map +1 -1
  92. package/dist/cjs/output/progress.js.map +1 -1
  93. package/dist/cjs/output/search-error.js.map +1 -1
  94. package/dist/cjs/scan/frontmatter.js.map +1 -1
  95. package/dist/cjs/scan/index.js.map +1 -1
  96. package/dist/cjs/scan/list.js.map +1 -1
  97. package/dist/cjs/scan/pool.js.map +1 -1
  98. package/dist/cjs/scan/reparse.js.map +1 -1
  99. package/dist/cjs/scan/worker-error.js.map +1 -1
  100. package/dist/cjs/store/batch.js.map +1 -1
  101. package/dist/cjs/store/builder.js.map +1 -1
  102. package/dist/cjs/store/cache.js.map +1 -1
  103. package/dist/cjs/store/duckdb/batch.js.map +1 -1
  104. package/dist/cjs/store/duckdb/connection.js.map +1 -1
  105. package/dist/cjs/store/duckdb/fieldStats.js.map +1 -1
  106. package/dist/cjs/store/duckdb/lexical.d.cts +1 -6
  107. package/dist/cjs/store/duckdb/lexical.d.ts +1 -6
  108. package/dist/cjs/store/duckdb/lexical.js +28 -39
  109. package/dist/cjs/store/duckdb/lexical.js.map +1 -1
  110. package/dist/cjs/store/duckdb/native.d.cts +1 -2
  111. package/dist/cjs/store/duckdb/native.d.ts +1 -2
  112. package/dist/cjs/store/duckdb/native.js +1 -6
  113. package/dist/cjs/store/duckdb/native.js.map +1 -1
  114. package/dist/cjs/store/duckdb/open.js.map +1 -1
  115. package/dist/cjs/store/duckdb/ordered-bm25.d.cts +3 -16
  116. package/dist/cjs/store/duckdb/ordered-bm25.d.ts +3 -16
  117. package/dist/cjs/store/duckdb/ordered-bm25.js +27 -79
  118. package/dist/cjs/store/duckdb/ordered-bm25.js.map +1 -1
  119. package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
  120. package/dist/cjs/store/duckdb/sql-functions.js.map +1 -1
  121. package/dist/cjs/store/duckdb/store.js.map +1 -1
  122. package/dist/cjs/store/duckdb/vectors.js.map +1 -1
  123. package/dist/cjs/store/embed-scope.js.map +1 -1
  124. package/dist/cjs/store/feature-scope.js.map +1 -1
  125. package/dist/cjs/store/index.js.map +1 -1
  126. package/dist/cjs/store/lock-wait.js.map +1 -1
  127. package/dist/cjs/store/native.js.map +1 -1
  128. package/dist/cjs/store/open.js.map +1 -1
  129. package/dist/cjs/store/preset-scope.js.map +1 -1
  130. package/dist/cjs/store/readiness.js.map +1 -1
  131. package/dist/cjs/store/reconcile.js.map +1 -1
  132. package/dist/cjs/store/shared.js.map +1 -1
  133. package/dist/cjs/store/signature.js.map +1 -1
  134. package/dist/cjs/store/sql-functions.js.map +1 -1
  135. package/dist/cjs/store/sqlite/connection.js.map +1 -1
  136. package/dist/cjs/store/sqlite/fieldStats.js.map +1 -1
  137. package/dist/cjs/store/sqlite/lexical.js.map +1 -1
  138. package/dist/cjs/store/sqlite/open.js.map +1 -1
  139. package/dist/cjs/store/sqlite/reconcile.js.map +1 -1
  140. package/dist/cjs/store/sqlite/sql-functions.js.map +1 -1
  141. package/dist/cjs/store/sqlite/store.js.map +1 -1
  142. package/dist/cjs/store/sqlite/vectors.js.map +1 -1
  143. package/dist/cjs/store/stages.js.map +1 -1
  144. package/dist/cjs/store/transaction.js.map +1 -1
  145. package/dist/cjs/store/turso/connection.js.map +1 -1
  146. package/dist/cjs/store/turso/fieldStats.js.map +1 -1
  147. package/dist/cjs/store/turso/lexical-text.js.map +1 -1
  148. package/dist/cjs/store/turso/lexical.js.map +1 -1
  149. package/dist/cjs/store/turso/native.js.map +1 -1
  150. package/dist/cjs/store/turso/open.js.map +1 -1
  151. package/dist/cjs/store/turso/reconcile.js.map +1 -1
  152. package/dist/cjs/store/turso/sql-functions.js.map +1 -1
  153. package/dist/cjs/store/turso/store.js.map +1 -1
  154. package/dist/cjs/store/turso/vectors.js.map +1 -1
  155. package/dist/cjs/store/types.js.map +1 -1
  156. package/dist/cjs/store/vectors.js.map +1 -1
  157. package/dist/cjs/text/segment.js.map +1 -1
  158. package/dist/cjs/text/strip.js.map +1 -1
  159. package/dist/cjs/watch-claim.js.map +1 -1
  160. package/dist/cjs/watch.js.map +1 -1
  161. package/dist/cjs/workers/parse.js.map +1 -1
  162. package/dist/cjs/workers/watch-heartbeat.js.map +1 -1
  163. package/dist/esm/chunk/extract.js.map +1 -1
  164. package/dist/esm/chunk/group.js.map +1 -1
  165. package/dist/esm/chunk/index.js.map +1 -1
  166. package/dist/esm/chunk/parse.js.map +1 -1
  167. package/dist/esm/chunk/parser.js.map +1 -1
  168. package/dist/esm/chunk/tokens.js.map +1 -1
  169. package/dist/esm/chunk/types.js.map +1 -1
  170. package/dist/esm/chunk/version.js.map +1 -1
  171. package/dist/esm/cli/build.js.map +1 -1
  172. package/dist/esm/cli/download.js.map +1 -1
  173. package/dist/esm/cli/index.d.ts +2 -2
  174. package/dist/esm/cli/index.js +2 -2
  175. package/dist/esm/cli/index.js.map +1 -1
  176. package/dist/esm/cli/init.js.map +1 -1
  177. package/dist/esm/cli/map.js.map +1 -1
  178. package/dist/esm/cli/named.js.map +1 -1
  179. package/dist/esm/cli/path.js.map +1 -1
  180. package/dist/esm/cli/peek.js +20 -2
  181. package/dist/esm/cli/peek.js.map +1 -1
  182. package/dist/esm/cli/related.js.map +1 -1
  183. package/dist/esm/cli/search.js +12 -2
  184. package/dist/esm/cli/search.js.map +1 -1
  185. package/dist/esm/cli/shared.js.map +1 -1
  186. package/dist/esm/cli/sql.js.map +1 -1
  187. package/dist/esm/cli/status.js.map +1 -1
  188. package/dist/esm/cli/types.js.map +1 -1
  189. package/dist/esm/cli/watch.js.map +1 -1
  190. package/dist/esm/cli.js.map +1 -1
  191. package/dist/esm/commands/index.d.ts +2 -2
  192. package/dist/esm/commands/index.js.map +1 -1
  193. package/dist/esm/commands/map.js.map +1 -1
  194. package/dist/esm/commands/path.js.map +1 -1
  195. package/dist/esm/commands/peek.d.ts +9 -1
  196. package/dist/esm/commands/peek.js +26 -12
  197. package/dist/esm/commands/peek.js.map +1 -1
  198. package/dist/esm/commands/related.js.map +1 -1
  199. package/dist/esm/commands/scope.js.map +1 -1
  200. package/dist/esm/commands/search.d.ts +6 -2
  201. package/dist/esm/commands/search.js +11 -3
  202. package/dist/esm/commands/search.js.map +1 -1
  203. package/dist/esm/commands/signals.d.ts +19 -5
  204. package/dist/esm/commands/signals.js +64 -14
  205. package/dist/esm/commands/signals.js.map +1 -1
  206. package/dist/esm/commands/snapshot.js.map +1 -1
  207. package/dist/esm/commands/status.js.map +1 -1
  208. package/dist/esm/config/access.js.map +1 -1
  209. package/dist/esm/config/index.js.map +1 -1
  210. package/dist/esm/config/load.js +6 -0
  211. package/dist/esm/config/load.js.map +1 -1
  212. package/dist/esm/config/resolve.js.map +1 -1
  213. package/dist/esm/config/signals.js.map +1 -1
  214. package/dist/esm/config/types.js.map +1 -1
  215. package/dist/esm/config/validate.js.map +1 -1
  216. package/dist/esm/embed/cohere.js.map +1 -1
  217. package/dist/esm/embed/distribution.js.map +1 -1
  218. package/dist/esm/embed/endpoint.js.map +1 -1
  219. package/dist/esm/embed/handoff.js.map +1 -1
  220. package/dist/esm/embed/http.js.map +1 -1
  221. package/dist/esm/embed/identity.js.map +1 -1
  222. package/dist/esm/embed/langfit.js.map +1 -1
  223. package/dist/esm/embed/languages.js.map +1 -1
  224. package/dist/esm/embed/openai.js.map +1 -1
  225. package/dist/esm/embed/query.js.map +1 -1
  226. package/dist/esm/embed/registry.js.map +1 -1
  227. package/dist/esm/embed/static.js.map +1 -1
  228. package/dist/esm/embed/store.js.map +1 -1
  229. package/dist/esm/embed/types.js.map +1 -1
  230. package/dist/esm/errors.js.map +1 -1
  231. package/dist/esm/features/embed.js.map +1 -1
  232. package/dist/esm/features/fences.js.map +1 -1
  233. package/dist/esm/features/index.js.map +1 -1
  234. package/dist/esm/features/links.js.map +1 -1
  235. package/dist/esm/features/rank.js.map +1 -1
  236. package/dist/esm/features/sections.js.map +1 -1
  237. package/dist/esm/features/tags.js.map +1 -1
  238. package/dist/esm/features/types.js.map +1 -1
  239. package/dist/esm/graph/graph.js.map +1 -1
  240. package/dist/esm/graph/traverse.js.map +1 -1
  241. package/dist/esm/index.d.ts +1 -1
  242. package/dist/esm/index.js.map +1 -1
  243. package/dist/esm/lib/atomic-write.js.map +1 -1
  244. package/dist/esm/lib/guarded-tick.js.map +1 -1
  245. package/dist/esm/lib/serial-query.js.map +1 -1
  246. package/dist/esm/lib/watch-notification.js.map +1 -1
  247. package/dist/esm/lib/worker-file.js.map +1 -1
  248. package/dist/esm/output/column-hint.js.map +1 -1
  249. package/dist/esm/output/output.js.map +1 -1
  250. package/dist/esm/output/progress.js.map +1 -1
  251. package/dist/esm/output/search-error.js.map +1 -1
  252. package/dist/esm/scan/frontmatter.js.map +1 -1
  253. package/dist/esm/scan/index.js.map +1 -1
  254. package/dist/esm/scan/list.js.map +1 -1
  255. package/dist/esm/scan/pool.js.map +1 -1
  256. package/dist/esm/scan/reparse.js.map +1 -1
  257. package/dist/esm/scan/worker-error.js.map +1 -1
  258. package/dist/esm/store/batch.js.map +1 -1
  259. package/dist/esm/store/builder.js.map +1 -1
  260. package/dist/esm/store/cache.js.map +1 -1
  261. package/dist/esm/store/duckdb/batch.js.map +1 -1
  262. package/dist/esm/store/duckdb/connection.js.map +1 -1
  263. package/dist/esm/store/duckdb/fieldStats.js.map +1 -1
  264. package/dist/esm/store/duckdb/lexical.d.ts +1 -6
  265. package/dist/esm/store/duckdb/lexical.js +13 -17
  266. package/dist/esm/store/duckdb/lexical.js.map +1 -1
  267. package/dist/esm/store/duckdb/native.d.ts +1 -2
  268. package/dist/esm/store/duckdb/native.js +1 -3
  269. package/dist/esm/store/duckdb/native.js.map +1 -1
  270. package/dist/esm/store/duckdb/open.js.map +1 -1
  271. package/dist/esm/store/duckdb/ordered-bm25.d.ts +3 -16
  272. package/dist/esm/store/duckdb/ordered-bm25.js +18 -54
  273. package/dist/esm/store/duckdb/ordered-bm25.js.map +1 -1
  274. package/dist/esm/store/duckdb/reconcile.js.map +1 -1
  275. package/dist/esm/store/duckdb/sql-functions.js.map +1 -1
  276. package/dist/esm/store/duckdb/store.js.map +1 -1
  277. package/dist/esm/store/duckdb/vectors.js.map +1 -1
  278. package/dist/esm/store/embed-scope.js.map +1 -1
  279. package/dist/esm/store/feature-scope.js.map +1 -1
  280. package/dist/esm/store/index.js.map +1 -1
  281. package/dist/esm/store/lock-wait.js.map +1 -1
  282. package/dist/esm/store/native.js.map +1 -1
  283. package/dist/esm/store/open.js.map +1 -1
  284. package/dist/esm/store/preset-scope.js.map +1 -1
  285. package/dist/esm/store/readiness.js.map +1 -1
  286. package/dist/esm/store/reconcile.js.map +1 -1
  287. package/dist/esm/store/shared.js.map +1 -1
  288. package/dist/esm/store/signature.js.map +1 -1
  289. package/dist/esm/store/sql-functions.js.map +1 -1
  290. package/dist/esm/store/sqlite/connection.js.map +1 -1
  291. package/dist/esm/store/sqlite/fieldStats.js.map +1 -1
  292. package/dist/esm/store/sqlite/lexical.js.map +1 -1
  293. package/dist/esm/store/sqlite/open.js.map +1 -1
  294. package/dist/esm/store/sqlite/reconcile.js.map +1 -1
  295. package/dist/esm/store/sqlite/sql-functions.js.map +1 -1
  296. package/dist/esm/store/sqlite/store.js.map +1 -1
  297. package/dist/esm/store/sqlite/vectors.js.map +1 -1
  298. package/dist/esm/store/stages.js.map +1 -1
  299. package/dist/esm/store/transaction.js.map +1 -1
  300. package/dist/esm/store/turso/connection.js.map +1 -1
  301. package/dist/esm/store/turso/fieldStats.js.map +1 -1
  302. package/dist/esm/store/turso/lexical-text.js.map +1 -1
  303. package/dist/esm/store/turso/lexical.js.map +1 -1
  304. package/dist/esm/store/turso/native.js.map +1 -1
  305. package/dist/esm/store/turso/open.js.map +1 -1
  306. package/dist/esm/store/turso/reconcile.js.map +1 -1
  307. package/dist/esm/store/turso/sql-functions.js.map +1 -1
  308. package/dist/esm/store/turso/store.js.map +1 -1
  309. package/dist/esm/store/turso/vectors.js.map +1 -1
  310. package/dist/esm/store/types.js.map +1 -1
  311. package/dist/esm/store/vectors.js.map +1 -1
  312. package/dist/esm/text/segment.js.map +1 -1
  313. package/dist/esm/text/strip.js.map +1 -1
  314. package/dist/esm/watch-claim.js.map +1 -1
  315. package/dist/esm/watch.js.map +1 -1
  316. package/dist/esm/workers/parse.js.map +1 -1
  317. package/dist/esm/workers/watch-heartbeat.js.map +1 -1
  318. package/package.json +2 -2
  319. package/skills/sense/EXAMPLES.md +3 -3
  320. package/skills/sense/SKILL.md +7 -1
  321. package/skills/sense/references/search.md +17 -1
  322. package/skills/sense/references/sql.md +1 -1
  323. package/skills/sense/references/terminology.md +32 -0
  324. package/skills/sense-setup/references/store-benchmarks.md +5 -5
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/extract.ts"],"sourcesContent":["import type { Token } from 'markdown-it';\nimport { parser } from './parser.ts';\nimport type { Block } from './types.ts';\n\n// markdown-it, like mdast, has no wikilink, embed, or %%comment%% token -- literal text resolved\n// by regex passes over non-code text (code/inline code is placeholder-held and spliced back verbatim).\nconst COMMENT_PAIR = /%%[\\s\\S]*?%%/g;\n// An embed always yields its target, whatever follows a pipe (a resize suffix, never an alias);\n// must run before the wikilink regex below, bang included, or that regex matches first.\nconst EMBED = /!\\[\\[([^\\]]+)\\]\\]/g;\nconst WIKILINK = /\\[\\[([^\\]]+)\\]\\]/g;\n// A trailing \" ^id\" is an Obsidian block anchor, valid only at a line's end; a caret elsewhere\n// (mid-line) is ordinary text and is left alone.\nconst BLOCK_ID = / \\^[A-Za-z0-9-]+$/gm;\n// A callout marker is only ever the first thing in a blockquote's text (Obsidian's grammar),\n// so this anchors to blockquote output alone -- never applied to prose in general.\nconst CALLOUT_MARKER = /^\\[!\\w[\\w-]*\\][+-]?[ \\t]?/;\n// An html token's content is raw HTML, block or inline: a full <!-- --> comment is dropped, any\n// remaining tags are stripped, and the text a browser would still render survives.\nconst HTML_COMMENT = /<!--[\\s\\S]*?-->/g;\nconst HTML_TAG = /<[^>]+>/g;\n\nfunction stripHtml(value: string): string {\n return value.replace(HTML_COMMENT, '').replace(HTML_TAG, '');\n}\n\n// A `#anchor` keeps its text (hash dropped), unlike links.ts's parseWikilinkInner (the resolver\n// authority), which discards it entirely -- replicated here since that return value doesn't fit.\nfunction anchorText(base: string): string {\n const hashIdx = base.indexOf('#');\n if (hashIdx === -1) return base.trim();\n const target = base.slice(0, hashIdx).trim();\n const anchor = base.slice(hashIdx + 1).trim();\n return target ? `${target} ${anchor}` : anchor;\n}\n\nfunction wikilinkText(inner: string): string {\n const pipeIdx = inner.indexOf('|');\n return pipeIdx === -1 ? anchorText(inner) : inner.slice(pipeIdx + 1).trim();\n}\n\nfunction embedText(inner: string): string {\n const pipeIdx = inner.indexOf('|');\n return anchorText(pipeIdx === -1 ? inner : inner.slice(0, pipeIdx));\n}\n\nfunction resolveFlavor(text: string): string {\n return text\n .replace(HTML_COMMENT, '')\n .replace(COMMENT_PAIR, '')\n .replace(EMBED, (_, inner: string) => embedText(inner))\n .replace(WIKILINK, (_, inner: string) => wikilinkText(inner))\n .replace(BLOCK_ID, '');\n}\n\n// U+E000 (Private Use Area) never appears in real markdown text, so it is a collision-free\n// placeholder delimiter, spliced back to the literal code value after flavor resolution.\nfunction codePlaceholder(value: string, code: string[]): string {\n const idx = code.push(value) - 1;\n return `\\uE000${idx}\\uE000`;\n}\n\n// GFM's autolink literal ends where its path machine stops: a trail of punctuation is a genuine\n// end (link stops before it) only when trailEndsAt accepts it, else the marks are part of the link.\nconst PUNCT = new Set(['!', '\"', '&', \"'\", ')', '*', ',', '.', ';', ':', '<', '?', '_', '~', ']']);\nconst TRAIL_PUNCT = new Set(['!', '\"', \"'\", ')', '*', ',', '.', ';', ':', '?', '_', '~']);\nconst isAlpha = (c: string | undefined): boolean => c !== undefined && ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));\nfunction trailEndsAt(s: string, j: number): boolean {\n for (;;) {\n const c = s[j];\n if (c === undefined) return true;\n if (TRAIL_PUNCT.has(c)) {\n j += 1;\n continue;\n }\n if (c === '&') {\n j += 1;\n if (!isAlpha(s[j])) return false;\n j += 1;\n while (isAlpha(s[j])) j += 1;\n if (s[j] !== ';') return false;\n j += 1;\n continue;\n }\n if (c === ']') {\n j += 1;\n const d = s[j];\n return d === undefined || d === '(' || d === '[' || /\\s/u.test(d ?? ' ');\n }\n if (c === '<') return true;\n if (c !== undefined && /^\\s$/u.test(c)) return true;\n return false;\n }\n}\n// Where the GFM autolink ends in S (the linkifier's text plus the following text), old-style:\n// punctuation that fails the trail test, or a ) with closes <= opens, extends the link.\nfunction gfmAutolinkEnd(s: string): number {\n let open = 0;\n let close = 0;\n for (let i = 0; i < s.length; i++) {\n const c = s[i];\n if (c === '(') {\n open += 1;\n continue;\n }\n if (c === ')' && close < open) {\n close += 1;\n continue;\n }\n if (PUNCT.has(c) && trailEndsAt(s, i)) return i;\n if (c !== undefined && /^\\s$/u.test(c)) return i;\n }\n return s.length;\n}\n// linkify-it links more than GFM's autolink literal (bare domains, ftp://, //host); only the\n// GFM forms (http(s)://, www., email) drop their text.\nfunction isGfmUrl(text: string): boolean {\n return /^https?:\\/\\//i.test(text) || /^www\\./i.test(text);\n}\n// Only a bare address is GFM's email autolink: a url keeps its @, since a path can hold one.\nfunction isGfmEmail(text: string): boolean {\n return !isGfmUrl(text) && text.includes('@');\n}\n// The task-lists plugin injects its checkbox as the item's first inline child.\nfunction isTaskCheckbox(token: Token | undefined): boolean {\n return token?.type === 'html_inline' && /^<input\\b/i.test(token.content);\n}\n// A linkify span can swallow the & of a following entity (span ...c& + text amp; z); the\n// re-emitted lead is then a reference the entity rule never saw, so decode it old-style.\nconst LEAD_ENTITY = /^&[a-z#][a-z0-9]{1,31};/i;\n\n// Split a flat token range into its top-level blocks: nesting 1 opens, nesting 0 is one block.\nfunction topLevelBlocks(tokens: Token[]): Token[][] {\n const out: Token[][] = [];\n let i = 0;\n while (i < tokens.length) {\n const token = tokens[i];\n if (token.nesting === 1) {\n let depth = 1;\n let j = i + 1;\n while (j < tokens.length && depth > 0) {\n depth += tokens[j].nesting === 1 ? 1 : tokens[j].nesting === -1 ? -1 : 0;\n j += 1;\n }\n out.push(tokens.slice(i, j));\n i = j;\n } else if (token.nesting === 0) {\n out.push(tokens.slice(i, i + 1));\n i += 1;\n } else {\n i += 1;\n }\n }\n return out;\n}\n\n// A first line with no source content (a bare task checkbox, whitespace) contributes no line to\n// the value, so its softbreak is dropped; a first line whose content extraction removes (an\n// autolink, an image) still leaves its line ending behind.\nfunction paragraphText(children: Token[], code: string[]): string {\n let k = 0;\n const first = children[0];\n if (isTaskCheckbox(first)) k = 1;\n while (k < children.length && children[k].type === 'text' && children[k].content.trim() === '') k += 1;\n if (k > 0 && children[k]?.type === 'softbreak') return inlineText(children.slice(k + 1), code);\n return inlineText(children, code);\n}\n\nfunction blockText(tokens: Token[], code: string[]): string {\n const first = tokens[0];\n if (!first) return '';\n switch (first.type) {\n case 'heading_open':\n case 'paragraph_open': {\n const inline = tokens.find((t) => t.type === 'inline');\n return inline ? paragraphText(inline.children ?? [], code) : '';\n }\n case 'fence':\n case 'code_block':\n // Fence and indented code tokens carry the closing newline their lines were joined with.\n return codePlaceholder(first.content.replace(/\\n$/, ''), code);\n case 'table_open':\n return tableText(tokens, code);\n case 'ordered_list_open':\n case 'bullet_list_open':\n return listItemsText(tokens, code);\n case 'blockquote_open':\n return blocksIn(tokens.slice(1, -1), code).replace(CALLOUT_MARKER, '');\n case 'html_block':\n // A non-final-line html block carries its last line's terminator, which the mdast value lacked.\n return stripHtml(first.content.replace(/\\n$/, ''));\n case 'footnote_reference_open':\n return blocksIn(tokens.slice(1, -1), code);\n default:\n return '';\n }\n}\n\n// Sibling blocks (list items, blockquote children, footnote bodies) joined one per line;\n// empties dropped so a blank child never widens the gap between its neighbors.\nfunction blocksIn(tokens: Token[], code: string[]): string {\n return topLevelBlocks(tokens)\n .map((b) => blockText(b, code))\n .filter((s) => s.length > 0)\n .join('\\n');\n}\n\n// The task-lists plugin slices 3 of the marker's 4 chars, leaving its trailing space on the text\n// after the checkbox token. Returns a copy with that space dropped, never a mutation: a block is\n// extracted more than once (parse pre-extracts headings, group.ts extracts again).\nfunction withoutTaskMarker(item: Token[]): Token[] {\n for (let i = 0; i < item.length; i++) {\n const token = item[i];\n // The checkbox, if any, sits in the item's first inline only.\n if (token.type !== 'inline' || !token.children?.length) continue;\n const second = token.children[1];\n if (!isTaskCheckbox(token.children[0]) || second?.type !== 'text' || !second.content.startsWith(' ')) return item;\n const children = token.children.slice();\n children[1] = { ...second, content: second.content.slice(1) } as Token;\n const copy = item.slice();\n copy[i] = { ...token, children } as Token;\n return copy;\n }\n return item;\n}\n\nfunction listItemsText(tokens: Token[], code: string[]): string {\n const items: string[] = [];\n for (const item of topLevelBlocks(tokens.slice(1, -1))) {\n items.push(blocksIn(withoutTaskMarker(item).slice(1, -1), code));\n }\n return items.filter((s) => s.length > 0).join('\\n');\n}\n\n// Table rows joined by newline, cells by space (mdast's tableRow/tableCell joiners).\nfunction tableText(tokens: Token[], code: string[]): string {\n const rows: string[] = [];\n let cells: string[] = [];\n for (const token of tokens) {\n if (token.type === 'tr_open') cells = [];\n else if (token.type === 'inline') cells.push(inlineText(token.children ?? [], code));\n else if (token.type === 'tr_close') rows.push(cells.join(' '));\n }\n return rows.join('\\n');\n}\n\n// Inline content (headings, paragraphs, emphasis, links) concatenated with no separator: the\n// source text tokens already carry whatever spacing separates them.\nfunction inlineText(tokens: Token[], code: string[], inAlt = false): string {\n let out = '';\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n if (token.type === 'link_open') {\n let skip = 0;\n let j = i + 1;\n let depth = 1;\n while (j < tokens.length && depth > 0) {\n if (tokens[j].type === 'link_open') depth += 1;\n else if (tokens[j].type === 'link_close') depth -= 1;\n j += 1;\n }\n const text = inlineText(tokens.slice(i + 1, j - 1), code, inAlt);\n const markup = token.markup;\n const next = tokens[j];\n if (inAlt) {\n // An image's alt is plain text: mdast kept every link's own text there, autolinks included.\n out += text;\n } else if (markup === 'linkify' && isGfmUrl(text)) {\n // GFM drop: the next text token resumes at the old link's boundary, re-emitting any\n // trimmed trail. <www.x> has no trail to absorb (the brackets bound it), keep the >.\n // Emails keep their whole remainder: GFM's email machine has no trail, so the span\n // already ends at the old boundary and the entity rule has decoded the rest.\n const prev = tokens[i - 1];\n const bracketed = prev?.type === 'text' && prev.content.endsWith('<') && next?.type === 'text' && next.content.startsWith('>');\n const tail = next?.type === 'text' ? text + next.content : text;\n const k = bracketed ? text.length : gfmAutolinkEnd(tail);\n out += tail.slice(k).replace(LEAD_ENTITY, (m) => parser().utils.unescapeAll(m));\n // The trail came out of the next text token, so that token is consumed here, not re-read.\n if (next?.type === 'text') skip = 1;\n } else if (markup === 'linkify' && isGfmEmail(text)) {\n // Email drop: nothing after the span to trim, so the span alone is dropped.\n } else if (markup === 'autolink') {\n // <...> leaf: dropped whole, its brackets live inside the token so nothing follows to trim.\n } else {\n out += text; // user link or non-GFM linkify target: keep the display text\n }\n i = j - 1 + skip;\n } else if (token.type === 'text') {\n out += token.content;\n } else if (token.type === 'softbreak') {\n out += '\\n';\n } else if (token.type === 'hardbreak') {\n out += ' ';\n } else if (token.type === 'code_inline') {\n out += codePlaceholder(token.content, code);\n } else if (token.type === 'html_inline') {\n out += stripHtml(token.content);\n } else if (token.type === 'image') {\n out += inlineText(token.children ?? [], code, true);\n }\n // Emphasis, strikethrough and footnote markers carry no text of their own.\n }\n return out;\n}\n\nconst CODE_PLACEHOLDER = /\\uE000(\\d+)\\uE000/g;\n\n// Plain text of one parsed block: heading/list/table structure is kept as text, markup (emphasis,\n// link targets, task and callout markers) is dropped. Pure, synchronous.\nexport function extractText(block: Block): string {\n return extractTexts([block]);\n}\n\n// Blocks resolved together: a blank line inside %%...%% splits it across blocks, and a per-block\n// strip then never sees the closing %%. Code stays placeholder-held across all of them.\nexport function extractTexts(blocks: Block[]): string {\n const code: string[] = [];\n const joined = blocks\n .map((b) => blockText(b.node, code))\n .filter((s) => s.length > 0)\n .join('\\n');\n const resolved = resolveFlavor(joined);\n return code.length === 0 ? resolved : resolved.replace(CODE_PLACEHOLDER, (_, i: string) => code[Number(i)]);\n}\n"],"names":["parser","COMMENT_PAIR","EMBED","WIKILINK","BLOCK_ID","CALLOUT_MARKER","HTML_COMMENT","HTML_TAG","stripHtml","value","replace","anchorText","base","hashIdx","indexOf","trim","target","slice","anchor","wikilinkText","inner","pipeIdx","embedText","resolveFlavor","text","_","codePlaceholder","code","idx","push","PUNCT","Set","TRAIL_PUNCT","isAlpha","c","undefined","trailEndsAt","s","j","has","d","test","gfmAutolinkEnd","open","close","i","length","isGfmUrl","isGfmEmail","includes","isTaskCheckbox","token","type","content","LEAD_ENTITY","topLevelBlocks","tokens","out","nesting","depth","paragraphText","children","k","first","inlineText","blockText","inline","find","t","tableText","listItemsText","blocksIn","map","b","filter","join","withoutTaskMarker","item","second","startsWith","copy","items","rows","cells","inAlt","skip","markup","next","prev","bracketed","endsWith","tail","m","utils","unescapeAll","CODE_PLACEHOLDER","extractText","block","extractTexts","blocks","joined","node","resolved","Number"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/chunk/extract.ts"],"sourcesContent":["import type { Token } from 'markdown-it';\nimport { parser } from './parser.ts';\nimport type { Block } from './types.ts';\n\n// markdown-it, like mdast, has no wikilink, embed, or %%comment%% token -- literal text resolved\n// by regex passes over non-code text (code/inline code is placeholder-held and spliced back verbatim).\nconst COMMENT_PAIR = /%%[\\s\\S]*?%%/g;\n// An embed always yields its target, whatever follows a pipe (a resize suffix, never an alias);\n// must run before the wikilink regex below, bang included, or that regex matches first.\nconst EMBED = /!\\[\\[([^\\]]+)\\]\\]/g;\nconst WIKILINK = /\\[\\[([^\\]]+)\\]\\]/g;\n// A trailing \" ^id\" is an Obsidian block anchor, valid only at a line's end; a caret elsewhere\n// (mid-line) is ordinary text and is left alone.\nconst BLOCK_ID = / \\^[A-Za-z0-9-]+$/gm;\n// A callout marker is only ever the first thing in a blockquote's text (Obsidian's grammar),\n// so this anchors to blockquote output alone -- never applied to prose in general.\nconst CALLOUT_MARKER = /^\\[!\\w[\\w-]*\\][+-]?[ \\t]?/;\n// An html token's content is raw HTML, block or inline: a full <!-- --> comment is dropped, any\n// remaining tags are stripped, and the text a browser would still render survives.\nconst HTML_COMMENT = /<!--[\\s\\S]*?-->/g;\nconst HTML_TAG = /<[^>]+>/g;\n\nfunction stripHtml(value: string): string {\n return value.replace(HTML_COMMENT, '').replace(HTML_TAG, '');\n}\n\n// A `#anchor` keeps its text (hash dropped), unlike links.ts's parseWikilinkInner (the resolver\n// authority), which discards it entirely -- replicated here since that return value doesn't fit.\nfunction anchorText(base: string): string {\n const hashIdx = base.indexOf('#');\n if (hashIdx === -1) return base.trim();\n const target = base.slice(0, hashIdx).trim();\n const anchor = base.slice(hashIdx + 1).trim();\n return target ? `${target} ${anchor}` : anchor;\n}\n\nfunction wikilinkText(inner: string): string {\n const pipeIdx = inner.indexOf('|');\n return pipeIdx === -1 ? anchorText(inner) : inner.slice(pipeIdx + 1).trim();\n}\n\nfunction embedText(inner: string): string {\n const pipeIdx = inner.indexOf('|');\n return anchorText(pipeIdx === -1 ? inner : inner.slice(0, pipeIdx));\n}\n\nfunction resolveFlavor(text: string): string {\n return text\n .replace(HTML_COMMENT, '')\n .replace(COMMENT_PAIR, '')\n .replace(EMBED, (_, inner: string) => embedText(inner))\n .replace(WIKILINK, (_, inner: string) => wikilinkText(inner))\n .replace(BLOCK_ID, '');\n}\n\n// U+E000 (Private Use Area) never appears in real markdown text, so it is a collision-free\n// placeholder delimiter, spliced back to the literal code value after flavor resolution.\nfunction codePlaceholder(value: string, code: string[]): string {\n const idx = code.push(value) - 1;\n return `\\uE000${idx}\\uE000`;\n}\n\n// GFM's autolink literal ends where its path machine stops: a trail of punctuation is a genuine\n// end (link stops before it) only when trailEndsAt accepts it, else the marks are part of the link.\nconst PUNCT = new Set(['!', '\"', '&', \"'\", ')', '*', ',', '.', ';', ':', '<', '?', '_', '~', ']']);\nconst TRAIL_PUNCT = new Set(['!', '\"', \"'\", ')', '*', ',', '.', ';', ':', '?', '_', '~']);\nconst isAlpha = (c: string | undefined): boolean => c !== undefined && ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));\nfunction trailEndsAt(s: string, j: number): boolean {\n for (;;) {\n const c = s[j];\n if (c === undefined) return true;\n if (TRAIL_PUNCT.has(c)) {\n j += 1;\n continue;\n }\n if (c === '&') {\n j += 1;\n if (!isAlpha(s[j])) return false;\n j += 1;\n while (isAlpha(s[j])) j += 1;\n if (s[j] !== ';') return false;\n j += 1;\n continue;\n }\n if (c === ']') {\n j += 1;\n const d = s[j];\n return d === undefined || d === '(' || d === '[' || /\\s/u.test(d ?? ' ');\n }\n if (c === '<') return true;\n if (c !== undefined && /^\\s$/u.test(c)) return true;\n return false;\n }\n}\n// Where the GFM autolink ends in S (the linkifier's text plus the following text), old-style:\n// punctuation that fails the trail test, or a ) with closes <= opens, extends the link.\nfunction gfmAutolinkEnd(s: string): number {\n let open = 0;\n let close = 0;\n for (let i = 0; i < s.length; i++) {\n const c = s[i];\n if (c === '(') {\n open += 1;\n continue;\n }\n if (c === ')' && close < open) {\n close += 1;\n continue;\n }\n if (PUNCT.has(c) && trailEndsAt(s, i)) return i;\n if (c !== undefined && /^\\s$/u.test(c)) return i;\n }\n return s.length;\n}\n// linkify-it links more than GFM's autolink literal (bare domains, ftp://, //host); only the\n// GFM forms (http(s)://, www., email) drop their text.\nfunction isGfmUrl(text: string): boolean {\n return /^https?:\\/\\//i.test(text) || /^www\\./i.test(text);\n}\n// Only a bare address is GFM's email autolink: a url keeps its @, since a path can hold one.\nfunction isGfmEmail(text: string): boolean {\n return !isGfmUrl(text) && text.includes('@');\n}\n// The task-lists plugin injects its checkbox as the item's first inline child.\nfunction isTaskCheckbox(token: Token | undefined): boolean {\n return token?.type === 'html_inline' && /^<input\\b/i.test(token.content);\n}\n// A linkify span can swallow the & of a following entity (span ...c& + text amp; z); the\n// re-emitted lead is then a reference the entity rule never saw, so decode it old-style.\nconst LEAD_ENTITY = /^&[a-z#][a-z0-9]{1,31};/i;\n\n// Split a flat token range into its top-level blocks: nesting 1 opens, nesting 0 is one block.\nfunction topLevelBlocks(tokens: Token[]): Token[][] {\n const out: Token[][] = [];\n let i = 0;\n while (i < tokens.length) {\n const token = tokens[i];\n if (token.nesting === 1) {\n let depth = 1;\n let j = i + 1;\n while (j < tokens.length && depth > 0) {\n depth += tokens[j].nesting === 1 ? 1 : tokens[j].nesting === -1 ? -1 : 0;\n j += 1;\n }\n out.push(tokens.slice(i, j));\n i = j;\n } else if (token.nesting === 0) {\n out.push(tokens.slice(i, i + 1));\n i += 1;\n } else {\n i += 1;\n }\n }\n return out;\n}\n\n// A first line with no source content (a bare task checkbox, whitespace) contributes no line to\n// the value, so its softbreak is dropped; a first line whose content extraction removes (an\n// autolink, an image) still leaves its line ending behind.\nfunction paragraphText(children: Token[], code: string[]): string {\n let k = 0;\n const first = children[0];\n if (isTaskCheckbox(first)) k = 1;\n while (k < children.length && children[k].type === 'text' && children[k].content.trim() === '') k += 1;\n if (k > 0 && children[k]?.type === 'softbreak') return inlineText(children.slice(k + 1), code);\n return inlineText(children, code);\n}\n\nfunction blockText(tokens: Token[], code: string[]): string {\n const first = tokens[0];\n if (!first) return '';\n switch (first.type) {\n case 'heading_open':\n case 'paragraph_open': {\n const inline = tokens.find((t) => t.type === 'inline');\n return inline ? paragraphText(inline.children ?? [], code) : '';\n }\n case 'fence':\n case 'code_block':\n // Fence and indented code tokens carry the closing newline their lines were joined with.\n return codePlaceholder(first.content.replace(/\\n$/, ''), code);\n case 'table_open':\n return tableText(tokens, code);\n case 'ordered_list_open':\n case 'bullet_list_open':\n return listItemsText(tokens, code);\n case 'blockquote_open':\n return blocksIn(tokens.slice(1, -1), code).replace(CALLOUT_MARKER, '');\n case 'html_block':\n // A non-final-line html block carries its last line's terminator, which the mdast value lacked.\n return stripHtml(first.content.replace(/\\n$/, ''));\n case 'footnote_reference_open':\n return blocksIn(tokens.slice(1, -1), code);\n default:\n return '';\n }\n}\n\n// Sibling blocks (list items, blockquote children, footnote bodies) joined one per line;\n// empties dropped so a blank child never widens the gap between its neighbors.\nfunction blocksIn(tokens: Token[], code: string[]): string {\n return topLevelBlocks(tokens)\n .map((b) => blockText(b, code))\n .filter((s) => s.length > 0)\n .join('\\n');\n}\n\n// The task-lists plugin slices 3 of the marker's 4 chars, leaving its trailing space on the text\n// after the checkbox token. Returns a copy with that space dropped, never a mutation: a block is\n// extracted more than once (parse pre-extracts headings, group.ts extracts again).\nfunction withoutTaskMarker(item: Token[]): Token[] {\n for (let i = 0; i < item.length; i++) {\n const token = item[i];\n // The checkbox, if any, sits in the item's first inline only.\n if (token.type !== 'inline' || !token.children?.length) continue;\n const second = token.children[1];\n if (!isTaskCheckbox(token.children[0]) || second?.type !== 'text' || !second.content.startsWith(' ')) return item;\n const children = token.children.slice();\n children[1] = { ...second, content: second.content.slice(1) } as Token;\n const copy = item.slice();\n copy[i] = { ...token, children } as Token;\n return copy;\n }\n return item;\n}\n\nfunction listItemsText(tokens: Token[], code: string[]): string {\n const items: string[] = [];\n for (const item of topLevelBlocks(tokens.slice(1, -1))) {\n items.push(blocksIn(withoutTaskMarker(item).slice(1, -1), code));\n }\n return items.filter((s) => s.length > 0).join('\\n');\n}\n\n// Table rows joined by newline, cells by space (mdast's tableRow/tableCell joiners).\nfunction tableText(tokens: Token[], code: string[]): string {\n const rows: string[] = [];\n let cells: string[] = [];\n for (const token of tokens) {\n if (token.type === 'tr_open') cells = [];\n else if (token.type === 'inline') cells.push(inlineText(token.children ?? [], code));\n else if (token.type === 'tr_close') rows.push(cells.join(' '));\n }\n return rows.join('\\n');\n}\n\n// Inline content (headings, paragraphs, emphasis, links) concatenated with no separator: the\n// source text tokens already carry whatever spacing separates them.\nfunction inlineText(tokens: Token[], code: string[], inAlt = false): string {\n let out = '';\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n if (token.type === 'link_open') {\n let skip = 0;\n let j = i + 1;\n let depth = 1;\n while (j < tokens.length && depth > 0) {\n if (tokens[j].type === 'link_open') depth += 1;\n else if (tokens[j].type === 'link_close') depth -= 1;\n j += 1;\n }\n const text = inlineText(tokens.slice(i + 1, j - 1), code, inAlt);\n const markup = token.markup;\n const next = tokens[j];\n if (inAlt) {\n // An image's alt is plain text: mdast kept every link's own text there, autolinks included.\n out += text;\n } else if (markup === 'linkify' && isGfmUrl(text)) {\n // GFM drop: the next text token resumes at the old link's boundary, re-emitting any\n // trimmed trail. <www.x> has no trail to absorb (the brackets bound it), keep the >.\n // Emails keep their whole remainder: GFM's email machine has no trail, so the span\n // already ends at the old boundary and the entity rule has decoded the rest.\n const prev = tokens[i - 1];\n const bracketed = prev?.type === 'text' && prev.content.endsWith('<') && next?.type === 'text' && next.content.startsWith('>');\n const tail = next?.type === 'text' ? text + next.content : text;\n const k = bracketed ? text.length : gfmAutolinkEnd(tail);\n out += tail.slice(k).replace(LEAD_ENTITY, (m) => parser().utils.unescapeAll(m));\n // The trail came out of the next text token, so that token is consumed here, not re-read.\n if (next?.type === 'text') skip = 1;\n } else if (markup === 'linkify' && isGfmEmail(text)) {\n // Email drop: nothing after the span to trim, so the span alone is dropped.\n } else if (markup === 'autolink') {\n // <...> leaf: dropped whole, its brackets live inside the token so nothing follows to trim.\n } else {\n out += text; // user link or non-GFM linkify target: keep the display text\n }\n i = j - 1 + skip;\n } else if (token.type === 'text') {\n out += token.content;\n } else if (token.type === 'softbreak') {\n out += '\\n';\n } else if (token.type === 'hardbreak') {\n out += ' ';\n } else if (token.type === 'code_inline') {\n out += codePlaceholder(token.content, code);\n } else if (token.type === 'html_inline') {\n out += stripHtml(token.content);\n } else if (token.type === 'image') {\n out += inlineText(token.children ?? [], code, true);\n }\n // Emphasis, strikethrough and footnote markers carry no text of their own.\n }\n return out;\n}\n\nconst CODE_PLACEHOLDER = /\\uE000(\\d+)\\uE000/g;\n\n// Plain text of one parsed block: heading/list/table structure is kept as text, markup (emphasis,\n// link targets, task and callout markers) is dropped. Pure, synchronous.\nexport function extractText(block: Block): string {\n return extractTexts([block]);\n}\n\n// Blocks resolved together: a blank line inside %%...%% splits it across blocks, and a per-block\n// strip then never sees the closing %%. Code stays placeholder-held across all of them.\nexport function extractTexts(blocks: Block[]): string {\n const code: string[] = [];\n const joined = blocks\n .map((b) => blockText(b.node, code))\n .filter((s) => s.length > 0)\n .join('\\n');\n const resolved = resolveFlavor(joined);\n return code.length === 0 ? resolved : resolved.replace(CODE_PLACEHOLDER, (_, i: string) => code[Number(i)]);\n}\n"],"names":["parser","COMMENT_PAIR","EMBED","WIKILINK","BLOCK_ID","CALLOUT_MARKER","HTML_COMMENT","HTML_TAG","stripHtml","value","replace","anchorText","base","hashIdx","indexOf","trim","target","slice","anchor","wikilinkText","inner","pipeIdx","embedText","resolveFlavor","text","_","codePlaceholder","code","idx","push","PUNCT","Set","TRAIL_PUNCT","isAlpha","c","undefined","trailEndsAt","s","j","has","d","test","gfmAutolinkEnd","open","close","i","length","isGfmUrl","isGfmEmail","includes","isTaskCheckbox","token","type","content","LEAD_ENTITY","topLevelBlocks","tokens","out","nesting","depth","paragraphText","children","k","first","inlineText","blockText","inline","find","t","tableText","listItemsText","blocksIn","map","b","filter","join","withoutTaskMarker","item","second","startsWith","copy","items","rows","cells","inAlt","skip","markup","next","prev","bracketed","endsWith","tail","m","utils","unescapeAll","CODE_PLACEHOLDER","extractText","block","extractTexts","blocks","joined","node","resolved","Number"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/group.ts"],"sourcesContent":["import { extractText } from './extract.ts';\nimport { parse } from './parse.ts';\nimport { DEFAULT_TARGET_TOKENS, estimateTokens } from './tokens.ts';\nimport type { Block, BlockType, Chunk, ChunkOptions } from './types.ts';\n\nconst PGC_GROUP_SIZE = 2;\nconst OVERSIZE_TRIGGER_MULTIPLE = 2;\n\ninterface ResolvedOptions {\n targetTokens: number;\n text: 'extracted' | 'raw';\n}\n\nfunction resolveOptions(opts?: ChunkOptions): ResolvedOptions {\n return {\n targetTokens: opts?.targetTokens ?? DEFAULT_TARGET_TOKENS,\n text: opts?.text ?? 'raw',\n };\n}\n\n// A heading of any depth ends the current scope and starts a new one (D1); the heading block\n// itself is carried into the new scope, where it joins that scope's first group (F7/F10).\nfunction splitScopes(blocks: Block[]): Block[][] {\n const scopes: Block[][] = [];\n let current: Block[] = [];\n for (const block of blocks) {\n if (block.type === 'heading' && current.length > 0) {\n scopes.push(current);\n current = [];\n }\n current.push(block);\n }\n if (current.length > 0) scopes.push(current);\n return scopes;\n}\n\ninterface Part {\n startLine: number;\n endLine: number;\n text: string;\n // True for a sub-line split piece: its text is already the final slice, not the whole line --\n // group()'s extent-based raw re-slice must not touch it (siblings share startLine === endLine).\n final?: boolean;\n}\n\nfunction finalize(parts: Part[]): (Chunk & { final?: boolean }) | undefined {\n if (parts.length === 0) return undefined;\n const first = parts[0];\n const last = parts[parts.length - 1];\n return { startLine: first.startLine, endLine: last.endLine, text: parts.map((p) => p.text).join('\\n'), final: parts.some((p) => p.final) };\n}\n\nconst NEWLINE_TOKENS = estimateTokens('\\n');\n// Built on first use and kept: each construction is ~3.5 ms, and only an oversize block is ever\n// split, so no command pays for a segmenter it never reaches.\nconst SEGMENTERS = new Map<string, Intl.Segmenter>();\n\nfunction segmentsOf(text: string, granularity: 'sentence' | 'word'): string[] {\n let segmenter = SEGMENTERS.get(granularity);\n if (!segmenter) {\n segmenter = new Intl.Segmenter(undefined, { granularity });\n SEGMENTERS.set(granularity, segmenter);\n }\n return Array.from(segmenter.segment(text), (s) => s.segment);\n}\n\n// Greedily packs segments (already contiguous, tiling the source text with no gaps) into groups\n// of at most `working` estimated tokens; a lone segment over `working` still stands alone.\nfunction pack(segments: string[], working: number): string[] {\n const groups: string[] = [];\n let current = '';\n let tokens = 0;\n for (const segment of segments) {\n const segmentTokens = estimateTokens(segment);\n if (current.length > 0 && tokens + segmentTokens > working) {\n groups.push(current);\n current = '';\n tokens = 0;\n }\n current += segment;\n tokens += segmentTokens;\n }\n if (current.length > 0) groups.push(current);\n return groups;\n}\n\n// Line-split alone can't shrink a lone dense line (the CJK case): falls back to sentence then\n// word boundaries (Intl.Segmenter, the same grapheme-safe engine as segment.ts), mode-agnostic on `text`.\nfunction splitLineText(text: string, working: number): string[] {\n const sentences = segmentsOf(text, 'sentence');\n const out: string[] = [];\n let current = '';\n let tokens = 0;\n const flush = () => {\n if (current.length > 0) {\n out.push(current);\n current = '';\n tokens = 0;\n }\n };\n for (const sentence of sentences) {\n const sentenceTokens = estimateTokens(sentence);\n if (sentenceTokens > working) {\n flush();\n out.push(...pack(segmentsOf(sentence, 'word'), working));\n continue;\n }\n if (current.length > 0 && tokens + sentenceTokens > working) flush();\n current += sentence;\n tokens += sentenceTokens;\n }\n flush();\n return out;\n}\n\nconst ATOMIC_TYPES: ReadonlySet<BlockType> = new Set(['code', 'table', 'list']);\n\n// Atomic (code/table/list) pieces are always a raw line slice: re-parsing a table's later pieces\n// without their header/delimiter rows would demote them to paragraph text.\nfunction piece(pieceLines: string[], startLine: number, endLine: number, blockType: BlockType, textMode: 'extracted' | 'raw'): Part {\n const text =\n ATOMIC_TYPES.has(blockType) || textMode === 'raw'\n ? pieceLines.join('\\n')\n : parse(pieceLines.join('\\n'))\n .map((b) => extractText(b))\n .join('\\n');\n return { startLine, endLine, text };\n}\n\n// A one-line piece over working can't shrink via another line-boundary pass (rule 5's gap), so it\n// splits at sentence/word boundaries instead; `final` stops group() re-deriving its text by extent (F5).\nfunction finalizePiece(pieceLines: string[], startLine: number, endLine: number, working: number, blockType: BlockType, textMode: 'extracted' | 'raw'): Part[] {\n const p = piece(pieceLines, startLine, endLine, blockType, textMode);\n if (pieceLines.length === 1 && estimateTokens(p.text) > working) {\n return splitLineText(p.text, working).map((text) => ({ startLine, endLine, text, final: true }));\n }\n return [p];\n}\n\n// A block over 2x working size splits at line boundaries into pieces each <= working size, never\n// mid-line. `seed`: pending tokens (e.g. a heading) the first piece must join, checked against the limit.\nfunction splitOversizeBlock(lines: string[], startLine: number, endLine: number, working: number, blockType: BlockType, textMode: 'extracted' | 'raw', seed = 0): Part[] {\n const pieces: Part[] = [];\n let pieceLines: string[] = [];\n let pieceStart = startLine;\n let tokens = seed;\n for (let line = startLine; line <= endLine; line++) {\n const lineText = lines[line - 1];\n const sep = pieceLines.length > 0 || tokens > 0 ? NEWLINE_TOKENS : 0;\n const lineTokens = estimateTokens(lineText);\n if (pieceLines.length > 0 && tokens + sep + lineTokens > working) {\n pieces.push(...finalizePiece(pieceLines, pieceStart, line - 1, working, blockType, textMode));\n pieceLines = [];\n tokens = 0;\n pieceStart = line;\n pieceLines.push(lineText);\n tokens += lineTokens;\n continue;\n }\n pieceLines.push(lineText);\n tokens += sep + lineTokens;\n }\n if (pieceLines.length > 0) pieces.push(...finalizePiece(pieceLines, pieceStart, endLine, working, blockType, textMode));\n return pieces;\n}\n\n// One heading scope's groups (D1): a heading opens the first group, and an oversize block\n// (rule 5, including an oversize heading) splits into pieces that each close their own group.\nfunction groupScope(scopeBlocks: Block[], lines: string[], resolved: ResolvedOptions): (Chunk & { final?: boolean })[] {\n const working = resolved.targetTokens;\n const trigger = working * OVERSIZE_TRIGGER_MULTIPLE;\n const finished: (Chunk & { final?: boolean })[] = [];\n let parts: Part[] = [];\n let paragraphCount = 0;\n let tokens = 0;\n\n function close(): void {\n const group = finalize(parts);\n if (group) finished.push(group);\n parts = [];\n paragraphCount = 0;\n tokens = 0;\n }\n\n // tokens tracks the active text mode's own estimate (a newline between parts costs\n // NEWLINE_TOKENS too), so packing decisions size the text the chunk will actually ship as.\n function addPart(text: string, sizeText: string, startLine: number, endLine: number): void {\n tokens += (parts.length > 0 ? NEWLINE_TOKENS : 0) + estimateTokens(sizeText);\n parts.push({ startLine, endLine, text });\n }\n\n for (const block of scopeBlocks) {\n const raw = lines.slice(block.startLine - 1, block.endLine).join('\\n');\n const blockTokens = estimateTokens(raw);\n\n if (blockTokens > trigger) {\n const seed = parts.length > 0 ? tokens : 0;\n for (const p of splitOversizeBlock(lines, block.startLine, block.endLine, working, block.type, resolved.text, seed)) {\n parts.push(p);\n close();\n }\n continue;\n }\n\n const extracted = extractText(block);\n const sizeText = resolved.text === 'raw' ? raw : extracted;\n\n if (block.type === 'heading') {\n addPart(extracted, sizeText, block.startLine, block.endLine);\n continue;\n }\n\n // The 2x-working invariant holds even under pgc's paper-faithful 2-paragraph pairing --\n // close first if the pair about to form would cross it.\n const pairOversize = parts.length > 0 && tokens + NEWLINE_TOKENS + blockTokens > trigger;\n if (pairOversize) close();\n\n addPart(extracted, sizeText, block.startLine, block.endLine);\n paragraphCount++;\n\n if (paragraphCount >= PGC_GROUP_SIZE) close();\n }\n close();\n\n return finished;\n}\n\n// Groups already-parsed blocks per opts (D1/D3), against the same body the blocks were parsed\n// from (line lookups for oversize splitting).\nexport function group(blocks: Block[], body: string, opts?: ChunkOptions): Chunk[] {\n const resolved = resolveOptions(opts);\n const lines = body.split('\\n');\n const chunks: (Chunk & { final?: boolean })[] = [];\n for (const scope of splitScopes(blocks)) chunks.push(...groupScope(scope, lines, resolved));\n // 'raw': the chunk's own source lines verbatim, replacing the flavor-resolved join above (D9).\n // A `final` chunk already carries its own slice's raw text; re-slicing by extent would return the whole shared line.\n const texted =\n resolved.text === 'raw'\n ? chunks.map((c) =>\n c.final\n ? c\n : {\n ...c,\n text: lines\n .slice(c.startLine - 1, c.endLine)\n .join('\\n')\n .trim(),\n }\n )\n : chunks;\n // A group can be all-blank (flavor-stripped to nothing, or a raw slice of pure syntax); it never produces a chunk.\n return texted.filter((c) => c.text.trim().length > 0).map((c) => ({ startLine: c.startLine, endLine: c.endLine, text: c.text }));\n}\n"],"names":["extractText","parse","DEFAULT_TARGET_TOKENS","estimateTokens","PGC_GROUP_SIZE","OVERSIZE_TRIGGER_MULTIPLE","resolveOptions","opts","targetTokens","text","splitScopes","blocks","scopes","current","block","type","length","push","finalize","parts","undefined","first","last","startLine","endLine","map","p","join","final","some","NEWLINE_TOKENS","SEGMENTERS","Map","segmentsOf","granularity","segmenter","get","Intl","Segmenter","set","Array","from","segment","s","pack","segments","working","groups","tokens","segmentTokens","splitLineText","sentences","out","flush","sentence","sentenceTokens","ATOMIC_TYPES","Set","piece","pieceLines","blockType","textMode","has","b","finalizePiece","splitOversizeBlock","lines","seed","pieces","pieceStart","line","lineText","sep","lineTokens","groupScope","scopeBlocks","resolved","trigger","finished","paragraphCount","close","group","addPart","sizeText","raw","slice","blockTokens","extracted","pairOversize","body","split","chunks","scope","texted","c","trim","filter"],"mappings":"AAAA,SAASA,WAAW,QAAQ,eAAe;AAC3C,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,qBAAqB,EAAEC,cAAc,QAAQ,cAAc;AAGpE,MAAMC,iBAAiB;AACvB,MAAMC,4BAA4B;AAOlC,SAASC,eAAeC,IAAmB;;IACzC,OAAO;QACLC,YAAY,UAAED,iBAAAA,2BAAAA,KAAMC,YAAY,uCAAIN;QACpCO,IAAI,WAAEF,iBAAAA,2BAAAA,KAAME,IAAI,yCAAI;IACtB;AACF;AAEA,6FAA6F;AAC7F,0FAA0F;AAC1F,SAASC,YAAYC,MAAe;IAClC,MAAMC,SAAoB,EAAE;IAC5B,IAAIC,UAAmB,EAAE;IACzB,KAAK,MAAMC,SAASH,OAAQ;QAC1B,IAAIG,MAAMC,IAAI,KAAK,aAAaF,QAAQG,MAAM,GAAG,GAAG;YAClDJ,OAAOK,IAAI,CAACJ;YACZA,UAAU,EAAE;QACd;QACAA,QAAQI,IAAI,CAACH;IACf;IACA,IAAID,QAAQG,MAAM,GAAG,GAAGJ,OAAOK,IAAI,CAACJ;IACpC,OAAOD;AACT;AAWA,SAASM,SAASC,KAAa;IAC7B,IAAIA,MAAMH,MAAM,KAAK,GAAG,OAAOI;IAC/B,MAAMC,QAAQF,KAAK,CAAC,EAAE;IACtB,MAAMG,OAAOH,KAAK,CAACA,MAAMH,MAAM,GAAG,EAAE;IACpC,OAAO;QAAEO,WAAWF,MAAME,SAAS;QAAEC,SAASF,KAAKE,OAAO;QAAEf,MAAMU,MAAMM,GAAG,CAAC,CAACC,IAAMA,EAAEjB,IAAI,EAAEkB,IAAI,CAAC;QAAOC,OAAOT,MAAMU,IAAI,CAAC,CAACH,IAAMA,EAAEE,KAAK;IAAE;AAC3I;AAEA,MAAME,iBAAiB3B,eAAe;AACtC,gGAAgG;AAChG,8DAA8D;AAC9D,MAAM4B,aAAa,IAAIC;AAEvB,SAASC,WAAWxB,IAAY,EAAEyB,WAAgC;IAChE,IAAIC,YAAYJ,WAAWK,GAAG,CAACF;IAC/B,IAAI,CAACC,WAAW;QACdA,YAAY,IAAIE,KAAKC,SAAS,CAAClB,WAAW;YAAEc;QAAY;QACxDH,WAAWQ,GAAG,CAACL,aAAaC;IAC9B;IACA,OAAOK,MAAMC,IAAI,CAACN,UAAUO,OAAO,CAACjC,OAAO,CAACkC,IAAMA,EAAED,OAAO;AAC7D;AAEA,gGAAgG;AAChG,2FAA2F;AAC3F,SAASE,KAAKC,QAAkB,EAAEC,OAAe;IAC/C,MAAMC,SAAmB,EAAE;IAC3B,IAAIlC,UAAU;IACd,IAAImC,SAAS;IACb,KAAK,MAAMN,WAAWG,SAAU;QAC9B,MAAMI,gBAAgB9C,eAAeuC;QACrC,IAAI7B,QAAQG,MAAM,GAAG,KAAKgC,SAASC,gBAAgBH,SAAS;YAC1DC,OAAO9B,IAAI,CAACJ;YACZA,UAAU;YACVmC,SAAS;QACX;QACAnC,WAAW6B;QACXM,UAAUC;IACZ;IACA,IAAIpC,QAAQG,MAAM,GAAG,GAAG+B,OAAO9B,IAAI,CAACJ;IACpC,OAAOkC;AACT;AAEA,8FAA8F;AAC9F,0GAA0G;AAC1G,SAASG,cAAczC,IAAY,EAAEqC,OAAe;IAClD,MAAMK,YAAYlB,WAAWxB,MAAM;IACnC,MAAM2C,MAAgB,EAAE;IACxB,IAAIvC,UAAU;IACd,IAAImC,SAAS;IACb,MAAMK,QAAQ;QACZ,IAAIxC,QAAQG,MAAM,GAAG,GAAG;YACtBoC,IAAInC,IAAI,CAACJ;YACTA,UAAU;YACVmC,SAAS;QACX;IACF;IACA,KAAK,MAAMM,YAAYH,UAAW;QAChC,MAAMI,iBAAiBpD,eAAemD;QACtC,IAAIC,iBAAiBT,SAAS;YAC5BO;YACAD,IAAInC,IAAI,IAAI2B,KAAKX,WAAWqB,UAAU,SAASR;YAC/C;QACF;QACA,IAAIjC,QAAQG,MAAM,GAAG,KAAKgC,SAASO,iBAAiBT,SAASO;QAC7DxC,WAAWyC;QACXN,UAAUO;IACZ;IACAF;IACA,OAAOD;AACT;AAEA,MAAMI,eAAuC,IAAIC,IAAI;IAAC;IAAQ;IAAS;CAAO;AAE9E,iGAAiG;AACjG,2EAA2E;AAC3E,SAASC,MAAMC,UAAoB,EAAEpC,SAAiB,EAAEC,OAAe,EAAEoC,SAAoB,EAAEC,QAA6B;IAC1H,MAAMpD,OACJ+C,aAAaM,GAAG,CAACF,cAAcC,aAAa,QACxCF,WAAWhC,IAAI,CAAC,QAChB1B,MAAM0D,WAAWhC,IAAI,CAAC,OACnBF,GAAG,CAAC,CAACsC,IAAM/D,YAAY+D,IACvBpC,IAAI,CAAC;IACd,OAAO;QAAEJ;QAAWC;QAASf;IAAK;AACpC;AAEA,kGAAkG;AAClG,yGAAyG;AACzG,SAASuD,cAAcL,UAAoB,EAAEpC,SAAiB,EAAEC,OAAe,EAAEsB,OAAe,EAAEc,SAAoB,EAAEC,QAA6B;IACnJ,MAAMnC,IAAIgC,MAAMC,YAAYpC,WAAWC,SAASoC,WAAWC;IAC3D,IAAIF,WAAW3C,MAAM,KAAK,KAAKb,eAAeuB,EAAEjB,IAAI,IAAIqC,SAAS;QAC/D,OAAOI,cAAcxB,EAAEjB,IAAI,EAAEqC,SAASrB,GAAG,CAAC,CAAChB,OAAU,CAAA;gBAAEc;gBAAWC;gBAASf;gBAAMmB,OAAO;YAAK,CAAA;IAC/F;IACA,OAAO;QAACF;KAAE;AACZ;AAEA,iGAAiG;AACjG,0GAA0G;AAC1G,SAASuC,mBAAmBC,KAAe,EAAE3C,SAAiB,EAAEC,OAAe,EAAEsB,OAAe,EAAEc,SAAoB,EAAEC,QAA6B,EAAEM,OAAO,CAAC;IAC7J,MAAMC,SAAiB,EAAE;IACzB,IAAIT,aAAuB,EAAE;IAC7B,IAAIU,aAAa9C;IACjB,IAAIyB,SAASmB;IACb,IAAK,IAAIG,OAAO/C,WAAW+C,QAAQ9C,SAAS8C,OAAQ;QAClD,MAAMC,WAAWL,KAAK,CAACI,OAAO,EAAE;QAChC,MAAME,MAAMb,WAAW3C,MAAM,GAAG,KAAKgC,SAAS,IAAIlB,iBAAiB;QACnE,MAAM2C,aAAatE,eAAeoE;QAClC,IAAIZ,WAAW3C,MAAM,GAAG,KAAKgC,SAASwB,MAAMC,aAAa3B,SAAS;YAChEsB,OAAOnD,IAAI,IAAI+C,cAAcL,YAAYU,YAAYC,OAAO,GAAGxB,SAASc,WAAWC;YACnFF,aAAa,EAAE;YACfX,SAAS;YACTqB,aAAaC;YACbX,WAAW1C,IAAI,CAACsD;YAChBvB,UAAUyB;YACV;QACF;QACAd,WAAW1C,IAAI,CAACsD;QAChBvB,UAAUwB,MAAMC;IAClB;IACA,IAAId,WAAW3C,MAAM,GAAG,GAAGoD,OAAOnD,IAAI,IAAI+C,cAAcL,YAAYU,YAAY7C,SAASsB,SAASc,WAAWC;IAC7G,OAAOO;AACT;AAEA,0FAA0F;AAC1F,8FAA8F;AAC9F,SAASM,WAAWC,WAAoB,EAAET,KAAe,EAAEU,QAAyB;IAClF,MAAM9B,UAAU8B,SAASpE,YAAY;IACrC,MAAMqE,UAAU/B,UAAUzC;IAC1B,MAAMyE,WAA4C,EAAE;IACpD,IAAI3D,QAAgB,EAAE;IACtB,IAAI4D,iBAAiB;IACrB,IAAI/B,SAAS;IAEb,SAASgC;QACP,MAAMC,QAAQ/D,SAASC;QACvB,IAAI8D,OAAOH,SAAS7D,IAAI,CAACgE;QACzB9D,QAAQ,EAAE;QACV4D,iBAAiB;QACjB/B,SAAS;IACX;IAEA,mFAAmF;IACnF,2FAA2F;IAC3F,SAASkC,QAAQzE,IAAY,EAAE0E,QAAgB,EAAE5D,SAAiB,EAAEC,OAAe;QACjFwB,UAAU,AAAC7B,CAAAA,MAAMH,MAAM,GAAG,IAAIc,iBAAiB,CAAA,IAAK3B,eAAegF;QACnEhE,MAAMF,IAAI,CAAC;YAAEM;YAAWC;YAASf;QAAK;IACxC;IAEA,KAAK,MAAMK,SAAS6D,YAAa;QAC/B,MAAMS,MAAMlB,MAAMmB,KAAK,CAACvE,MAAMS,SAAS,GAAG,GAAGT,MAAMU,OAAO,EAAEG,IAAI,CAAC;QACjE,MAAM2D,cAAcnF,eAAeiF;QAEnC,IAAIE,cAAcT,SAAS;YACzB,MAAMV,OAAOhD,MAAMH,MAAM,GAAG,IAAIgC,SAAS;YACzC,KAAK,MAAMtB,KAAKuC,mBAAmBC,OAAOpD,MAAMS,SAAS,EAAET,MAAMU,OAAO,EAAEsB,SAAShC,MAAMC,IAAI,EAAE6D,SAASnE,IAAI,EAAE0D,MAAO;gBACnHhD,MAAMF,IAAI,CAACS;gBACXsD;YACF;YACA;QACF;QAEA,MAAMO,YAAYvF,YAAYc;QAC9B,MAAMqE,WAAWP,SAASnE,IAAI,KAAK,QAAQ2E,MAAMG;QAEjD,IAAIzE,MAAMC,IAAI,KAAK,WAAW;YAC5BmE,QAAQK,WAAWJ,UAAUrE,MAAMS,SAAS,EAAET,MAAMU,OAAO;YAC3D;QACF;QAEA,wFAAwF;QACxF,wDAAwD;QACxD,MAAMgE,eAAerE,MAAMH,MAAM,GAAG,KAAKgC,SAASlB,iBAAiBwD,cAAcT;QACjF,IAAIW,cAAcR;QAElBE,QAAQK,WAAWJ,UAAUrE,MAAMS,SAAS,EAAET,MAAMU,OAAO;QAC3DuD;QAEA,IAAIA,kBAAkB3E,gBAAgB4E;IACxC;IACAA;IAEA,OAAOF;AACT;AAEA,8FAA8F;AAC9F,8CAA8C;AAC9C,OAAO,SAASG,MAAMtE,MAAe,EAAE8E,IAAY,EAAElF,IAAmB;IACtE,MAAMqE,WAAWtE,eAAeC;IAChC,MAAM2D,QAAQuB,KAAKC,KAAK,CAAC;IACzB,MAAMC,SAA0C,EAAE;IAClD,KAAK,MAAMC,SAASlF,YAAYC,QAASgF,OAAO1E,IAAI,IAAIyD,WAAWkB,OAAO1B,OAAOU;IACjF,+FAA+F;IAC/F,qHAAqH;IACrH,MAAMiB,SACJjB,SAASnE,IAAI,KAAK,QACdkF,OAAOlE,GAAG,CAAC,CAACqE,IACVA,EAAElE,KAAK,GACHkE,IACA;YACE,GAAGA,CAAC;YACJrF,MAAMyD,MACHmB,KAAK,CAACS,EAAEvE,SAAS,GAAG,GAAGuE,EAAEtE,OAAO,EAChCG,IAAI,CAAC,MACLoE,IAAI;QACT,KAENJ;IACN,mHAAmH;IACnH,OAAOE,OAAOG,MAAM,CAAC,CAACF,IAAMA,EAAErF,IAAI,CAACsF,IAAI,GAAG/E,MAAM,GAAG,GAAGS,GAAG,CAAC,CAACqE,IAAO,CAAA;YAAEvE,WAAWuE,EAAEvE,SAAS;YAAEC,SAASsE,EAAEtE,OAAO;YAAEf,MAAMqF,EAAErF,IAAI;QAAC,CAAA;AAC/H"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/chunk/group.ts"],"sourcesContent":["import { extractText } from './extract.ts';\nimport { parse } from './parse.ts';\nimport { DEFAULT_TARGET_TOKENS, estimateTokens } from './tokens.ts';\nimport type { Block, BlockType, Chunk, ChunkOptions } from './types.ts';\n\nconst PGC_GROUP_SIZE = 2;\nconst OVERSIZE_TRIGGER_MULTIPLE = 2;\n\ninterface ResolvedOptions {\n targetTokens: number;\n text: 'extracted' | 'raw';\n}\n\nfunction resolveOptions(opts?: ChunkOptions): ResolvedOptions {\n return {\n targetTokens: opts?.targetTokens ?? DEFAULT_TARGET_TOKENS,\n text: opts?.text ?? 'raw',\n };\n}\n\n// A heading of any depth ends the current scope and starts a new one (D1); the heading block\n// itself is carried into the new scope, where it joins that scope's first group (F7/F10).\nfunction splitScopes(blocks: Block[]): Block[][] {\n const scopes: Block[][] = [];\n let current: Block[] = [];\n for (const block of blocks) {\n if (block.type === 'heading' && current.length > 0) {\n scopes.push(current);\n current = [];\n }\n current.push(block);\n }\n if (current.length > 0) scopes.push(current);\n return scopes;\n}\n\ninterface Part {\n startLine: number;\n endLine: number;\n text: string;\n // True for a sub-line split piece: its text is already the final slice, not the whole line --\n // group()'s extent-based raw re-slice must not touch it (siblings share startLine === endLine).\n final?: boolean;\n}\n\nfunction finalize(parts: Part[]): (Chunk & { final?: boolean }) | undefined {\n if (parts.length === 0) return undefined;\n const first = parts[0];\n const last = parts[parts.length - 1];\n return { startLine: first.startLine, endLine: last.endLine, text: parts.map((p) => p.text).join('\\n'), final: parts.some((p) => p.final) };\n}\n\nconst NEWLINE_TOKENS = estimateTokens('\\n');\n// Built on first use and kept: each construction is ~3.5 ms, and only an oversize block is ever\n// split, so no command pays for a segmenter it never reaches.\nconst SEGMENTERS = new Map<string, Intl.Segmenter>();\n\nfunction segmentsOf(text: string, granularity: 'sentence' | 'word'): string[] {\n let segmenter = SEGMENTERS.get(granularity);\n if (!segmenter) {\n segmenter = new Intl.Segmenter(undefined, { granularity });\n SEGMENTERS.set(granularity, segmenter);\n }\n return Array.from(segmenter.segment(text), (s) => s.segment);\n}\n\n// Greedily packs segments (already contiguous, tiling the source text with no gaps) into groups\n// of at most `working` estimated tokens; a lone segment over `working` still stands alone.\nfunction pack(segments: string[], working: number): string[] {\n const groups: string[] = [];\n let current = '';\n let tokens = 0;\n for (const segment of segments) {\n const segmentTokens = estimateTokens(segment);\n if (current.length > 0 && tokens + segmentTokens > working) {\n groups.push(current);\n current = '';\n tokens = 0;\n }\n current += segment;\n tokens += segmentTokens;\n }\n if (current.length > 0) groups.push(current);\n return groups;\n}\n\n// Line-split alone can't shrink a lone dense line (the CJK case): falls back to sentence then\n// word boundaries (Intl.Segmenter, the same grapheme-safe engine as segment.ts), mode-agnostic on `text`.\nfunction splitLineText(text: string, working: number): string[] {\n const sentences = segmentsOf(text, 'sentence');\n const out: string[] = [];\n let current = '';\n let tokens = 0;\n const flush = () => {\n if (current.length > 0) {\n out.push(current);\n current = '';\n tokens = 0;\n }\n };\n for (const sentence of sentences) {\n const sentenceTokens = estimateTokens(sentence);\n if (sentenceTokens > working) {\n flush();\n out.push(...pack(segmentsOf(sentence, 'word'), working));\n continue;\n }\n if (current.length > 0 && tokens + sentenceTokens > working) flush();\n current += sentence;\n tokens += sentenceTokens;\n }\n flush();\n return out;\n}\n\nconst ATOMIC_TYPES: ReadonlySet<BlockType> = new Set(['code', 'table', 'list']);\n\n// Atomic (code/table/list) pieces are always a raw line slice: re-parsing a table's later pieces\n// without their header/delimiter rows would demote them to paragraph text.\nfunction piece(pieceLines: string[], startLine: number, endLine: number, blockType: BlockType, textMode: 'extracted' | 'raw'): Part {\n const text =\n ATOMIC_TYPES.has(blockType) || textMode === 'raw'\n ? pieceLines.join('\\n')\n : parse(pieceLines.join('\\n'))\n .map((b) => extractText(b))\n .join('\\n');\n return { startLine, endLine, text };\n}\n\n// A one-line piece over working can't shrink via another line-boundary pass (rule 5's gap), so it\n// splits at sentence/word boundaries instead; `final` stops group() re-deriving its text by extent (F5).\nfunction finalizePiece(pieceLines: string[], startLine: number, endLine: number, working: number, blockType: BlockType, textMode: 'extracted' | 'raw'): Part[] {\n const p = piece(pieceLines, startLine, endLine, blockType, textMode);\n if (pieceLines.length === 1 && estimateTokens(p.text) > working) {\n return splitLineText(p.text, working).map((text) => ({ startLine, endLine, text, final: true }));\n }\n return [p];\n}\n\n// A block over 2x working size splits at line boundaries into pieces each <= working size, never\n// mid-line. `seed`: pending tokens (e.g. a heading) the first piece must join, checked against the limit.\nfunction splitOversizeBlock(lines: string[], startLine: number, endLine: number, working: number, blockType: BlockType, textMode: 'extracted' | 'raw', seed = 0): Part[] {\n const pieces: Part[] = [];\n let pieceLines: string[] = [];\n let pieceStart = startLine;\n let tokens = seed;\n for (let line = startLine; line <= endLine; line++) {\n const lineText = lines[line - 1];\n const sep = pieceLines.length > 0 || tokens > 0 ? NEWLINE_TOKENS : 0;\n const lineTokens = estimateTokens(lineText);\n if (pieceLines.length > 0 && tokens + sep + lineTokens > working) {\n pieces.push(...finalizePiece(pieceLines, pieceStart, line - 1, working, blockType, textMode));\n pieceLines = [];\n tokens = 0;\n pieceStart = line;\n pieceLines.push(lineText);\n tokens += lineTokens;\n continue;\n }\n pieceLines.push(lineText);\n tokens += sep + lineTokens;\n }\n if (pieceLines.length > 0) pieces.push(...finalizePiece(pieceLines, pieceStart, endLine, working, blockType, textMode));\n return pieces;\n}\n\n// One heading scope's groups (D1): a heading opens the first group, and an oversize block\n// (rule 5, including an oversize heading) splits into pieces that each close their own group.\nfunction groupScope(scopeBlocks: Block[], lines: string[], resolved: ResolvedOptions): (Chunk & { final?: boolean })[] {\n const working = resolved.targetTokens;\n const trigger = working * OVERSIZE_TRIGGER_MULTIPLE;\n const finished: (Chunk & { final?: boolean })[] = [];\n let parts: Part[] = [];\n let paragraphCount = 0;\n let tokens = 0;\n\n function close(): void {\n const group = finalize(parts);\n if (group) finished.push(group);\n parts = [];\n paragraphCount = 0;\n tokens = 0;\n }\n\n // tokens tracks the active text mode's own estimate (a newline between parts costs\n // NEWLINE_TOKENS too), so packing decisions size the text the chunk will actually ship as.\n function addPart(text: string, sizeText: string, startLine: number, endLine: number): void {\n tokens += (parts.length > 0 ? NEWLINE_TOKENS : 0) + estimateTokens(sizeText);\n parts.push({ startLine, endLine, text });\n }\n\n for (const block of scopeBlocks) {\n const raw = lines.slice(block.startLine - 1, block.endLine).join('\\n');\n const blockTokens = estimateTokens(raw);\n\n if (blockTokens > trigger) {\n const seed = parts.length > 0 ? tokens : 0;\n for (const p of splitOversizeBlock(lines, block.startLine, block.endLine, working, block.type, resolved.text, seed)) {\n parts.push(p);\n close();\n }\n continue;\n }\n\n const extracted = extractText(block);\n const sizeText = resolved.text === 'raw' ? raw : extracted;\n\n if (block.type === 'heading') {\n addPart(extracted, sizeText, block.startLine, block.endLine);\n continue;\n }\n\n // The 2x-working invariant holds even under pgc's paper-faithful 2-paragraph pairing --\n // close first if the pair about to form would cross it.\n const pairOversize = parts.length > 0 && tokens + NEWLINE_TOKENS + blockTokens > trigger;\n if (pairOversize) close();\n\n addPart(extracted, sizeText, block.startLine, block.endLine);\n paragraphCount++;\n\n if (paragraphCount >= PGC_GROUP_SIZE) close();\n }\n close();\n\n return finished;\n}\n\n// Groups already-parsed blocks per opts (D1/D3), against the same body the blocks were parsed\n// from (line lookups for oversize splitting).\nexport function group(blocks: Block[], body: string, opts?: ChunkOptions): Chunk[] {\n const resolved = resolveOptions(opts);\n const lines = body.split('\\n');\n const chunks: (Chunk & { final?: boolean })[] = [];\n for (const scope of splitScopes(blocks)) chunks.push(...groupScope(scope, lines, resolved));\n // 'raw': the chunk's own source lines verbatim, replacing the flavor-resolved join above (D9).\n // A `final` chunk already carries its own slice's raw text; re-slicing by extent would return the whole shared line.\n const texted =\n resolved.text === 'raw'\n ? chunks.map((c) =>\n c.final\n ? c\n : {\n ...c,\n text: lines\n .slice(c.startLine - 1, c.endLine)\n .join('\\n')\n .trim(),\n }\n )\n : chunks;\n // A group can be all-blank (flavor-stripped to nothing, or a raw slice of pure syntax); it never produces a chunk.\n return texted.filter((c) => c.text.trim().length > 0).map((c) => ({ startLine: c.startLine, endLine: c.endLine, text: c.text }));\n}\n"],"names":["extractText","parse","DEFAULT_TARGET_TOKENS","estimateTokens","PGC_GROUP_SIZE","OVERSIZE_TRIGGER_MULTIPLE","resolveOptions","opts","targetTokens","text","splitScopes","blocks","scopes","current","block","type","length","push","finalize","parts","undefined","first","last","startLine","endLine","map","p","join","final","some","NEWLINE_TOKENS","SEGMENTERS","Map","segmentsOf","granularity","segmenter","get","Intl","Segmenter","set","Array","from","segment","s","pack","segments","working","groups","tokens","segmentTokens","splitLineText","sentences","out","flush","sentence","sentenceTokens","ATOMIC_TYPES","Set","piece","pieceLines","blockType","textMode","has","b","finalizePiece","splitOversizeBlock","lines","seed","pieces","pieceStart","line","lineText","sep","lineTokens","groupScope","scopeBlocks","resolved","trigger","finished","paragraphCount","close","group","addPart","sizeText","raw","slice","blockTokens","extracted","pairOversize","body","split","chunks","scope","texted","c","trim","filter"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/index.ts"],"sourcesContent":["import { group } from './group.ts';\nimport { parse } from './parse.ts';\nimport type { Block, Chunk, ChunkOptions } from './types.ts';\n\n// Groups blocks a caller already parsed (e.g. scan/index.ts, sharing one parse with the FTS\n// text path) against the same body they came from, per opts (D1/D3).\nexport function chunkFromBlocks(blocks: Block[], body: string, opts?: ChunkOptions): Chunk[] {\n return group(blocks, body, opts);\n}\n\n// Pure, deterministic function of file content; chunk semantics are version-stamped via\n// CHUNK_VERSION (./version.ts). Algorithm and evidence: BENCHMARKING.md, \"The chunking algorithm\".\nexport function chunk(body: string, opts?: ChunkOptions): Chunk[] {\n return chunkFromBlocks(parse(body), body, opts);\n}\n\nexport { extractText, extractTexts } from './extract.ts';\nexport { parse } from './parse.ts';\nexport { DEFAULT_TARGET_TOKENS, estimateTokens } from './tokens.ts';\nexport type { Block, BlockType, Chunk, ChunkOptions } from './types.ts';\nexport { CHUNK_VERSION } from './version.ts';\n"],"names":["group","parse","chunkFromBlocks","blocks","body","opts","chunk","extractText","extractTexts","DEFAULT_TARGET_TOKENS","estimateTokens","CHUNK_VERSION"],"mappings":"AAAA,SAASA,KAAK,QAAQ,aAAa;AACnC,SAASC,KAAK,QAAQ,aAAa;AAGnC,4FAA4F;AAC5F,qEAAqE;AACrE,OAAO,SAASC,gBAAgBC,MAAe,EAAEC,IAAY,EAAEC,IAAmB;IAChF,OAAOL,MAAMG,QAAQC,MAAMC;AAC7B;AAEA,wFAAwF;AACxF,mGAAmG;AACnG,OAAO,SAASC,MAAMF,IAAY,EAAEC,IAAmB;IACrD,OAAOH,gBAAgBD,MAAMG,OAAOA,MAAMC;AAC5C;AAEA,SAASE,WAAW,EAAEC,YAAY,QAAQ,eAAe;AACzD,SAASP,KAAK,QAAQ,aAAa;AACnC,SAASQ,qBAAqB,EAAEC,cAAc,QAAQ,cAAc;AAEpE,SAASC,aAAa,QAAQ,eAAe"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/chunk/index.ts"],"sourcesContent":["import { group } from './group.ts';\nimport { parse } from './parse.ts';\nimport type { Block, Chunk, ChunkOptions } from './types.ts';\n\n// Groups blocks a caller already parsed (e.g. scan/index.ts, sharing one parse with the FTS\n// text path) against the same body they came from, per opts (D1/D3).\nexport function chunkFromBlocks(blocks: Block[], body: string, opts?: ChunkOptions): Chunk[] {\n return group(blocks, body, opts);\n}\n\n// Pure, deterministic function of file content; chunk semantics are version-stamped via\n// CHUNK_VERSION (./version.ts). Algorithm and evidence: BENCHMARKING.md, \"The chunking algorithm\".\nexport function chunk(body: string, opts?: ChunkOptions): Chunk[] {\n return chunkFromBlocks(parse(body), body, opts);\n}\n\nexport { extractText, extractTexts } from './extract.ts';\nexport { parse } from './parse.ts';\nexport { DEFAULT_TARGET_TOKENS, estimateTokens } from './tokens.ts';\nexport type { Block, BlockType, Chunk, ChunkOptions } from './types.ts';\nexport { CHUNK_VERSION } from './version.ts';\n"],"names":["group","parse","chunkFromBlocks","blocks","body","opts","chunk","extractText","extractTexts","DEFAULT_TARGET_TOKENS","estimateTokens","CHUNK_VERSION"],"mappings":"AAAA,SAASA,KAAK,QAAQ,aAAa;AACnC,SAASC,KAAK,QAAQ,aAAa;AAGnC,4FAA4F;AAC5F,qEAAqE;AACrE,OAAO,SAASC,gBAAgBC,MAAe,EAAEC,IAAY,EAAEC,IAAmB;IAChF,OAAOL,MAAMG,QAAQC,MAAMC;AAC7B;AAEA,wFAAwF;AACxF,mGAAmG;AACnG,OAAO,SAASC,MAAMF,IAAY,EAAEC,IAAmB;IACrD,OAAOH,gBAAgBD,MAAMG,OAAOA,MAAMC;AAC5C;AAEA,SAASE,WAAW,EAAEC,YAAY,QAAQ,eAAe;AACzD,SAASP,KAAK,QAAQ,aAAa;AACnC,SAASQ,qBAAqB,EAAEC,cAAc,QAAQ,cAAc;AAEpE,SAASC,aAAa,QAAQ,eAAe"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/parse.ts"],"sourcesContent":["import type { Token } from 'markdown-it';\nimport { extractText } from './extract.ts';\nimport { parser } from './parser.ts';\nimport type { Block, BlockType } from './types.ts';\n\n// Opening token type to Block type. Everything else (rules, raw html, footnote definitions) is\n// 'other', as mdast's BLOCK_TYPES mapped no entry for those nodes.\nconst BLOCK_TYPES: Record<string, BlockType> = {\n heading_open: 'heading',\n paragraph_open: 'paragraph',\n fence: 'code',\n code_block: 'code',\n table_open: 'table',\n ordered_list_open: 'list',\n bullet_list_open: 'list',\n blockquote_open: 'blockquote',\n};\n\n// Top-level blocks of a markdown body, typed and line-extent bounded from markdown-it's own\n// token maps (never a regex guess). html and linkify on, with the footnote and task-list plugins.\nexport function parse(body: string): Block[] {\n const tokens = parser().parse(body, {});\n const lines = body.split('\\n');\n const blocks: Block[] = [];\n let i = 0;\n while (i < tokens.length) {\n const token = tokens[i];\n if (token.nesting === 0) {\n blocks.push(makeBlock(BLOCK_TYPES[token.type] ?? 'other', tokens, i, i + 1, lines));\n i += 1;\n } else if (token.nesting === 1) {\n let depth = 1;\n let j = i + 1;\n while (j < tokens.length && depth > 0) {\n depth += tokens[j].nesting === 1 ? 1 : tokens[j].nesting === -1 ? -1 : 0;\n j += 1;\n }\n blocks.push(makeBlock(BLOCK_TYPES[token.type] ?? 'other', tokens, i, j, lines));\n i = j;\n } else {\n // Defensive: the balanced scan above consumes every close belonging to an open.\n i += 1;\n }\n }\n return blocks;\n}\n\n// 1-based inclusive extent from the min/max of the tokens' maps (0-based half-open); a block\n// whose tokens carry no map (an empty footnote definition) falls back to line 1. Trailing\n// blank lines trim so a list's endLine lands where mdast's position ended it.\nfunction makeBlock(type: BlockType, tokens: Token[], i: number, j: number, lines: string[]): Block {\n let start = Infinity;\n let end = 0;\n for (let k = i; k < j; k++) {\n const map = tokens[k].map;\n if (map) {\n start = Math.min(start, map[0]);\n end = Math.max(end, map[1]);\n }\n }\n const startLine = Number.isFinite(start) ? start + 1 : 1;\n let endLine = end > start ? end : startLine;\n while (endLine > startLine && lines[endLine - 1].trim() === '') endLine--;\n const block: Block = { type, startLine, endLine, node: tokens.slice(i, j) };\n if (type === 'heading') {\n block.depth = Number(tokens[i].tag.slice(1));\n block.text = extractText(block);\n }\n return block;\n}\n"],"names":["extractText","parser","BLOCK_TYPES","heading_open","paragraph_open","fence","code_block","table_open","ordered_list_open","bullet_list_open","blockquote_open","parse","body","tokens","lines","split","blocks","i","length","token","nesting","push","makeBlock","type","depth","j","start","Infinity","end","k","map","Math","min","max","startLine","Number","isFinite","endLine","trim","block","node","slice","tag","text"],"mappings":"AACA,SAASA,WAAW,QAAQ,eAAe;AAC3C,SAASC,MAAM,QAAQ,cAAc;AAGrC,+FAA+F;AAC/F,mEAAmE;AACnE,MAAMC,cAAyC;IAC7CC,cAAc;IACdC,gBAAgB;IAChBC,OAAO;IACPC,YAAY;IACZC,YAAY;IACZC,mBAAmB;IACnBC,kBAAkB;IAClBC,iBAAiB;AACnB;AAEA,4FAA4F;AAC5F,kGAAkG;AAClG,OAAO,SAASC,MAAMC,IAAY;IAChC,MAAMC,SAASZ,SAASU,KAAK,CAACC,MAAM,CAAC;IACrC,MAAME,QAAQF,KAAKG,KAAK,CAAC;IACzB,MAAMC,SAAkB,EAAE;IAC1B,IAAIC,IAAI;IACR,MAAOA,IAAIJ,OAAOK,MAAM,CAAE;QACxB,MAAMC,QAAQN,MAAM,CAACI,EAAE;QACvB,IAAIE,MAAMC,OAAO,KAAK,GAAG;gBACDlB;YAAtBc,OAAOK,IAAI,CAACC,WAAUpB,0BAAAA,WAAW,CAACiB,MAAMI,IAAI,CAAC,cAAvBrB,qCAAAA,0BAA2B,SAASW,QAAQI,GAAGA,IAAI,GAAGH;YAC5EG,KAAK;QACP,OAAO,IAAIE,MAAMC,OAAO,KAAK,GAAG;gBAORlB;YANtB,IAAIsB,QAAQ;YACZ,IAAIC,IAAIR,IAAI;YACZ,MAAOQ,IAAIZ,OAAOK,MAAM,IAAIM,QAAQ,EAAG;gBACrCA,SAASX,MAAM,CAACY,EAAE,CAACL,OAAO,KAAK,IAAI,IAAIP,MAAM,CAACY,EAAE,CAACL,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI;gBACvEK,KAAK;YACP;YACAT,OAAOK,IAAI,CAACC,WAAUpB,2BAAAA,WAAW,CAACiB,MAAMI,IAAI,CAAC,cAAvBrB,sCAAAA,2BAA2B,SAASW,QAAQI,GAAGQ,GAAGX;YACxEG,IAAIQ;QACN,OAAO;YACL,gFAAgF;YAChFR,KAAK;QACP;IACF;IACA,OAAOD;AACT;AAEA,6FAA6F;AAC7F,0FAA0F;AAC1F,8EAA8E;AAC9E,SAASM,UAAUC,IAAe,EAAEV,MAAe,EAAEI,CAAS,EAAEQ,CAAS,EAAEX,KAAe;IACxF,IAAIY,QAAQC;IACZ,IAAIC,MAAM;IACV,IAAK,IAAIC,IAAIZ,GAAGY,IAAIJ,GAAGI,IAAK;QAC1B,MAAMC,MAAMjB,MAAM,CAACgB,EAAE,CAACC,GAAG;QACzB,IAAIA,KAAK;YACPJ,QAAQK,KAAKC,GAAG,CAACN,OAAOI,GAAG,CAAC,EAAE;YAC9BF,MAAMG,KAAKE,GAAG,CAACL,KAAKE,GAAG,CAAC,EAAE;QAC5B;IACF;IACA,MAAMI,YAAYC,OAAOC,QAAQ,CAACV,SAASA,QAAQ,IAAI;IACvD,IAAIW,UAAUT,MAAMF,QAAQE,MAAMM;IAClC,MAAOG,UAAUH,aAAapB,KAAK,CAACuB,UAAU,EAAE,CAACC,IAAI,OAAO,GAAID;IAChE,MAAME,QAAe;QAAEhB;QAAMW;QAAWG;QAASG,MAAM3B,OAAO4B,KAAK,CAACxB,GAAGQ;IAAG;IAC1E,IAAIF,SAAS,WAAW;QACtBgB,MAAMf,KAAK,GAAGW,OAAOtB,MAAM,CAACI,EAAE,CAACyB,GAAG,CAACD,KAAK,CAAC;QACzCF,MAAMI,IAAI,GAAG3C,YAAYuC;IAC3B;IACA,OAAOA;AACT"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/chunk/parse.ts"],"sourcesContent":["import type { Token } from 'markdown-it';\nimport { extractText } from './extract.ts';\nimport { parser } from './parser.ts';\nimport type { Block, BlockType } from './types.ts';\n\n// Opening token type to Block type. Everything else (rules, raw html, footnote definitions) is\n// 'other', as mdast's BLOCK_TYPES mapped no entry for those nodes.\nconst BLOCK_TYPES: Record<string, BlockType> = {\n heading_open: 'heading',\n paragraph_open: 'paragraph',\n fence: 'code',\n code_block: 'code',\n table_open: 'table',\n ordered_list_open: 'list',\n bullet_list_open: 'list',\n blockquote_open: 'blockquote',\n};\n\n// Top-level blocks of a markdown body, typed and line-extent bounded from markdown-it's own\n// token maps (never a regex guess). html and linkify on, with the footnote and task-list plugins.\nexport function parse(body: string): Block[] {\n const tokens = parser().parse(body, {});\n const lines = body.split('\\n');\n const blocks: Block[] = [];\n let i = 0;\n while (i < tokens.length) {\n const token = tokens[i];\n if (token.nesting === 0) {\n blocks.push(makeBlock(BLOCK_TYPES[token.type] ?? 'other', tokens, i, i + 1, lines));\n i += 1;\n } else if (token.nesting === 1) {\n let depth = 1;\n let j = i + 1;\n while (j < tokens.length && depth > 0) {\n depth += tokens[j].nesting === 1 ? 1 : tokens[j].nesting === -1 ? -1 : 0;\n j += 1;\n }\n blocks.push(makeBlock(BLOCK_TYPES[token.type] ?? 'other', tokens, i, j, lines));\n i = j;\n } else {\n // Defensive: the balanced scan above consumes every close belonging to an open.\n i += 1;\n }\n }\n return blocks;\n}\n\n// 1-based inclusive extent from the min/max of the tokens' maps (0-based half-open); a block\n// whose tokens carry no map (an empty footnote definition) falls back to line 1. Trailing\n// blank lines trim so a list's endLine lands where mdast's position ended it.\nfunction makeBlock(type: BlockType, tokens: Token[], i: number, j: number, lines: string[]): Block {\n let start = Infinity;\n let end = 0;\n for (let k = i; k < j; k++) {\n const map = tokens[k].map;\n if (map) {\n start = Math.min(start, map[0]);\n end = Math.max(end, map[1]);\n }\n }\n const startLine = Number.isFinite(start) ? start + 1 : 1;\n let endLine = end > start ? end : startLine;\n while (endLine > startLine && lines[endLine - 1].trim() === '') endLine--;\n const block: Block = { type, startLine, endLine, node: tokens.slice(i, j) };\n if (type === 'heading') {\n block.depth = Number(tokens[i].tag.slice(1));\n block.text = extractText(block);\n }\n return block;\n}\n"],"names":["extractText","parser","BLOCK_TYPES","heading_open","paragraph_open","fence","code_block","table_open","ordered_list_open","bullet_list_open","blockquote_open","parse","body","tokens","lines","split","blocks","i","length","token","nesting","push","makeBlock","type","depth","j","start","Infinity","end","k","map","Math","min","max","startLine","Number","isFinite","endLine","trim","block","node","slice","tag","text"],"mappings":"AACA,SAASA,WAAW,QAAQ,eAAe;AAC3C,SAASC,MAAM,QAAQ,cAAc;AAGrC,+FAA+F;AAC/F,mEAAmE;AACnE,MAAMC,cAAyC;IAC7CC,cAAc;IACdC,gBAAgB;IAChBC,OAAO;IACPC,YAAY;IACZC,YAAY;IACZC,mBAAmB;IACnBC,kBAAkB;IAClBC,iBAAiB;AACnB;AAEA,4FAA4F;AAC5F,kGAAkG;AAClG,OAAO,SAASC,MAAMC,IAAY;IAChC,MAAMC,SAASZ,SAASU,KAAK,CAACC,MAAM,CAAC;IACrC,MAAME,QAAQF,KAAKG,KAAK,CAAC;IACzB,MAAMC,SAAkB,EAAE;IAC1B,IAAIC,IAAI;IACR,MAAOA,IAAIJ,OAAOK,MAAM,CAAE;QACxB,MAAMC,QAAQN,MAAM,CAACI,EAAE;QACvB,IAAIE,MAAMC,OAAO,KAAK,GAAG;gBACDlB;YAAtBc,OAAOK,IAAI,CAACC,WAAUpB,0BAAAA,WAAW,CAACiB,MAAMI,IAAI,CAAC,cAAvBrB,qCAAAA,0BAA2B,SAASW,QAAQI,GAAGA,IAAI,GAAGH;YAC5EG,KAAK;QACP,OAAO,IAAIE,MAAMC,OAAO,KAAK,GAAG;gBAORlB;YANtB,IAAIsB,QAAQ;YACZ,IAAIC,IAAIR,IAAI;YACZ,MAAOQ,IAAIZ,OAAOK,MAAM,IAAIM,QAAQ,EAAG;gBACrCA,SAASX,MAAM,CAACY,EAAE,CAACL,OAAO,KAAK,IAAI,IAAIP,MAAM,CAACY,EAAE,CAACL,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI;gBACvEK,KAAK;YACP;YACAT,OAAOK,IAAI,CAACC,WAAUpB,2BAAAA,WAAW,CAACiB,MAAMI,IAAI,CAAC,cAAvBrB,sCAAAA,2BAA2B,SAASW,QAAQI,GAAGQ,GAAGX;YACxEG,IAAIQ;QACN,OAAO;YACL,gFAAgF;YAChFR,KAAK;QACP;IACF;IACA,OAAOD;AACT;AAEA,6FAA6F;AAC7F,0FAA0F;AAC1F,8EAA8E;AAC9E,SAASM,UAAUC,IAAe,EAAEV,MAAe,EAAEI,CAAS,EAAEQ,CAAS,EAAEX,KAAe;IACxF,IAAIY,QAAQC;IACZ,IAAIC,MAAM;IACV,IAAK,IAAIC,IAAIZ,GAAGY,IAAIJ,GAAGI,IAAK;QAC1B,MAAMC,MAAMjB,MAAM,CAACgB,EAAE,CAACC,GAAG;QACzB,IAAIA,KAAK;YACPJ,QAAQK,KAAKC,GAAG,CAACN,OAAOI,GAAG,CAAC,EAAE;YAC9BF,MAAMG,KAAKE,GAAG,CAACL,KAAKE,GAAG,CAAC,EAAE;QAC5B;IACF;IACA,MAAMI,YAAYC,OAAOC,QAAQ,CAACV,SAASA,QAAQ,IAAI;IACvD,IAAIW,UAAUT,MAAMF,QAAQE,MAAMM;IAClC,MAAOG,UAAUH,aAAapB,KAAK,CAACuB,UAAU,EAAE,CAACC,IAAI,OAAO,GAAID;IAChE,MAAME,QAAe;QAAEhB;QAAMW;QAAWG;QAASG,MAAM3B,OAAO4B,KAAK,CAACxB,GAAGQ;IAAG;IAC1E,IAAIF,SAAS,WAAW;QACtBgB,MAAMf,KAAK,GAAGW,OAAOtB,MAAM,CAACI,EAAE,CAACyB,GAAG,CAACD,KAAK,CAAC;QACzCF,MAAMI,IAAI,GAAG3C,YAAYuC;IAC3B;IACA,OAAOA;AACT"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/parser.ts"],"sourcesContent":["import Module from 'node:module';\nimport type { MarkdownIt } from 'markdown-it';\nimport type footnotePlugin from 'markdown-it-footnote';\nimport type taskListsPlugin from 'markdown-it-task-lists';\n\n// Tier-2, as embed/static.ts: the parser's packages cost ~19 ms to load and a warm tree never\n// parses, so every store-opening command paid for them until a file actually changed.\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\n\n// The CJS build resolves markdown-it's export= types, so the constructor is named locally.\ntype Ctor = new (options?: { html?: boolean; linkify?: boolean }) => MarkdownIt;\n\nlet cached: MarkdownIt | undefined;\n\n// The one shared parser: html and linkify on, fuzzy links, footnotes and task lists, with the\n// footnote rules disabled for GFM parity (definitions stay spans; ^[...] stays inert text).\nexport function parser(): MarkdownIt {\n if (cached) return cached;\n const Ctor = _require('markdown-it') as Ctor;\n const footnote = _require('markdown-it-footnote') as typeof footnotePlugin;\n const taskLists = _require('markdown-it-task-lists') as typeof taskListsPlugin;\n const md = new Ctor({ html: true, linkify: true }).use(footnote).use(taskLists);\n // Fuzzy linking is what links www. domains and emails (the scheme matcher does neither); its\n // bare-domain over-matching vs GFM is reined in at extraction, where the text is kept.\n md.linkify.set({ fuzzyLink: true });\n md.core.ruler.disable('footnote_tail');\n md.inline.ruler.disable('footnote_inline');\n cached = md;\n return cached;\n}\n"],"names":["Module","_require","require","createRequire","url","cached","parser","Ctor","footnote","taskLists","md","html","linkify","use","set","fuzzyLink","core","ruler","disable","inline"],"mappings":"AAAA,OAAOA,YAAY,cAAc;AAKjC,8FAA8F;AAC9F,sFAAsF;AACtF,MAAMC,WAAW,OAAOC,YAAY,cAAcF,OAAOG,aAAa,CAAC,YAAYC,GAAG,IAAIF;AAK1F,IAAIG;AAEJ,8FAA8F;AAC9F,4FAA4F;AAC5F,OAAO,SAASC;IACd,IAAID,QAAQ,OAAOA;IACnB,MAAME,OAAON,SAAS;IACtB,MAAMO,WAAWP,SAAS;IAC1B,MAAMQ,YAAYR,SAAS;IAC3B,MAAMS,KAAK,IAAIH,KAAK;QAAEI,MAAM;QAAMC,SAAS;IAAK,GAAGC,GAAG,CAACL,UAAUK,GAAG,CAACJ;IACrE,6FAA6F;IAC7F,uFAAuF;IACvFC,GAAGE,OAAO,CAACE,GAAG,CAAC;QAAEC,WAAW;IAAK;IACjCL,GAAGM,IAAI,CAACC,KAAK,CAACC,OAAO,CAAC;IACtBR,GAAGS,MAAM,CAACF,KAAK,CAACC,OAAO,CAAC;IACxBb,SAASK;IACT,OAAOL;AACT"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/chunk/parser.ts"],"sourcesContent":["import Module from 'node:module';\nimport type { MarkdownIt } from 'markdown-it';\nimport type footnotePlugin from 'markdown-it-footnote';\nimport type taskListsPlugin from 'markdown-it-task-lists';\n\n// Tier-2, as embed/static.ts: the parser's packages cost ~19 ms to load and a warm tree never\n// parses, so every store-opening command paid for them until a file actually changed.\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\n\n// The CJS build resolves markdown-it's export= types, so the constructor is named locally.\ntype Ctor = new (options?: { html?: boolean; linkify?: boolean }) => MarkdownIt;\n\nlet cached: MarkdownIt | undefined;\n\n// The one shared parser: html and linkify on, fuzzy links, footnotes and task lists, with the\n// footnote rules disabled for GFM parity (definitions stay spans; ^[...] stays inert text).\nexport function parser(): MarkdownIt {\n if (cached) return cached;\n const Ctor = _require('markdown-it') as Ctor;\n const footnote = _require('markdown-it-footnote') as typeof footnotePlugin;\n const taskLists = _require('markdown-it-task-lists') as typeof taskListsPlugin;\n const md = new Ctor({ html: true, linkify: true }).use(footnote).use(taskLists);\n // Fuzzy linking is what links www. domains and emails (the scheme matcher does neither); its\n // bare-domain over-matching vs GFM is reined in at extraction, where the text is kept.\n md.linkify.set({ fuzzyLink: true });\n md.core.ruler.disable('footnote_tail');\n md.inline.ruler.disable('footnote_inline');\n cached = md;\n return cached;\n}\n"],"names":["Module","_require","require","createRequire","url","cached","parser","Ctor","footnote","taskLists","md","html","linkify","use","set","fuzzyLink","core","ruler","disable","inline"],"mappings":"AAAA,OAAOA,YAAY,cAAc;AAKjC,8FAA8F;AAC9F,sFAAsF;AACtF,MAAMC,WAAW,OAAOC,YAAY,cAAcF,OAAOG,aAAa,CAAC,YAAYC,GAAG,IAAIF;AAK1F,IAAIG;AAEJ,8FAA8F;AAC9F,4FAA4F;AAC5F,OAAO,SAASC;IACd,IAAID,QAAQ,OAAOA;IACnB,MAAME,OAAON,SAAS;IACtB,MAAMO,WAAWP,SAAS;IAC1B,MAAMQ,YAAYR,SAAS;IAC3B,MAAMS,KAAK,IAAIH,KAAK;QAAEI,MAAM;QAAMC,SAAS;IAAK,GAAGC,GAAG,CAACL,UAAUK,GAAG,CAACJ;IACrE,6FAA6F;IAC7F,uFAAuF;IACvFC,GAAGE,OAAO,CAACE,GAAG,CAAC;QAAEC,WAAW;IAAK;IACjCL,GAAGM,IAAI,CAACC,KAAK,CAACC,OAAO,CAAC;IACtBR,GAAGS,MAAM,CAACF,KAAK,CAACC,OAAO,CAAC;IACxBb,SAASK;IACT,OAAOL;AACT"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/tokens.ts"],"sourcesContent":["import { UNSPACED_SCRIPTS } from '../text/segment.ts';\n\nexport const DEFAULT_TARGET_TOKENS = 500;\n\n// D5: segment.ts's unspaced-script set packs close to one token per character; Hangul is\n// spaced but still token-dense and sits in this set as a conservative bound (one Unicode set, one home).\nconst DENSE_SCRIPT = new RegExp(`[${UNSPACED_SCRIPTS}\\\\p{scx=Hangul}]`, 'u');\n\n// D5's size estimate: dense-script graphemes 1:1, everything else at 4 chars/token.\nexport function estimateTokens(text: string): number {\n let dense = 0;\n let other = 0;\n for (const ch of text) {\n if (DENSE_SCRIPT.test(ch)) dense++;\n else other++;\n }\n return dense + other / 4;\n}\n"],"names":["UNSPACED_SCRIPTS","DEFAULT_TARGET_TOKENS","DENSE_SCRIPT","RegExp","estimateTokens","text","dense","other","ch","test"],"mappings":"AAAA,SAASA,gBAAgB,QAAQ,qBAAqB;AAEtD,OAAO,MAAMC,wBAAwB,IAAI;AAEzC,yFAAyF;AACzF,yGAAyG;AACzG,MAAMC,eAAe,IAAIC,OAAO,CAAC,CAAC,EAAEH,iBAAiB,gBAAgB,CAAC,EAAE;AAExE,oFAAoF;AACpF,OAAO,SAASI,eAAeC,IAAY;IACzC,IAAIC,QAAQ;IACZ,IAAIC,QAAQ;IACZ,KAAK,MAAMC,MAAMH,KAAM;QACrB,IAAIH,aAAaO,IAAI,CAACD,KAAKF;aACtBC;IACP;IACA,OAAOD,QAAQC,QAAQ;AACzB"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/chunk/tokens.ts"],"sourcesContent":["import { UNSPACED_SCRIPTS } from '../text/segment.ts';\n\nexport const DEFAULT_TARGET_TOKENS = 500;\n\n// D5: segment.ts's unspaced-script set packs close to one token per character; Hangul is\n// spaced but still token-dense and sits in this set as a conservative bound (one Unicode set, one home).\nconst DENSE_SCRIPT = new RegExp(`[${UNSPACED_SCRIPTS}\\\\p{scx=Hangul}]`, 'u');\n\n// D5's size estimate: dense-script graphemes 1:1, everything else at 4 chars/token.\nexport function estimateTokens(text: string): number {\n let dense = 0;\n let other = 0;\n for (const ch of text) {\n if (DENSE_SCRIPT.test(ch)) dense++;\n else other++;\n }\n return dense + other / 4;\n}\n"],"names":["UNSPACED_SCRIPTS","DEFAULT_TARGET_TOKENS","DENSE_SCRIPT","RegExp","estimateTokens","text","dense","other","ch","test"],"mappings":"AAAA,SAASA,gBAAgB,QAAQ,qBAAqB;AAEtD,OAAO,MAAMC,wBAAwB,IAAI;AAEzC,yFAAyF;AACzF,yGAAyG;AACzG,MAAMC,eAAe,IAAIC,OAAO,CAAC,CAAC,EAAEH,iBAAiB,gBAAgB,CAAC,EAAE;AAExE,oFAAoF;AACpF,OAAO,SAASI,eAAeC,IAAY;IACzC,IAAIC,QAAQ;IACZ,IAAIC,QAAQ;IACZ,KAAK,MAAMC,MAAMH,KAAM;QACrB,IAAIH,aAAaO,IAAI,CAACD,KAAKF;aACtBC;IACP;IACA,OAAOD,QAAQC,QAAQ;AACzB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/types.ts"],"sourcesContent":["import type { Token } from 'markdown-it';\n\nexport type BlockType = 'heading' | 'paragraph' | 'code' | 'table' | 'list' | 'blockquote' | 'other';\n\n// One top-level markdown-it block plus its 1-indexed source line extent, heading depth/text if any.\n// `node` is the block's token slice, so extract.ts and group.ts (W2) read the same parse.\nexport interface Block {\n type: BlockType;\n startLine: number;\n endLine: number;\n depth?: number;\n text?: string;\n node: Token[];\n}\n\nexport interface ChunkOptions {\n // D3/W3b: the pgc pairing cap and the sole owner lever (embed.chunkTokens); default 500.\n targetTokens?: number;\n // D9: 'raw' (source lines verbatim) is the shipped default; 'extracted' (flavor-resolved)\n // stays available for a future measured revisit, not currently shipped.\n text?: 'extracted' | 'raw';\n}\n\n// One grouped, extracted unit: 1-indexed line extent over the body, flavor-resolved text.\nexport interface Chunk {\n startLine: number;\n endLine: number;\n text: string;\n}\n"],"names":[],"mappings":"AAuBA,0FAA0F;AAC1F,WAIC"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/chunk/types.ts"],"sourcesContent":["import type { Token } from 'markdown-it';\n\nexport type BlockType = 'heading' | 'paragraph' | 'code' | 'table' | 'list' | 'blockquote' | 'other';\n\n// One top-level markdown-it block plus its 1-indexed source line extent, heading depth/text if any.\n// `node` is the block's token slice, so extract.ts and group.ts (W2) read the same parse.\nexport interface Block {\n type: BlockType;\n startLine: number;\n endLine: number;\n depth?: number;\n text?: string;\n node: Token[];\n}\n\nexport interface ChunkOptions {\n // D3/W3b: the pgc pairing cap and the sole owner lever (embed.chunkTokens); default 500.\n targetTokens?: number;\n // D9: 'raw' (source lines verbatim) is the shipped default; 'extracted' (flavor-resolved)\n // stays available for a future measured revisit, not currently shipped.\n text?: 'extracted' | 'raw';\n}\n\n// One grouped, extracted unit: 1-indexed line extent over the body, flavor-resolved text.\nexport interface Chunk {\n startLine: number;\n endLine: number;\n text: string;\n}\n"],"names":[],"mappings":"AAuBA,0FAA0F;AAC1F,WAIC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/version.ts"],"sourcesContent":["// D8: bump whenever chunk semantics change (grouping, sizing, splitting); the digest in\n// test/unit/chunk/version.test.ts tracks EXTRACTION changes only, so the two move independently.\nexport const CHUNK_VERSION = 'chunk:v6';\n"],"names":["CHUNK_VERSION"],"mappings":"AAAA,wFAAwF;AACxF,iGAAiG;AACjG,OAAO,MAAMA,gBAAgB,WAAW"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/chunk/version.ts"],"sourcesContent":["// D8: bump whenever chunk semantics change (grouping, sizing, splitting); the digest in\n// test/unit/chunk/version.test.ts tracks EXTRACTION changes only, so the two move independently.\nexport const CHUNK_VERSION = 'chunk:v6';\n"],"names":["CHUNK_VERSION"],"mappings":"AAAA,wFAAwF;AACxF,iGAAiG;AACjG,OAAO,MAAMA,gBAAgB,WAAW"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/build.ts"],"sourcesContent":["import { buildIndex } from '../store/index.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst build: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.build}`, { force: { type: 'boolean', default: false }, ...CONFIG });\n const result = await buildIndex(ctx.resolveConfig(values.config as string | undefined), { force: values.force === true });\n printWarnings(result.warnings);\n console.log(`${ctx.name} build: ${result.parsed} file(s) parsed; index ready at ${result.dbPath}`);\n};\n\nexport default build;\n"],"names":["buildIndex","USAGE","CONFIG","parse","printWarnings","build","ctx","values","argv","name","force","type","default","result","resolveConfig","config","warnings","console","log","parsed","dbPath"],"mappings":"AAAA,SAASA,UAAU,QAAQ,oBAAoB;AAC/C,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,MAAMW,SAAS,MAAMb,WAAWM,IAAIQ,aAAa,CAACP,OAAOQ,MAAM,GAAyB;QAAEL,OAAOH,OAAOG,KAAK,KAAK;IAAK;IACvHN,cAAcS,OAAOG,QAAQ;IAC7BC,QAAQC,GAAG,CAAC,GAAGZ,IAAIG,IAAI,CAAC,QAAQ,EAAEI,OAAOM,MAAM,CAAC,gCAAgC,EAAEN,OAAOO,MAAM,EAAE;AACnG;AAEA,eAAef,MAAM"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/cli/build.ts"],"sourcesContent":["import { buildIndex } from '../store/index.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst build: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.build}`, { force: { type: 'boolean', default: false }, ...CONFIG });\n const result = await buildIndex(ctx.resolveConfig(values.config as string | undefined), { force: values.force === true });\n printWarnings(result.warnings);\n console.log(`${ctx.name} build: ${result.parsed} file(s) parsed; index ready at ${result.dbPath}`);\n};\n\nexport default build;\n"],"names":["buildIndex","USAGE","CONFIG","parse","printWarnings","build","ctx","values","argv","name","force","type","default","result","resolveConfig","config","warnings","console","log","parsed","dbPath"],"mappings":"AAAA,SAASA,UAAU,QAAQ,oBAAoB;AAC/C,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,MAAMW,SAAS,MAAMb,WAAWM,IAAIQ,aAAa,CAACP,OAAOQ,MAAM,GAAyB;QAAEL,OAAOH,OAAOG,KAAK,KAAK;IAAK;IACvHN,cAAcS,OAAOG,QAAQ;IAC7BC,QAAQC,GAAG,CAAC,GAAGZ,IAAIG,IAAI,CAAC,QAAQ,EAAEI,OAAOM,MAAM,CAAC,gCAAgC,EAAEN,OAAOO,MAAM,EAAE;AACnG;AAEA,eAAef,MAAM"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/download.ts"],"sourcesContent":["import { basename } from 'node:path';\nimport { embedConfig } from '../config/index.ts';\nimport { downloadModel, isDownloadable, modelDir, modelPresent } from '../embed/store.ts';\nimport { SenseError } from '../errors.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, parse } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// A prefetch over the store's own fetch path: a search would fetch the same weights\n// lazily, so this only moves the wait earlier. Idempotent; asks nothing, so CI can run it unattended.\nconst download: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.download}`, { ...CONFIG });\n const cfg = ctx.resolveConfig(values.config as string | undefined);\n const e = embedConfig(cfg);\n if (!e) throw new SenseError('EMBED_DISABLED', 'no preset asks for vectors, so there is no model to download');\n\n if (e.provider !== 'static') {\n console.log(`embed provider is \"${e.provider}\" (${e.url}), so there is nothing to download; ${ctx.name} search reaches it over the network`);\n return;\n }\n if (modelPresent(cfg)) {\n const at = isDownloadable(e.model) ? `@${basename(modelDir(e.model))} ` : ' ';\n console.log(`${e.model}${at}is already available in ${modelDir(e.model)}`);\n return;\n }\n const dir = await downloadModel(e.model, (file, into) => console.error(`fetching ${e.model}/${file} into ${into}`));\n console.log(`downloaded ${e.model}@${basename(dir)} into ${dir}`);\n};\nexport default download;\n"],"names":["basename","embedConfig","downloadModel","isDownloadable","modelDir","modelPresent","SenseError","USAGE","CONFIG","parse","download","ctx","values","argv","name","cfg","resolveConfig","config","e","provider","console","log","url","at","model","dir","file","into","error"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,YAAY;AACrC,SAASC,WAAW,QAAQ,qBAAqB;AACjD,SAASC,aAAa,EAAEC,cAAc,EAAEC,QAAQ,EAAEC,YAAY,QAAQ,oBAAoB;AAC1F,SAASC,UAAU,QAAQ,eAAe;AAC1C,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,KAAK,QAAQ,cAAc;AAG5C,oFAAoF;AACpF,sGAAsG;AACtG,MAAMC,WAAoB,OAAOC;IAC/B,MAAM,EAAEC,MAAM,EAAE,GAAGH,MAAME,IAAIE,IAAI,EAAE,CAAC,OAAO,EAAEF,IAAIG,IAAI,CAAC,CAAC,EAAEP,MAAMG,QAAQ,EAAE,EAAE;QAAE,GAAGF,MAAM;IAAC;IACvF,MAAMO,MAAMJ,IAAIK,aAAa,CAACJ,OAAOK,MAAM;IAC3C,MAAMC,IAAIjB,YAAYc;IACtB,IAAI,CAACG,GAAG,MAAM,IAAIZ,WAAW,kBAAkB;IAE/C,IAAIY,EAAEC,QAAQ,KAAK,UAAU;QAC3BC,QAAQC,GAAG,CAAC,CAAC,mBAAmB,EAAEH,EAAEC,QAAQ,CAAC,GAAG,EAAED,EAAEI,GAAG,CAAC,oCAAoC,EAAEX,IAAIG,IAAI,CAAC,mCAAmC,CAAC;QAC3I;IACF;IACA,IAAIT,aAAaU,MAAM;QACrB,MAAMQ,KAAKpB,eAAee,EAAEM,KAAK,IAAI,CAAC,CAAC,EAAExB,SAASI,SAASc,EAAEM,KAAK,GAAG,CAAC,CAAC,GAAG;QAC1EJ,QAAQC,GAAG,CAAC,GAAGH,EAAEM,KAAK,GAAGD,GAAG,wBAAwB,EAAEnB,SAASc,EAAEM,KAAK,GAAG;QACzE;IACF;IACA,MAAMC,MAAM,MAAMvB,cAAcgB,EAAEM,KAAK,EAAE,CAACE,MAAMC,OAASP,QAAQQ,KAAK,CAAC,CAAC,SAAS,EAAEV,EAAEM,KAAK,CAAC,CAAC,EAAEE,KAAK,MAAM,EAAEC,MAAM;IACjHP,QAAQC,GAAG,CAAC,CAAC,WAAW,EAAEH,EAAEM,KAAK,CAAC,CAAC,EAAExB,SAASyB,KAAK,MAAM,EAAEA,KAAK;AAClE;AACA,eAAef,SAAS"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/cli/download.ts"],"sourcesContent":["import { basename } from 'node:path';\nimport { embedConfig } from '../config/index.ts';\nimport { downloadModel, isDownloadable, modelDir, modelPresent } from '../embed/store.ts';\nimport { SenseError } from '../errors.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, parse } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// A prefetch over the store's own fetch path: a search would fetch the same weights\n// lazily, so this only moves the wait earlier. Idempotent; asks nothing, so CI can run it unattended.\nconst download: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.download}`, { ...CONFIG });\n const cfg = ctx.resolveConfig(values.config as string | undefined);\n const e = embedConfig(cfg);\n if (!e) throw new SenseError('EMBED_DISABLED', 'no preset asks for vectors, so there is no model to download');\n\n if (e.provider !== 'static') {\n console.log(`embed provider is \"${e.provider}\" (${e.url}), so there is nothing to download; ${ctx.name} search reaches it over the network`);\n return;\n }\n if (modelPresent(cfg)) {\n const at = isDownloadable(e.model) ? `@${basename(modelDir(e.model))} ` : ' ';\n console.log(`${e.model}${at}is already available in ${modelDir(e.model)}`);\n return;\n }\n const dir = await downloadModel(e.model, (file, into) => console.error(`fetching ${e.model}/${file} into ${into}`));\n console.log(`downloaded ${e.model}@${basename(dir)} into ${dir}`);\n};\nexport default download;\n"],"names":["basename","embedConfig","downloadModel","isDownloadable","modelDir","modelPresent","SenseError","USAGE","CONFIG","parse","download","ctx","values","argv","name","cfg","resolveConfig","config","e","provider","console","log","url","at","model","dir","file","into","error"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,YAAY;AACrC,SAASC,WAAW,QAAQ,qBAAqB;AACjD,SAASC,aAAa,EAAEC,cAAc,EAAEC,QAAQ,EAAEC,YAAY,QAAQ,oBAAoB;AAC1F,SAASC,UAAU,QAAQ,eAAe;AAC1C,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,KAAK,QAAQ,cAAc;AAG5C,oFAAoF;AACpF,sGAAsG;AACtG,MAAMC,WAAoB,OAAOC;IAC/B,MAAM,EAAEC,MAAM,EAAE,GAAGH,MAAME,IAAIE,IAAI,EAAE,CAAC,OAAO,EAAEF,IAAIG,IAAI,CAAC,CAAC,EAAEP,MAAMG,QAAQ,EAAE,EAAE;QAAE,GAAGF,MAAM;IAAC;IACvF,MAAMO,MAAMJ,IAAIK,aAAa,CAACJ,OAAOK,MAAM;IAC3C,MAAMC,IAAIjB,YAAYc;IACtB,IAAI,CAACG,GAAG,MAAM,IAAIZ,WAAW,kBAAkB;IAE/C,IAAIY,EAAEC,QAAQ,KAAK,UAAU;QAC3BC,QAAQC,GAAG,CAAC,CAAC,mBAAmB,EAAEH,EAAEC,QAAQ,CAAC,GAAG,EAAED,EAAEI,GAAG,CAAC,oCAAoC,EAAEX,IAAIG,IAAI,CAAC,mCAAmC,CAAC;QAC3I;IACF;IACA,IAAIT,aAAaU,MAAM;QACrB,MAAMQ,KAAKpB,eAAee,EAAEM,KAAK,IAAI,CAAC,CAAC,EAAExB,SAASI,SAASc,EAAEM,KAAK,GAAG,CAAC,CAAC,GAAG;QAC1EJ,QAAQC,GAAG,CAAC,GAAGH,EAAEM,KAAK,GAAGD,GAAG,wBAAwB,EAAEnB,SAASc,EAAEM,KAAK,GAAG;QACzE;IACF;IACA,MAAMC,MAAM,MAAMvB,cAAcgB,EAAEM,KAAK,EAAE,CAACE,MAAMC,OAASP,QAAQQ,KAAK,CAAC,CAAC,SAAS,EAAEV,EAAEM,KAAK,CAAC,CAAC,EAAEE,KAAK,MAAM,EAAEC,MAAM;IACjHP,QAAQC,GAAG,CAAC,CAAC,WAAW,EAAEH,EAAEM,KAAK,CAAC,CAAC,EAAExB,SAASyB,KAAK,MAAM,EAAEA,KAAK;AAClE;AACA,eAAef,SAAS"}
@@ -6,9 +6,9 @@ export declare const USAGE: {
6
6
  readonly status: "status [--format table|json] [--config path]";
7
7
  readonly download: "download [--config path]";
8
8
  readonly sql: "sql \"<statement>\" [params...] [--preset name] [--no-build] [--format table|json|csv] [--config path]";
9
- readonly search: "search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--no-build] [--format table|json|csv] [--config path]";
9
+ readonly search: "search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--explain] [--no-build] [--format table|json|csv] [--config path]";
10
10
  readonly map: "map [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]";
11
- readonly peek: "peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]";
11
+ readonly peek: "peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--section-count-limit n] [--link-count-limit n] [--no-build] [--format table|json] [--config path]";
12
12
  readonly path: "path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--no-build] [--format table|json] [--config path]";
13
13
  readonly related: "related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--no-build] [--format table|json|csv] [--config path]";
14
14
  };
@@ -7,9 +7,9 @@ export const USAGE = {
7
7
  status: 'status [--format table|json] [--config path]',
8
8
  download: 'download [--config path]',
9
9
  sql: 'sql "<statement>" [params...] [--preset name] [--no-build] [--format table|json|csv] [--config path]',
10
- search: 'search "<terms>" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--no-build] [--format table|json|csv] [--config path]',
10
+ search: 'search "<terms>" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--explain] [--no-build] [--format table|json|csv] [--config path]',
11
11
  map: 'map [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--no-build] [--format table|json] [--config path]',
12
- peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--no-build] [--format table|json] [--config path]',
12
+ peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--section-count-limit n] [--link-count-limit n] [--no-build] [--format table|json] [--config path]',
13
13
  path: 'path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--max-depth n] [--no-build] [--format table|json] [--config path]',
14
14
  related: 'related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--k n] [--no-build] [--format table|json|csv] [--config path]'
15
15
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/index.ts"],"sourcesContent":["import type { Command } from './types.ts';\n\n// Each command's usage line, minus the leading \"usage: <name> \": shared by cli.ts's\n// usage() and the command's own parse() error/--help output so there is one copy, not two.\nexport const USAGE = {\n init: 'init [--model id-or-path] [--provider static|openai|cohere] [--url url]',\n build: 'build [--force] [--config path]',\n watch: 'watch [--force] [--config path]',\n status: 'status [--format table|json] [--config path]',\n download: 'download [--config path]',\n sql: 'sql \"<statement>\" [params...] [--preset name] [--no-build] [--format table|json|csv] [--config path]',\n search: 'search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--no-build] [--format table|json|csv] [--config path]',\n map: 'map [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]',\n peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]',\n path: 'path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--no-build] [--format table|json] [--config path]',\n related: 'related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--no-build] [--format table|json|csv] [--config path]',\n} as const;\n\n// Lazy registry: a command's imports load only when it runs, so a heavy dependency in one\n// command never taxes the others (or --version/--help). These names are reserved from saved queries.\nexport const COMMANDS: Record<string, () => Promise<{ default: Command }>> = {\n init: () => import('./init.ts'),\n build: () => import('./build.ts'),\n watch: () => import('./watch.ts'),\n status: () => import('./status.ts'),\n download: () => import('./download.ts'),\n sql: () => import('./sql.ts'),\n search: () => import('./search.ts'),\n map: () => import('./map.ts'),\n peek: () => import('./peek.ts'),\n path: () => import('./path.ts'),\n related: () => import('./related.ts'),\n};\n\nexport type { Command, Ctx } from './types.ts';\n"],"names":["USAGE","init","build","watch","status","download","sql","search","map","peek","path","related","COMMANDS"],"mappings":"AAEA,oFAAoF;AACpF,2FAA2F;AAC3F,OAAO,MAAMA,QAAQ;IACnBC,MAAM;IACNC,OAAO;IACPC,OAAO;IACPC,QAAQ;IACRC,UAAU;IACVC,KAAK;IACLC,QAAQ;IACRC,KAAK;IACLC,MAAM;IACNC,MAAM;IACNC,SAAS;AACX,EAAW;AAEX,0FAA0F;AAC1F,qGAAqG;AACrG,OAAO,MAAMC,WAAgE;IAC3EX,MAAM,IAAM,MAAM,CAAC;IACnBC,OAAO,IAAM,MAAM,CAAC;IACpBC,OAAO,IAAM,MAAM,CAAC;IACpBC,QAAQ,IAAM,MAAM,CAAC;IACrBC,UAAU,IAAM,MAAM,CAAC;IACvBC,KAAK,IAAM,MAAM,CAAC;IAClBC,QAAQ,IAAM,MAAM,CAAC;IACrBC,KAAK,IAAM,MAAM,CAAC;IAClBC,MAAM,IAAM,MAAM,CAAC;IACnBC,MAAM,IAAM,MAAM,CAAC;IACnBC,SAAS,IAAM,MAAM,CAAC;AACxB,EAAE"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/cli/index.ts"],"sourcesContent":["import type { Command } from './types.ts';\n\n// Each command's usage line, minus the leading \"usage: <name> \": shared by cli.ts's\n// usage() and the command's own parse() error/--help output so there is one copy, not two.\nexport const USAGE = {\n init: 'init [--model id-or-path] [--provider static|openai|cohere] [--url url]',\n build: 'build [--force] [--config path]',\n watch: 'watch [--force] [--config path]',\n status: 'status [--format table|json] [--config path]',\n download: 'download [--config path]',\n sql: 'sql \"<statement>\" [params...] [--preset name] [--no-build] [--format table|json|csv] [--config path]',\n search: 'search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--explain] [--no-build] [--format table|json|csv] [--config path]',\n map: 'map [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]',\n peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--section-count-limit n] [--link-count-limit n] [--no-build] [--format table|json] [--config path]',\n path: 'path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--no-build] [--format table|json] [--config path]',\n related: 'related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--no-build] [--format table|json|csv] [--config path]',\n} as const;\n\n// Lazy registry: a command's imports load only when it runs, so a heavy dependency in one\n// command never taxes the others (or --version/--help). These names are reserved from saved queries.\nexport const COMMANDS: Record<string, () => Promise<{ default: Command }>> = {\n init: () => import('./init.ts'),\n build: () => import('./build.ts'),\n watch: () => import('./watch.ts'),\n status: () => import('./status.ts'),\n download: () => import('./download.ts'),\n sql: () => import('./sql.ts'),\n search: () => import('./search.ts'),\n map: () => import('./map.ts'),\n peek: () => import('./peek.ts'),\n path: () => import('./path.ts'),\n related: () => import('./related.ts'),\n};\n\nexport type { Command, Ctx } from './types.ts';\n"],"names":["USAGE","init","build","watch","status","download","sql","search","map","peek","path","related","COMMANDS"],"mappings":"AAEA,oFAAoF;AACpF,2FAA2F;AAC3F,OAAO,MAAMA,QAAQ;IACnBC,MAAM;IACNC,OAAO;IACPC,OAAO;IACPC,QAAQ;IACRC,UAAU;IACVC,KAAK;IACLC,QAAQ;IACRC,KAAK;IACLC,MAAM;IACNC,MAAM;IACNC,SAAS;AACX,EAAW;AAEX,0FAA0F;AAC1F,qGAAqG;AACrG,OAAO,MAAMC,WAAgE;IAC3EX,MAAM,IAAM,MAAM,CAAC;IACnBC,OAAO,IAAM,MAAM,CAAC;IACpBC,OAAO,IAAM,MAAM,CAAC;IACpBC,QAAQ,IAAM,MAAM,CAAC;IACrBC,UAAU,IAAM,MAAM,CAAC;IACvBC,KAAK,IAAM,MAAM,CAAC;IAClBC,QAAQ,IAAM,MAAM,CAAC;IACrBC,KAAK,IAAM,MAAM,CAAC;IAClBC,MAAM,IAAM,MAAM,CAAC;IACnBC,MAAM,IAAM,MAAM,CAAC;IACnBC,SAAS,IAAM,MAAM,CAAC;AACxB,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/init.ts"],"sourcesContent":["import { DEFAULT_EMBED_MODEL, initConfig } from '../config/index.ts';\nimport { USAGE } from './index.ts';\nimport { parse } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst init: Command = (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.init}`, {\n model: { type: 'string' },\n provider: { type: 'string' },\n url: { type: 'string' },\n });\n const modelFlag = values.model as string | undefined;\n const providerFlag = values.provider as string | undefined;\n const model = modelFlag ?? DEFAULT_EMBED_MODEL;\n const provider = providerFlag ?? 'static';\n const url = values.url as string | undefined;\n // An invalid --provider throws here (validateConfig's own shape error), before anything is\n // written -- one validator, not a second copy of its rules.\n const configPath = initConfig(process.cwd(), { model: modelFlag, provider: providerFlag, url });\n console.log(`created ${configPath}`);\n console.log(`query away: ${ctx.name} sql \"SELECT path FROM frontmatter LIMIT 10\"`);\n // Naming a model is consent to fetch it, so writing one into the config says so loudly,\n // with the download consequence and the prefetch command, right where it was just written.\n if (provider === 'static') {\n console.log(`embed model: ${model} (static); ${ctx.name} build, watch, or a vector search downloads it when needed -- ${ctx.name} download fetches it now instead`);\n } else {\n console.log(`embed model: ${model} (${provider}${url ? ` at ${url}` : ''}); build, watch, and vector queries use the network, nothing to download`);\n }\n console.log('a non-English tree should pick a model for its languages: see the sense-setup skill or INTEGRATIONS.md');\n // The decisions a new tree faces -- features, frontmatter conventions, note size -- are not\n // in this output; name both places that hold them, since an agent may have neither.\n console.log('features and tree design: the sense-setup skill, or schema.json');\n};\nexport default init;\n"],"names":["DEFAULT_EMBED_MODEL","initConfig","USAGE","parse","init","ctx","values","argv","name","model","type","provider","url","modelFlag","providerFlag","configPath","process","cwd","console","log"],"mappings":"AAAA,SAASA,mBAAmB,EAAEC,UAAU,QAAQ,qBAAqB;AACrE,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,KAAK,QAAQ,cAAc;AAGpC,MAAMC,OAAgB,CAACC;IACrB,MAAM,EAAEC,MAAM,EAAE,GAAGH,MAAME,IAAIE,IAAI,EAAE,CAAC,OAAO,EAAEF,IAAIG,IAAI,CAAC,CAAC,EAAEN,MAAME,IAAI,EAAE,EAAE;QACrEK,OAAO;YAAEC,MAAM;QAAS;QACxBC,UAAU;YAAED,MAAM;QAAS;QAC3BE,KAAK;YAAEF,MAAM;QAAS;IACxB;IACA,MAAMG,YAAYP,OAAOG,KAAK;IAC9B,MAAMK,eAAeR,OAAOK,QAAQ;IACpC,MAAMF,QAAQI,sBAAAA,uBAAAA,YAAab;IAC3B,MAAMW,WAAWG,yBAAAA,0BAAAA,eAAgB;IACjC,MAAMF,MAAMN,OAAOM,GAAG;IACtB,2FAA2F;IAC3F,4DAA4D;IAC5D,MAAMG,aAAad,WAAWe,QAAQC,GAAG,IAAI;QAAER,OAAOI;QAAWF,UAAUG;QAAcF;IAAI;IAC7FM,QAAQC,GAAG,CAAC,CAAC,QAAQ,EAAEJ,YAAY;IACnCG,QAAQC,GAAG,CAAC,CAAC,YAAY,EAAEd,IAAIG,IAAI,CAAC,4CAA4C,CAAC;IACjF,wFAAwF;IACxF,2FAA2F;IAC3F,IAAIG,aAAa,UAAU;QACzBO,QAAQC,GAAG,CAAC,CAAC,aAAa,EAAEV,MAAM,WAAW,EAAEJ,IAAIG,IAAI,CAAC,8DAA8D,EAAEH,IAAIG,IAAI,CAAC,gCAAgC,CAAC;IACpK,OAAO;QACLU,QAAQC,GAAG,CAAC,CAAC,aAAa,EAAEV,MAAM,EAAE,EAAEE,WAAWC,MAAM,CAAC,IAAI,EAAEA,KAAK,GAAG,GAAG,wEAAwE,CAAC;IACpJ;IACAM,QAAQC,GAAG,CAAC;IACZ,4FAA4F;IAC5F,oFAAoF;IACpFD,QAAQC,GAAG,CAAC;AACd;AACA,eAAef,KAAK"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/cli/init.ts"],"sourcesContent":["import { DEFAULT_EMBED_MODEL, initConfig } from '../config/index.ts';\nimport { USAGE } from './index.ts';\nimport { parse } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst init: Command = (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.init}`, {\n model: { type: 'string' },\n provider: { type: 'string' },\n url: { type: 'string' },\n });\n const modelFlag = values.model as string | undefined;\n const providerFlag = values.provider as string | undefined;\n const model = modelFlag ?? DEFAULT_EMBED_MODEL;\n const provider = providerFlag ?? 'static';\n const url = values.url as string | undefined;\n // An invalid --provider throws here (validateConfig's own shape error), before anything is\n // written -- one validator, not a second copy of its rules.\n const configPath = initConfig(process.cwd(), { model: modelFlag, provider: providerFlag, url });\n console.log(`created ${configPath}`);\n console.log(`query away: ${ctx.name} sql \"SELECT path FROM frontmatter LIMIT 10\"`);\n // Naming a model is consent to fetch it, so writing one into the config says so loudly,\n // with the download consequence and the prefetch command, right where it was just written.\n if (provider === 'static') {\n console.log(`embed model: ${model} (static); ${ctx.name} build, watch, or a vector search downloads it when needed -- ${ctx.name} download fetches it now instead`);\n } else {\n console.log(`embed model: ${model} (${provider}${url ? ` at ${url}` : ''}); build, watch, and vector queries use the network, nothing to download`);\n }\n console.log('a non-English tree should pick a model for its languages: see the sense-setup skill or INTEGRATIONS.md');\n // The decisions a new tree faces -- features, frontmatter conventions, note size -- are not\n // in this output; name both places that hold them, since an agent may have neither.\n console.log('features and tree design: the sense-setup skill, or schema.json');\n};\nexport default init;\n"],"names":["DEFAULT_EMBED_MODEL","initConfig","USAGE","parse","init","ctx","values","argv","name","model","type","provider","url","modelFlag","providerFlag","configPath","process","cwd","console","log"],"mappings":"AAAA,SAASA,mBAAmB,EAAEC,UAAU,QAAQ,qBAAqB;AACrE,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,KAAK,QAAQ,cAAc;AAGpC,MAAMC,OAAgB,CAACC;IACrB,MAAM,EAAEC,MAAM,EAAE,GAAGH,MAAME,IAAIE,IAAI,EAAE,CAAC,OAAO,EAAEF,IAAIG,IAAI,CAAC,CAAC,EAAEN,MAAME,IAAI,EAAE,EAAE;QACrEK,OAAO;YAAEC,MAAM;QAAS;QACxBC,UAAU;YAAED,MAAM;QAAS;QAC3BE,KAAK;YAAEF,MAAM;QAAS;IACxB;IACA,MAAMG,YAAYP,OAAOG,KAAK;IAC9B,MAAMK,eAAeR,OAAOK,QAAQ;IACpC,MAAMF,QAAQI,sBAAAA,uBAAAA,YAAab;IAC3B,MAAMW,WAAWG,yBAAAA,0BAAAA,eAAgB;IACjC,MAAMF,MAAMN,OAAOM,GAAG;IACtB,2FAA2F;IAC3F,4DAA4D;IAC5D,MAAMG,aAAad,WAAWe,QAAQC,GAAG,IAAI;QAAER,OAAOI;QAAWF,UAAUG;QAAcF;IAAI;IAC7FM,QAAQC,GAAG,CAAC,CAAC,QAAQ,EAAEJ,YAAY;IACnCG,QAAQC,GAAG,CAAC,CAAC,YAAY,EAAEd,IAAIG,IAAI,CAAC,4CAA4C,CAAC;IACjF,wFAAwF;IACxF,2FAA2F;IAC3F,IAAIG,aAAa,UAAU;QACzBO,QAAQC,GAAG,CAAC,CAAC,aAAa,EAAEV,MAAM,WAAW,EAAEJ,IAAIG,IAAI,CAAC,8DAA8D,EAAEH,IAAIG,IAAI,CAAC,gCAAgC,CAAC;IACpK,OAAO;QACLU,QAAQC,GAAG,CAAC,CAAC,aAAa,EAAEV,MAAM,EAAE,EAAEE,WAAWC,MAAM,CAAC,IAAI,EAAEA,KAAK,GAAG,GAAG,wEAAwE,CAAC;IACpJ;IACAM,QAAQC,GAAG,CAAC;IACZ,4FAA4F;IAC5F,oFAAoF;IACpFD,QAAQC,GAAG,CAAC;AACd;AACA,eAAef,KAAK"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/map.ts"],"sourcesContent":["import { mapTree } from '../commands/map.ts';\nimport { renderMap, stringifyJson } from '../output/output.ts';\nimport type { BuildRequirement } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, NO_BUILD, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst map: Command = (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.map}`, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, { noBuild: values['no-build'] === true, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg) => {\n const result = await mapTree(store, cfg, scopeOf(values));\n console.log(format === 'json' ? stringifyJson(result, 2) : renderMap(result));\n });\n};\nexport default map;\n"],"names":["mapTree","renderMap","stringifyJson","USAGE","CONFIG","FORMAT","formatOf","NO_BUILD","parse","SCOPE","scopeOf","withDb","map","ctx","values","argv","name","format","config","noBuild","requirements","Set","store","cfg","result","console","log"],"mappings":"AAAA,SAASA,OAAO,QAAQ,qBAAqB;AAC7C,SAASC,SAAS,EAAEC,aAAa,QAAQ,sBAAsB;AAE/D,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGhG,MAAMC,MAAe,CAACC;IACpB,MAAM,EAAEC,MAAM,EAAE,GAAGN,MAAMK,IAAIE,IAAI,EAAE,CAAC,OAAO,EAAEF,IAAIG,IAAI,CAAC,CAAC,EAAEb,MAAMS,GAAG,EAAE,EAAE;QAAE,GAAGH,KAAK;QAAE,GAAGF,QAAQ;QAAE,GAAGF,MAAM;QAAE,GAAGD,MAAM;IAAC;IACpH,MAAMa,SAASX,SAASQ;IACxB,OAAOH,OAAOE,KAAKC,OAAOI,MAAM,EAAwB;QAAEC,SAASL,MAAM,CAAC,WAAW,KAAK;QAAMM,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,OAAOC,OAAOC;QACjK,MAAMC,SAAS,MAAMxB,QAAQsB,OAAOC,KAAKb,QAAQI;QACjDW,QAAQC,GAAG,CAACT,WAAW,SAASf,cAAcsB,QAAQ,KAAKvB,UAAUuB;IACvE;AACF;AACA,eAAeZ,IAAI"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/cli/map.ts"],"sourcesContent":["import { mapTree } from '../commands/map.ts';\nimport { renderMap, stringifyJson } from '../output/output.ts';\nimport type { BuildRequirement } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, NO_BUILD, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst map: Command = (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.map}`, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, { noBuild: values['no-build'] === true, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg) => {\n const result = await mapTree(store, cfg, scopeOf(values));\n console.log(format === 'json' ? stringifyJson(result, 2) : renderMap(result));\n });\n};\nexport default map;\n"],"names":["mapTree","renderMap","stringifyJson","USAGE","CONFIG","FORMAT","formatOf","NO_BUILD","parse","SCOPE","scopeOf","withDb","map","ctx","values","argv","name","format","config","noBuild","requirements","Set","store","cfg","result","console","log"],"mappings":"AAAA,SAASA,OAAO,QAAQ,qBAAqB;AAC7C,SAASC,SAAS,EAAEC,aAAa,QAAQ,sBAAsB;AAE/D,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGhG,MAAMC,MAAe,CAACC;IACpB,MAAM,EAAEC,MAAM,EAAE,GAAGN,MAAMK,IAAIE,IAAI,EAAE,CAAC,OAAO,EAAEF,IAAIG,IAAI,CAAC,CAAC,EAAEb,MAAMS,GAAG,EAAE,EAAE;QAAE,GAAGH,KAAK;QAAE,GAAGF,QAAQ;QAAE,GAAGF,MAAM;QAAE,GAAGD,MAAM;IAAC;IACpH,MAAMa,SAASX,SAASQ;IACxB,OAAOH,OAAOE,KAAKC,OAAOI,MAAM,EAAwB;QAAEC,SAASL,MAAM,CAAC,WAAW,KAAK;QAAMM,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,OAAOC,OAAOC;QACjK,MAAMC,SAAS,MAAMxB,QAAQsB,OAAOC,KAAKb,QAAQI;QACjDW,QAAQC,GAAG,CAACT,WAAW,SAASf,cAAcsB,QAAQ,KAAKvB,UAAUuB;IACvE;AACF;AACA,eAAeZ,IAAI"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/named.ts"],"sourcesContent":["import { scopedPaths } from '../commands/scope.ts';\nimport { search } from '../commands/search.ts';\nimport { resolveSearch } from '../config/index.ts';\nimport { printRows } from '../output/output.ts';\nimport { type BuildRequirement, prepareDocumentEmbeddings } from '../store/open.ts';\nimport { CONFIG, FORMAT, NO_BUILD, parse, parseK, parseSnippetCharLimit, parseSnippetCountLimit, rowFormatOf, runSql, SEARCH_FLAGS, withResolvedDb } from './shared.ts';\nimport type { Ctx } from './types.ts';\n\n// Fallback when the first positional is not a command: a saved query, { sql } or { search }.\n// SEARCH_FLAGS override a saved search's fields the same way they override a preset's.\nexport default async function named(ctx: Ctx, queryName: string): Promise<void> {\n const usage = `usage: ${ctx.name} ${queryName} [params...] [--format table|json|csv] [--config path] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--no-build]`;\n const { values, positionals: params } = parse(ctx.argv, usage, { ...SEARCH_FLAGS, ...NO_BUILD, ...FORMAT, ...CONFIG });\n const format = rowFormatOf(values);\n const configPath = values.config as string | undefined;\n const noBuild = values['no-build'] === true;\n\n const cfg = ctx.resolveConfig(configPath, { writeMigration: !noBuild, query: true });\n const entry = cfg.queries[queryName];\n if (entry === undefined) {\n console.error(`unknown command or saved entry: \"${queryName}\"`);\n console.error(`saved queries: ${Object.keys(cfg.queries).sort().join(', ')}`);\n process.exit(2);\n }\n\n if ('sql' in entry) {\n // A saved statement written against `scope` is preset-agnostic, so the same entry can be\n // re-pointed at another layer from the command line instead of being copied per preset.\n await runSql(cfg, entry.sql, params, format, `query \"${queryName}\"`, noBuild, values.preset as string | undefined);\n return;\n }\n\n // A saved search's text is fixed in config; there is nowhere for a positional to bind.\n if (params.length > 0) {\n ctx.usageError(`\"${queryName}\" is a saved search and takes no positional parameters; edit its \"search\" in sense.config.json, or use \"${ctx.name} search\" directly`);\n }\n const k = parseK(values.k as string | undefined, ctx.usageError) ?? entry.k;\n const snippetCharLimit = parseSnippetCharLimit(values['snippet-char-limit'] as string | undefined, ctx.usageError);\n const snippetCountLimit = parseSnippetCountLimit(values['snippet-count-limit'] as string | undefined, ctx.usageError);\n const where = (values.where as string | undefined) ?? entry.where;\n const preset = (values.preset as string | undefined) ?? entry.preset;\n const include = (values.include as string[] | undefined) ?? entry.include;\n const exclude = (values.exclude as string[] | undefined) ?? entry.exclude;\n const noExclude = values['no-exclude'] === true;\n const overrides = { k, snippetCharLimit, snippetCountLimit, where, preset, include, exclude, noExclude };\n await withResolvedDb(\n cfg,\n {\n noBuild,\n requirements: (resolvedCfg) => {\n const signals = resolveSearch(resolvedCfg, overrides).signals;\n const requirements = new Set<BuildRequirement>(['core']);\n if (signals.words !== undefined) requirements.add('lexical');\n return requirements;\n },\n },\n async (store, resolvedCfg, build) => {\n if (build && resolveSearch(resolvedCfg, overrides).signals.vectors !== undefined) {\n await prepareDocumentEmbeddings(store, resolvedCfg, await scopedPaths(store, resolvedCfg, overrides));\n }\n printRows(await search(store, resolvedCfg, entry.search, overrides), format);\n }\n );\n}\n"],"names":["scopedPaths","search","resolveSearch","printRows","prepareDocumentEmbeddings","CONFIG","FORMAT","NO_BUILD","parse","parseK","parseSnippetCharLimit","parseSnippetCountLimit","rowFormatOf","runSql","SEARCH_FLAGS","withResolvedDb","named","ctx","queryName","values","usage","name","positionals","params","argv","format","configPath","config","noBuild","cfg","resolveConfig","writeMigration","query","entry","queries","undefined","console","error","Object","keys","sort","join","process","exit","sql","preset","length","usageError","k","snippetCharLimit","snippetCountLimit","where","include","exclude","noExclude","overrides","requirements","resolvedCfg","signals","Set","words","add","store","build","vectors"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/cli/named.ts"],"sourcesContent":["import { scopedPaths } from '../commands/scope.ts';\nimport { search } from '../commands/search.ts';\nimport { resolveSearch } from '../config/index.ts';\nimport { printRows } from '../output/output.ts';\nimport { type BuildRequirement, prepareDocumentEmbeddings } from '../store/open.ts';\nimport { CONFIG, FORMAT, NO_BUILD, parse, parseK, parseSnippetCharLimit, parseSnippetCountLimit, rowFormatOf, runSql, SEARCH_FLAGS, withResolvedDb } from './shared.ts';\nimport type { Ctx } from './types.ts';\n\n// Fallback when the first positional is not a command: a saved query, { sql } or { search }.\n// SEARCH_FLAGS override a saved search's fields the same way they override a preset's.\nexport default async function named(ctx: Ctx, queryName: string): Promise<void> {\n const usage = `usage: ${ctx.name} ${queryName} [params...] [--format table|json|csv] [--config path] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--no-build]`;\n const { values, positionals: params } = parse(ctx.argv, usage, { ...SEARCH_FLAGS, ...NO_BUILD, ...FORMAT, ...CONFIG });\n const format = rowFormatOf(values);\n const configPath = values.config as string | undefined;\n const noBuild = values['no-build'] === true;\n\n const cfg = ctx.resolveConfig(configPath, { writeMigration: !noBuild, query: true });\n const entry = cfg.queries[queryName];\n if (entry === undefined) {\n console.error(`unknown command or saved entry: \"${queryName}\"`);\n console.error(`saved queries: ${Object.keys(cfg.queries).sort().join(', ')}`);\n process.exit(2);\n }\n\n if ('sql' in entry) {\n // A saved statement written against `scope` is preset-agnostic, so the same entry can be\n // re-pointed at another layer from the command line instead of being copied per preset.\n await runSql(cfg, entry.sql, params, format, `query \"${queryName}\"`, noBuild, values.preset as string | undefined);\n return;\n }\n\n // A saved search's text is fixed in config; there is nowhere for a positional to bind.\n if (params.length > 0) {\n ctx.usageError(`\"${queryName}\" is a saved search and takes no positional parameters; edit its \"search\" in sense.config.json, or use \"${ctx.name} search\" directly`);\n }\n const k = parseK(values.k as string | undefined, ctx.usageError) ?? entry.k;\n const snippetCharLimit = parseSnippetCharLimit(values['snippet-char-limit'] as string | undefined, ctx.usageError);\n const snippetCountLimit = parseSnippetCountLimit(values['snippet-count-limit'] as string | undefined, ctx.usageError);\n const where = (values.where as string | undefined) ?? entry.where;\n const preset = (values.preset as string | undefined) ?? entry.preset;\n const include = (values.include as string[] | undefined) ?? entry.include;\n const exclude = (values.exclude as string[] | undefined) ?? entry.exclude;\n const noExclude = values['no-exclude'] === true;\n const overrides = { k, snippetCharLimit, snippetCountLimit, where, preset, include, exclude, noExclude };\n await withResolvedDb(\n cfg,\n {\n noBuild,\n requirements: (resolvedCfg) => {\n const signals = resolveSearch(resolvedCfg, overrides).signals;\n const requirements = new Set<BuildRequirement>(['core']);\n if (signals.words !== undefined) requirements.add('lexical');\n return requirements;\n },\n },\n async (store, resolvedCfg, build) => {\n if (build && resolveSearch(resolvedCfg, overrides).signals.vectors !== undefined) {\n await prepareDocumentEmbeddings(store, resolvedCfg, await scopedPaths(store, resolvedCfg, overrides));\n }\n printRows(await search(store, resolvedCfg, entry.search, overrides), format);\n }\n );\n}\n"],"names":["scopedPaths","search","resolveSearch","printRows","prepareDocumentEmbeddings","CONFIG","FORMAT","NO_BUILD","parse","parseK","parseSnippetCharLimit","parseSnippetCountLimit","rowFormatOf","runSql","SEARCH_FLAGS","withResolvedDb","named","ctx","queryName","values","usage","name","positionals","params","argv","format","configPath","config","noBuild","cfg","resolveConfig","writeMigration","query","entry","queries","undefined","console","error","Object","keys","sort","join","process","exit","sql","preset","length","usageError","k","snippetCharLimit","snippetCountLimit","where","include","exclude","noExclude","overrides","requirements","resolvedCfg","signals","Set","words","add","store","build","vectors"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/path.ts"],"sourcesContent":["import { findPath } from '../commands/path.ts';\nimport type { Row } from '../output/output.ts';\nimport { printRows } from '../output/output.ts';\nimport type { BuildRequirement } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, NO_BUILD, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// --max-depth must be a positive integer, mirroring shared.ts's parseK.\nfunction parseMaxDepth(depth: string | undefined, usageError: (message: string) => never): number | undefined {\n if (depth === undefined) return undefined;\n const parsed = Number(depth);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--max-depth expects a positive integer, got \"${depth}\"`);\n return parsed;\n}\n\nconst pathCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.path}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG, 'max-depth': { type: 'string' } });\n const [a, b] = positionals;\n if (!a || !b) ctx.usageError(usage);\n const maxDepth = parseMaxDepth(values['max-depth'] as string | undefined, ctx.usageError);\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, { noBuild: values['no-build'] === true, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg) => {\n const hops = await findPath(store, cfg, a, b, { ...scopeOf(values), maxDepth });\n\n if (format === 'json') {\n console.log(JSON.stringify(hops));\n return;\n }\n if (hops === null) {\n console.log(maxDepth ? `no path within ${maxDepth} hops` : 'no path');\n return;\n }\n const rows: Row[] = hops.map((p, step) => ({ step, path: p }));\n printRows(rows, format);\n });\n};\nexport default pathCmd;\n"],"names":["findPath","printRows","USAGE","CONFIG","FORMAT","formatOf","NO_BUILD","parse","SCOPE","scopeOf","withDb","parseMaxDepth","depth","usageError","undefined","parsed","Number","isInteger","pathCmd","ctx","usage","name","path","values","positionals","argv","type","a","b","maxDepth","format","config","noBuild","requirements","Set","store","cfg","hops","console","log","JSON","stringify","rows","map","p","step"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,sBAAsB;AAE/C,SAASC,SAAS,QAAQ,sBAAsB;AAEhD,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGhG,wEAAwE;AACxE,SAASC,cAAcC,KAAyB,EAAEC,UAAsC;IACtF,IAAID,UAAUE,WAAW,OAAOA;IAChC,MAAMC,SAASC,OAAOJ;IACtB,IAAI,CAACI,OAAOC,SAAS,CAACF,WAAWA,UAAU,GAAGF,WAAW,CAAC,6CAA6C,EAAED,MAAM,CAAC,CAAC;IACjH,OAAOG;AACT;AAEA,MAAMG,UAAmB,CAACC;IACxB,MAAMC,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEnB,MAAMoB,IAAI,EAAE;IAChD,MAAM,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGjB,MAAMY,IAAIM,IAAI,EAAEL,OAAO;QAAE,GAAGZ,KAAK;QAAE,GAAGF,QAAQ;QAAE,GAAGF,MAAM;QAAE,GAAGD,MAAM;QAAE,aAAa;YAAEuB,MAAM;QAAS;IAAE;IACtI,MAAM,CAACC,GAAGC,EAAE,GAAGJ;IACf,IAAI,CAACG,KAAK,CAACC,GAAGT,IAAIN,UAAU,CAACO;IAC7B,MAAMS,WAAWlB,cAAcY,MAAM,CAAC,YAAY,EAAwBJ,IAAIN,UAAU;IACxF,MAAMiB,SAASzB,SAASkB;IACxB,OAAOb,OAAOS,KAAKI,OAAOQ,MAAM,EAAwB;QAAEC,SAAST,MAAM,CAAC,WAAW,KAAK;QAAMU,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,OAAOC,OAAOC;QACjK,MAAMC,OAAO,MAAMrC,SAASmC,OAAOC,KAAKT,GAAGC,GAAG;YAAE,GAAGnB,QAAQc,OAAO;YAAEM;QAAS;QAE7E,IAAIC,WAAW,QAAQ;YACrBQ,QAAQC,GAAG,CAACC,KAAKC,SAAS,CAACJ;YAC3B;QACF;QACA,IAAIA,SAAS,MAAM;YACjBC,QAAQC,GAAG,CAACV,WAAW,CAAC,eAAe,EAAEA,SAAS,KAAK,CAAC,GAAG;YAC3D;QACF;QACA,MAAMa,OAAcL,KAAKM,GAAG,CAAC,CAACC,GAAGC,OAAU,CAAA;gBAAEA;gBAAMvB,MAAMsB;YAAE,CAAA;QAC3D3C,UAAUyC,MAAMZ;IAClB;AACF;AACA,eAAeZ,QAAQ"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/cli/path.ts"],"sourcesContent":["import { findPath } from '../commands/path.ts';\nimport type { Row } from '../output/output.ts';\nimport { printRows } from '../output/output.ts';\nimport type { BuildRequirement } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, NO_BUILD, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// --max-depth must be a positive integer, mirroring shared.ts's parseK.\nfunction parseMaxDepth(depth: string | undefined, usageError: (message: string) => never): number | undefined {\n if (depth === undefined) return undefined;\n const parsed = Number(depth);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--max-depth expects a positive integer, got \"${depth}\"`);\n return parsed;\n}\n\nconst pathCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.path}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG, 'max-depth': { type: 'string' } });\n const [a, b] = positionals;\n if (!a || !b) ctx.usageError(usage);\n const maxDepth = parseMaxDepth(values['max-depth'] as string | undefined, ctx.usageError);\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, { noBuild: values['no-build'] === true, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg) => {\n const hops = await findPath(store, cfg, a, b, { ...scopeOf(values), maxDepth });\n\n if (format === 'json') {\n console.log(JSON.stringify(hops));\n return;\n }\n if (hops === null) {\n console.log(maxDepth ? `no path within ${maxDepth} hops` : 'no path');\n return;\n }\n const rows: Row[] = hops.map((p, step) => ({ step, path: p }));\n printRows(rows, format);\n });\n};\nexport default pathCmd;\n"],"names":["findPath","printRows","USAGE","CONFIG","FORMAT","formatOf","NO_BUILD","parse","SCOPE","scopeOf","withDb","parseMaxDepth","depth","usageError","undefined","parsed","Number","isInteger","pathCmd","ctx","usage","name","path","values","positionals","argv","type","a","b","maxDepth","format","config","noBuild","requirements","Set","store","cfg","hops","console","log","JSON","stringify","rows","map","p","step"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,sBAAsB;AAE/C,SAASC,SAAS,QAAQ,sBAAsB;AAEhD,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGhG,wEAAwE;AACxE,SAASC,cAAcC,KAAyB,EAAEC,UAAsC;IACtF,IAAID,UAAUE,WAAW,OAAOA;IAChC,MAAMC,SAASC,OAAOJ;IACtB,IAAI,CAACI,OAAOC,SAAS,CAACF,WAAWA,UAAU,GAAGF,WAAW,CAAC,6CAA6C,EAAED,MAAM,CAAC,CAAC;IACjH,OAAOG;AACT;AAEA,MAAMG,UAAmB,CAACC;IACxB,MAAMC,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEnB,MAAMoB,IAAI,EAAE;IAChD,MAAM,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGjB,MAAMY,IAAIM,IAAI,EAAEL,OAAO;QAAE,GAAGZ,KAAK;QAAE,GAAGF,QAAQ;QAAE,GAAGF,MAAM;QAAE,GAAGD,MAAM;QAAE,aAAa;YAAEuB,MAAM;QAAS;IAAE;IACtI,MAAM,CAACC,GAAGC,EAAE,GAAGJ;IACf,IAAI,CAACG,KAAK,CAACC,GAAGT,IAAIN,UAAU,CAACO;IAC7B,MAAMS,WAAWlB,cAAcY,MAAM,CAAC,YAAY,EAAwBJ,IAAIN,UAAU;IACxF,MAAMiB,SAASzB,SAASkB;IACxB,OAAOb,OAAOS,KAAKI,OAAOQ,MAAM,EAAwB;QAAEC,SAAST,MAAM,CAAC,WAAW,KAAK;QAAMU,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,OAAOC,OAAOC;QACjK,MAAMC,OAAO,MAAMrC,SAASmC,OAAOC,KAAKT,GAAGC,GAAG;YAAE,GAAGnB,QAAQc,OAAO;YAAEM;QAAS;QAE7E,IAAIC,WAAW,QAAQ;YACrBQ,QAAQC,GAAG,CAACC,KAAKC,SAAS,CAACJ;YAC3B;QACF;QACA,IAAIA,SAAS,MAAM;YACjBC,QAAQC,GAAG,CAACV,WAAW,CAAC,eAAe,EAAEA,SAAS,KAAK,CAAC,GAAG;YAC3D;QACF;QACA,MAAMa,OAAcL,KAAKM,GAAG,CAAC,CAACC,GAAGC,OAAU,CAAA;gBAAEA;gBAAMvB,MAAMsB;YAAE,CAAA;QAC3D3C,UAAUyC,MAAMZ;IAClB;AACF;AACA,eAAeZ,QAAQ"}
@@ -2,16 +2,30 @@ import { peek } from '../commands/peek.js';
2
2
  import { renderPeek, stringifyJson } from '../output/output.js';
3
3
  import { USAGE } from './index.js';
4
4
  import { CONFIG, FORMAT, formatOf, NO_BUILD, parse, SCOPE, scopeOf, withDb } from './shared.js';
5
+ function parseCountLimit(name, value, usageError) {
6
+ if (value === undefined) return undefined;
7
+ const parsed = Number(value);
8
+ if (!Number.isSafeInteger(parsed) || parsed <= 0) usageError(`--${name} expects a positive safe integer, got "${value}"`);
9
+ return parsed;
10
+ }
5
11
  const peekCmd = (ctx)=>{
6
12
  const usage = `usage: ${ctx.name} ${USAGE.peek}`;
7
13
  const { values, positionals } = parse(ctx.argv, usage, {
8
14
  ...SCOPE,
9
15
  ...NO_BUILD,
10
16
  ...FORMAT,
11
- ...CONFIG
17
+ ...CONFIG,
18
+ 'section-count-limit': {
19
+ type: 'string'
20
+ },
21
+ 'link-count-limit': {
22
+ type: 'string'
23
+ }
12
24
  });
13
25
  const [pathArg] = positionals;
14
26
  if (!pathArg) ctx.usageError(usage);
27
+ const sectionCountLimit = parseCountLimit('section-count-limit', values['section-count-limit'], ctx.usageError);
28
+ const linkCountLimit = parseCountLimit('link-count-limit', values['link-count-limit'], ctx.usageError);
15
29
  const format = formatOf(values);
16
30
  return withDb(ctx, values.config, {
17
31
  noBuild: values['no-build'] === true,
@@ -19,7 +33,11 @@ const peekCmd = (ctx)=>{
19
33
  'core'
20
34
  ])
21
35
  }, async (store, cfg)=>{
22
- const overrides = scopeOf(values);
36
+ const overrides = {
37
+ ...scopeOf(values),
38
+ sectionCountLimit,
39
+ linkCountLimit
40
+ };
23
41
  const result = await peek(store, cfg, pathArg, overrides);
24
42
  console.log(format === 'json' ? stringifyJson(result, 2) : renderPeek(result));
25
43
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/peek.ts"],"sourcesContent":["import { peek } from '../commands/peek.ts';\nimport { renderPeek, stringifyJson } from '../output/output.ts';\nimport type { BuildRequirement } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, NO_BUILD, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst peekCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.peek}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG });\n const [pathArg] = positionals;\n if (!pathArg) ctx.usageError(usage);\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, { noBuild: values['no-build'] === true, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg) => {\n const overrides = scopeOf(values);\n const result = await peek(store, cfg, pathArg, overrides);\n console.log(format === 'json' ? stringifyJson(result, 2) : renderPeek(result));\n });\n};\nexport default peekCmd;\n"],"names":["peek","renderPeek","stringifyJson","USAGE","CONFIG","FORMAT","formatOf","NO_BUILD","parse","SCOPE","scopeOf","withDb","peekCmd","ctx","usage","name","values","positionals","argv","pathArg","usageError","format","config","noBuild","requirements","Set","store","cfg","overrides","result","console","log"],"mappings":"AAAA,SAASA,IAAI,QAAQ,sBAAsB;AAC3C,SAASC,UAAU,EAAEC,aAAa,QAAQ,sBAAsB;AAEhE,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGhG,MAAMC,UAAmB,CAACC;IACxB,MAAMC,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEZ,MAAMH,IAAI,EAAE;IAChD,MAAM,EAAEgB,MAAM,EAAEC,WAAW,EAAE,GAAGT,MAAMK,IAAIK,IAAI,EAAEJ,OAAO;QAAE,GAAGL,KAAK;QAAE,GAAGF,QAAQ;QAAE,GAAGF,MAAM;QAAE,GAAGD,MAAM;IAAC;IACrG,MAAM,CAACe,QAAQ,GAAGF;IAClB,IAAI,CAACE,SAASN,IAAIO,UAAU,CAACN;IAC7B,MAAMO,SAASf,SAASU;IACxB,OAAOL,OAAOE,KAAKG,OAAOM,MAAM,EAAwB;QAAEC,SAASP,MAAM,CAAC,WAAW,KAAK;QAAMQ,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,OAAOC,OAAOC;QACjK,MAAMC,YAAYlB,QAAQM;QAC1B,MAAMa,SAAS,MAAM7B,KAAK0B,OAAOC,KAAKR,SAASS;QAC/CE,QAAQC,GAAG,CAACV,WAAW,SAASnB,cAAc2B,QAAQ,KAAK5B,WAAW4B;IACxE;AACF;AACA,eAAejB,QAAQ"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/cli/peek.ts"],"sourcesContent":["import { peek } from '../commands/peek.ts';\nimport { renderPeek, stringifyJson } from '../output/output.ts';\nimport type { BuildRequirement } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, NO_BUILD, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nfunction parseCountLimit(name: string, value: string | undefined, usageError: (message: string) => never): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n if (!Number.isSafeInteger(parsed) || parsed <= 0) usageError(`--${name} expects a positive safe integer, got \"${value}\"`);\n return parsed;\n}\n\nconst peekCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.peek}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG, 'section-count-limit': { type: 'string' }, 'link-count-limit': { type: 'string' } });\n const [pathArg] = positionals;\n if (!pathArg) ctx.usageError(usage);\n const sectionCountLimit = parseCountLimit('section-count-limit', values['section-count-limit'] as string | undefined, ctx.usageError);\n const linkCountLimit = parseCountLimit('link-count-limit', values['link-count-limit'] as string | undefined, ctx.usageError);\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, { noBuild: values['no-build'] === true, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg) => {\n const overrides = { ...scopeOf(values), sectionCountLimit, linkCountLimit };\n const result = await peek(store, cfg, pathArg, overrides);\n console.log(format === 'json' ? stringifyJson(result, 2) : renderPeek(result));\n });\n};\nexport default peekCmd;\n"],"names":["peek","renderPeek","stringifyJson","USAGE","CONFIG","FORMAT","formatOf","NO_BUILD","parse","SCOPE","scopeOf","withDb","parseCountLimit","name","value","usageError","undefined","parsed","Number","isSafeInteger","peekCmd","ctx","usage","values","positionals","argv","type","pathArg","sectionCountLimit","linkCountLimit","format","config","noBuild","requirements","Set","store","cfg","overrides","result","console","log"],"mappings":"AAAA,SAASA,IAAI,QAAQ,sBAAsB;AAC3C,SAASC,UAAU,EAAEC,aAAa,QAAQ,sBAAsB;AAEhE,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGhG,SAASC,gBAAgBC,IAAY,EAAEC,KAAyB,EAAEC,UAAsC;IACtG,IAAID,UAAUE,WAAW,OAAOA;IAChC,MAAMC,SAASC,OAAOJ;IACtB,IAAI,CAACI,OAAOC,aAAa,CAACF,WAAWA,UAAU,GAAGF,WAAW,CAAC,EAAE,EAAEF,KAAK,uCAAuC,EAAEC,MAAM,CAAC,CAAC;IACxH,OAAOG;AACT;AAEA,MAAMG,UAAmB,CAACC;IACxB,MAAMC,QAAQ,CAAC,OAAO,EAAED,IAAIR,IAAI,CAAC,CAAC,EAAEV,MAAMH,IAAI,EAAE;IAChD,MAAM,EAAEuB,MAAM,EAAEC,WAAW,EAAE,GAAGhB,MAAMa,IAAII,IAAI,EAAEH,OAAO;QAAE,GAAGb,KAAK;QAAE,GAAGF,QAAQ;QAAE,GAAGF,MAAM;QAAE,GAAGD,MAAM;QAAE,uBAAuB;YAAEsB,MAAM;QAAS;QAAG,oBAAoB;YAAEA,MAAM;QAAS;IAAE;IACxL,MAAM,CAACC,QAAQ,GAAGH;IAClB,IAAI,CAACG,SAASN,IAAIN,UAAU,CAACO;IAC7B,MAAMM,oBAAoBhB,gBAAgB,uBAAuBW,MAAM,CAAC,sBAAsB,EAAwBF,IAAIN,UAAU;IACpI,MAAMc,iBAAiBjB,gBAAgB,oBAAoBW,MAAM,CAAC,mBAAmB,EAAwBF,IAAIN,UAAU;IAC3H,MAAMe,SAASxB,SAASiB;IACxB,OAAOZ,OAAOU,KAAKE,OAAOQ,MAAM,EAAwB;QAAEC,SAAST,MAAM,CAAC,WAAW,KAAK;QAAMU,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,OAAOC,OAAOC;QACjK,MAAMC,YAAY;YAAE,GAAG3B,QAAQa,OAAO;YAAEK;YAAmBC;QAAe;QAC1E,MAAMS,SAAS,MAAMtC,KAAKmC,OAAOC,KAAKT,SAASU;QAC/CE,QAAQC,GAAG,CAACV,WAAW,SAAS5B,cAAcoC,QAAQ,KAAKrC,WAAWqC;IACxE;AACF;AACA,eAAelB,QAAQ"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/related.ts"],"sourcesContent":["import { RELATED_DEFAULT_K, relatedNotes, resolveRelatedSeed } from '../commands/related.ts';\nimport { scopedPaths } from '../commands/scope.ts';\nimport { resolveSearch } from '../config/index.ts';\nimport { printRows } from '../output/output.ts';\nimport { type BuildRequirement, prepareDocumentEmbeddings } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, NO_BUILD, parse, parseK, rowFormatOf, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst relatedCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.related}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG, k: { type: 'string' } });\n const [pathArg] = positionals;\n if (!pathArg) ctx.usageError(usage);\n const k = parseK(values.k as string | undefined, ctx.usageError) ?? RELATED_DEFAULT_K;\n const format = rowFormatOf(values);\n const noBuild = values['no-build'] === true;\n return withDb(ctx, values.config as string | undefined, { noBuild, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg, build) => {\n const overrides = scopeOf(values);\n if (build && resolveSearch(cfg, overrides).signals.vectors !== undefined) {\n const path = await resolveRelatedSeed(store, pathArg);\n const allowed = await scopedPaths(store, cfg, overrides);\n await prepareDocumentEmbeddings(store, cfg, new Set([...allowed, path]));\n }\n printRows(await relatedNotes(store, cfg, pathArg, { ...overrides, k }), format);\n });\n};\nexport default relatedCmd;\n"],"names":["RELATED_DEFAULT_K","relatedNotes","resolveRelatedSeed","scopedPaths","resolveSearch","printRows","prepareDocumentEmbeddings","USAGE","CONFIG","FORMAT","NO_BUILD","parse","parseK","rowFormatOf","SCOPE","scopeOf","withDb","relatedCmd","ctx","usage","name","related","values","positionals","argv","k","type","pathArg","usageError","format","noBuild","config","requirements","Set","store","cfg","build","overrides","signals","vectors","undefined","path","allowed"],"mappings":"AAAA,SAASA,iBAAiB,EAAEC,YAAY,EAAEC,kBAAkB,QAAQ,yBAAyB;AAC7F,SAASC,WAAW,QAAQ,uBAAuB;AACnD,SAASC,aAAa,QAAQ,qBAAqB;AACnD,SAASC,SAAS,QAAQ,sBAAsB;AAChD,SAAgCC,yBAAyB,QAAQ,mBAAmB;AACpF,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,MAAM,EAAEC,WAAW,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAG3G,MAAMC,aAAsB,CAACC;QAKjBN;IAJV,MAAMO,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEb,MAAMc,OAAO,EAAE;IACnD,MAAM,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGZ,MAAMO,IAAIM,IAAI,EAAEL,OAAO;QAAE,GAAGL,KAAK;QAAE,GAAGJ,QAAQ;QAAE,GAAGD,MAAM;QAAE,GAAGD,MAAM;QAAEiB,GAAG;YAAEC,MAAM;QAAS;IAAE;IAC5H,MAAM,CAACC,QAAQ,GAAGJ;IAClB,IAAI,CAACI,SAAST,IAAIU,UAAU,CAACT;IAC7B,MAAMM,KAAIb,UAAAA,OAAOU,OAAOG,CAAC,EAAwBP,IAAIU,UAAU,eAArDhB,qBAAAA,UAA0DZ;IACpE,MAAM6B,SAAShB,YAAYS;IAC3B,MAAMQ,UAAUR,MAAM,CAAC,WAAW,KAAK;IACvC,OAAON,OAAOE,KAAKI,OAAOS,MAAM,EAAwB;QAAED;QAASE,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,OAAOC,OAAOC,KAAKC;QACzI,MAAMC,YAAYtB,QAAQO;QAC1B,IAAIc,SAAShC,cAAc+B,KAAKE,WAAWC,OAAO,CAACC,OAAO,KAAKC,WAAW;YACxE,MAAMC,OAAO,MAAMvC,mBAAmBgC,OAAOP;YAC7C,MAAMe,UAAU,MAAMvC,YAAY+B,OAAOC,KAAKE;YAC9C,MAAM/B,0BAA0B4B,OAAOC,KAAK,IAAIF,IAAI;mBAAIS;gBAASD;aAAK;QACxE;QACApC,UAAU,MAAMJ,aAAaiC,OAAOC,KAAKR,SAAS;YAAE,GAAGU,SAAS;YAAEZ;QAAE,IAAII;IAC1E;AACF;AACA,eAAeZ,WAAW"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/open-source/ai/sensemaking/src/cli/related.ts"],"sourcesContent":["import { RELATED_DEFAULT_K, relatedNotes, resolveRelatedSeed } from '../commands/related.ts';\nimport { scopedPaths } from '../commands/scope.ts';\nimport { resolveSearch } from '../config/index.ts';\nimport { printRows } from '../output/output.ts';\nimport { type BuildRequirement, prepareDocumentEmbeddings } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, NO_BUILD, parse, parseK, rowFormatOf, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst relatedCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.related}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG, k: { type: 'string' } });\n const [pathArg] = positionals;\n if (!pathArg) ctx.usageError(usage);\n const k = parseK(values.k as string | undefined, ctx.usageError) ?? RELATED_DEFAULT_K;\n const format = rowFormatOf(values);\n const noBuild = values['no-build'] === true;\n return withDb(ctx, values.config as string | undefined, { noBuild, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg, build) => {\n const overrides = scopeOf(values);\n if (build && resolveSearch(cfg, overrides).signals.vectors !== undefined) {\n const path = await resolveRelatedSeed(store, pathArg);\n const allowed = await scopedPaths(store, cfg, overrides);\n await prepareDocumentEmbeddings(store, cfg, new Set([...allowed, path]));\n }\n printRows(await relatedNotes(store, cfg, pathArg, { ...overrides, k }), format);\n });\n};\nexport default relatedCmd;\n"],"names":["RELATED_DEFAULT_K","relatedNotes","resolveRelatedSeed","scopedPaths","resolveSearch","printRows","prepareDocumentEmbeddings","USAGE","CONFIG","FORMAT","NO_BUILD","parse","parseK","rowFormatOf","SCOPE","scopeOf","withDb","relatedCmd","ctx","usage","name","related","values","positionals","argv","k","type","pathArg","usageError","format","noBuild","config","requirements","Set","store","cfg","build","overrides","signals","vectors","undefined","path","allowed"],"mappings":"AAAA,SAASA,iBAAiB,EAAEC,YAAY,EAAEC,kBAAkB,QAAQ,yBAAyB;AAC7F,SAASC,WAAW,QAAQ,uBAAuB;AACnD,SAASC,aAAa,QAAQ,qBAAqB;AACnD,SAASC,SAAS,QAAQ,sBAAsB;AAChD,SAAgCC,yBAAyB,QAAQ,mBAAmB;AACpF,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,MAAM,EAAEC,WAAW,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAG3G,MAAMC,aAAsB,CAACC;QAKjBN;IAJV,MAAMO,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEb,MAAMc,OAAO,EAAE;IACnD,MAAM,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGZ,MAAMO,IAAIM,IAAI,EAAEL,OAAO;QAAE,GAAGL,KAAK;QAAE,GAAGJ,QAAQ;QAAE,GAAGD,MAAM;QAAE,GAAGD,MAAM;QAAEiB,GAAG;YAAEC,MAAM;QAAS;IAAE;IAC5H,MAAM,CAACC,QAAQ,GAAGJ;IAClB,IAAI,CAACI,SAAST,IAAIU,UAAU,CAACT;IAC7B,MAAMM,KAAIb,UAAAA,OAAOU,OAAOG,CAAC,EAAwBP,IAAIU,UAAU,eAArDhB,qBAAAA,UAA0DZ;IACpE,MAAM6B,SAAShB,YAAYS;IAC3B,MAAMQ,UAAUR,MAAM,CAAC,WAAW,KAAK;IACvC,OAAON,OAAOE,KAAKI,OAAOS,MAAM,EAAwB;QAAED;QAASE,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,OAAOC,OAAOC,KAAKC;QACzI,MAAMC,YAAYtB,QAAQO;QAC1B,IAAIc,SAAShC,cAAc+B,KAAKE,WAAWC,OAAO,CAACC,OAAO,KAAKC,WAAW;YACxE,MAAMC,OAAO,MAAMvC,mBAAmBgC,OAAOP;YAC7C,MAAMe,UAAU,MAAMvC,YAAY+B,OAAOC,KAAKE;YAC9C,MAAM/B,0BAA0B4B,OAAOC,KAAK,IAAIF,IAAI;mBAAIS;gBAASD;aAAK;QACxE;QACApC,UAAU,MAAMJ,aAAaiC,OAAOC,KAAKR,SAAS;YAAE,GAAGU,SAAS;YAAEZ;QAAE,IAAII;IAC1E;AACF;AACA,eAAeZ,WAAW"}