sensemaking 0.25.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (316) hide show
  1. package/README.md +14 -10
  2. package/dist/cjs/cli/index.d.cts +1 -1
  3. package/dist/cjs/cli/index.d.ts +1 -1
  4. package/dist/cjs/cli/index.js +1 -1
  5. package/dist/cjs/cli/index.js.map +1 -1
  6. package/dist/cjs/cli/path.js +5 -29
  7. package/dist/cjs/cli/path.js.map +1 -1
  8. package/dist/cjs/cli/related.js +4 -3
  9. package/dist/cjs/cli/related.js.map +1 -1
  10. package/dist/cjs/commands/index.d.cts +6 -3
  11. package/dist/cjs/commands/index.d.ts +6 -3
  12. package/dist/cjs/commands/index.js +4 -0
  13. package/dist/cjs/commands/index.js.map +1 -1
  14. package/dist/cjs/commands/map.d.cts +14 -5
  15. package/dist/cjs/commands/map.d.ts +14 -5
  16. package/dist/cjs/commands/map.js +42 -35
  17. package/dist/cjs/commands/map.js.map +1 -1
  18. package/dist/cjs/commands/path.d.cts +14 -0
  19. package/dist/cjs/commands/path.d.ts +14 -0
  20. package/dist/cjs/commands/path.js +209 -0
  21. package/dist/cjs/commands/path.js.map +1 -0
  22. package/dist/cjs/commands/peek.d.cts +16 -1
  23. package/dist/cjs/commands/peek.d.ts +16 -1
  24. package/dist/cjs/commands/peek.js +71 -33
  25. package/dist/cjs/commands/peek.js.map +1 -1
  26. package/dist/cjs/commands/related.d.cts +16 -3
  27. package/dist/cjs/commands/related.d.ts +16 -3
  28. package/dist/cjs/commands/related.js +131 -98
  29. package/dist/cjs/commands/related.js.map +1 -1
  30. package/dist/cjs/commands/scope.d.cts +1 -0
  31. package/dist/cjs/commands/scope.d.ts +1 -0
  32. package/dist/cjs/commands/scope.js +149 -0
  33. package/dist/cjs/commands/scope.js.map +1 -1
  34. package/dist/cjs/commands/search.d.cts +26 -3
  35. package/dist/cjs/commands/search.d.ts +26 -3
  36. package/dist/cjs/commands/search.js +211 -71
  37. package/dist/cjs/commands/search.js.map +1 -1
  38. package/dist/cjs/commands/signals.d.cts +4 -3
  39. package/dist/cjs/commands/signals.d.ts +4 -3
  40. package/dist/cjs/commands/signals.js +13 -4
  41. package/dist/cjs/commands/signals.js.map +1 -1
  42. package/dist/cjs/commands/snapshot.d.cts +3 -0
  43. package/dist/cjs/commands/snapshot.d.ts +3 -0
  44. package/dist/cjs/commands/snapshot.js +180 -0
  45. package/dist/cjs/commands/snapshot.js.map +1 -0
  46. package/dist/cjs/embed/cohere.js +41 -16
  47. package/dist/cjs/embed/cohere.js.map +1 -1
  48. package/dist/cjs/embed/endpoint.d.cts +2 -0
  49. package/dist/cjs/embed/endpoint.d.ts +2 -0
  50. package/dist/cjs/embed/endpoint.js +30 -0
  51. package/dist/cjs/embed/endpoint.js.map +1 -0
  52. package/dist/cjs/embed/handoff.d.cts +7 -2
  53. package/dist/cjs/embed/handoff.d.ts +7 -2
  54. package/dist/cjs/embed/handoff.js +10 -0
  55. package/dist/cjs/embed/handoff.js.map +1 -1
  56. package/dist/cjs/embed/http.d.cts +18 -1
  57. package/dist/cjs/embed/http.d.ts +18 -1
  58. package/dist/cjs/embed/http.js +239 -40
  59. package/dist/cjs/embed/http.js.map +1 -1
  60. package/dist/cjs/embed/openai.js +39 -17
  61. package/dist/cjs/embed/openai.js.map +1 -1
  62. package/dist/cjs/embed/query.d.cts +9 -3
  63. package/dist/cjs/embed/query.d.ts +9 -3
  64. package/dist/cjs/embed/query.js +257 -90
  65. package/dist/cjs/embed/query.js.map +1 -1
  66. package/dist/cjs/embed/registry.d.cts +2 -2
  67. package/dist/cjs/embed/registry.d.ts +2 -2
  68. package/dist/cjs/embed/registry.js +36 -4
  69. package/dist/cjs/embed/registry.js.map +1 -1
  70. package/dist/cjs/embed/static.js +6 -2
  71. package/dist/cjs/embed/static.js.map +1 -1
  72. package/dist/cjs/embed/store.js +42 -77
  73. package/dist/cjs/embed/store.js.map +1 -1
  74. package/dist/cjs/embed/types.d.cts +5 -2
  75. package/dist/cjs/embed/types.d.ts +5 -2
  76. package/dist/cjs/embed/types.js.map +1 -1
  77. package/dist/cjs/features/embed.js +290 -43
  78. package/dist/cjs/features/embed.js.map +1 -1
  79. package/dist/cjs/graph/traverse.d.cts +2 -2
  80. package/dist/cjs/graph/traverse.d.ts +2 -2
  81. package/dist/cjs/graph/traverse.js +15 -5
  82. package/dist/cjs/graph/traverse.js.map +1 -1
  83. package/dist/cjs/index.d.cts +2 -2
  84. package/dist/cjs/index.d.ts +2 -2
  85. package/dist/cjs/index.js +6 -0
  86. package/dist/cjs/index.js.map +1 -1
  87. package/dist/cjs/output/output.d.cts +4 -36
  88. package/dist/cjs/output/output.d.ts +4 -36
  89. package/dist/cjs/output/output.js +1 -2
  90. package/dist/cjs/output/output.js.map +1 -1
  91. package/dist/cjs/scan/pool.d.cts +2 -1
  92. package/dist/cjs/scan/pool.d.ts +2 -1
  93. package/dist/cjs/scan/pool.js +116 -27
  94. package/dist/cjs/scan/pool.js.map +1 -1
  95. package/dist/cjs/scan/reparse.d.cts +1 -0
  96. package/dist/cjs/scan/reparse.d.ts +1 -0
  97. package/dist/cjs/scan/reparse.js +75 -21
  98. package/dist/cjs/scan/reparse.js.map +1 -1
  99. package/dist/cjs/store/builder.d.cts +11 -21
  100. package/dist/cjs/store/builder.d.ts +11 -21
  101. package/dist/cjs/store/builder.js +1077 -438
  102. package/dist/cjs/store/builder.js.map +1 -1
  103. package/dist/cjs/store/duckdb/connection.js +16 -2
  104. package/dist/cjs/store/duckdb/connection.js.map +1 -1
  105. package/dist/cjs/store/duckdb/open.d.cts +1 -1
  106. package/dist/cjs/store/duckdb/open.d.ts +1 -1
  107. package/dist/cjs/store/duckdb/open.js +73 -65
  108. package/dist/cjs/store/duckdb/open.js.map +1 -1
  109. package/dist/cjs/store/duckdb/reconcile.js +533 -15
  110. package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
  111. package/dist/cjs/store/embed-scope.js +19 -9
  112. package/dist/cjs/store/embed-scope.js.map +1 -1
  113. package/dist/cjs/store/index.d.cts +6 -0
  114. package/dist/cjs/store/index.d.ts +6 -0
  115. package/dist/cjs/store/index.js +8 -4
  116. package/dist/cjs/store/index.js.map +1 -1
  117. package/dist/cjs/store/open.d.cts +6 -1
  118. package/dist/cjs/store/open.d.ts +6 -1
  119. package/dist/cjs/store/open.js +230 -307
  120. package/dist/cjs/store/open.js.map +1 -1
  121. package/dist/cjs/store/readiness.d.cts +5 -0
  122. package/dist/cjs/store/readiness.d.ts +5 -0
  123. package/dist/cjs/store/readiness.js +39 -0
  124. package/dist/cjs/store/readiness.js.map +1 -0
  125. package/dist/cjs/store/reconcile.d.cts +26 -1
  126. package/dist/cjs/store/reconcile.d.ts +26 -1
  127. package/dist/cjs/store/reconcile.js +670 -576
  128. package/dist/cjs/store/reconcile.js.map +1 -1
  129. package/dist/cjs/store/signature.d.cts +1 -0
  130. package/dist/cjs/store/signature.d.ts +1 -0
  131. package/dist/cjs/store/signature.js +9 -0
  132. package/dist/cjs/store/signature.js.map +1 -1
  133. package/dist/cjs/store/sqlite/open.d.cts +1 -1
  134. package/dist/cjs/store/sqlite/open.d.ts +1 -1
  135. package/dist/cjs/store/sqlite/open.js +84 -90
  136. package/dist/cjs/store/sqlite/open.js.map +1 -1
  137. package/dist/cjs/store/sqlite/reconcile.js.map +1 -1
  138. package/dist/cjs/store/sqlite/store.js +63 -60
  139. package/dist/cjs/store/sqlite/store.js.map +1 -1
  140. package/dist/cjs/store/sqlite/vectors.d.cts +2 -2
  141. package/dist/cjs/store/sqlite/vectors.d.ts +2 -2
  142. package/dist/cjs/store/sqlite/vectors.js +8 -4
  143. package/dist/cjs/store/sqlite/vectors.js.map +1 -1
  144. package/dist/cjs/store/stages.js.map +1 -1
  145. package/dist/cjs/store/turso/connection.d.cts +1 -0
  146. package/dist/cjs/store/turso/connection.d.ts +1 -0
  147. package/dist/cjs/store/turso/connection.js +319 -94
  148. package/dist/cjs/store/turso/connection.js.map +1 -1
  149. package/dist/cjs/store/turso/open.d.cts +1 -1
  150. package/dist/cjs/store/turso/open.d.ts +1 -1
  151. package/dist/cjs/store/turso/open.js +70 -74
  152. package/dist/cjs/store/turso/open.js.map +1 -1
  153. package/dist/cjs/store/turso/store.js +25 -23
  154. package/dist/cjs/store/turso/store.js.map +1 -1
  155. package/dist/cjs/store/turso/vectors.d.cts +2 -2
  156. package/dist/cjs/store/turso/vectors.d.ts +2 -2
  157. package/dist/cjs/store/turso/vectors.js +26 -16
  158. package/dist/cjs/store/turso/vectors.js.map +1 -1
  159. package/dist/cjs/store/types.d.cts +4 -1
  160. package/dist/cjs/store/types.d.ts +4 -1
  161. package/dist/cjs/store/types.js.map +1 -1
  162. package/dist/cjs/store/vectors.d.cts +14 -1
  163. package/dist/cjs/store/vectors.d.ts +14 -1
  164. package/dist/cjs/store/vectors.js +61 -0
  165. package/dist/cjs/store/vectors.js.map +1 -1
  166. package/dist/cjs/watch.d.cts +6 -0
  167. package/dist/cjs/watch.d.ts +6 -0
  168. package/dist/cjs/watch.js +42 -10
  169. package/dist/cjs/watch.js.map +1 -1
  170. package/dist/cjs/workers/parse.d.cts +4 -3
  171. package/dist/cjs/workers/parse.d.ts +4 -3
  172. package/dist/cjs/workers/parse.js +19 -17
  173. package/dist/cjs/workers/parse.js.map +1 -1
  174. package/dist/esm/cli/index.d.ts +1 -1
  175. package/dist/esm/cli/index.js +1 -1
  176. package/dist/esm/cli/index.js.map +1 -1
  177. package/dist/esm/cli/path.js +4 -10
  178. package/dist/esm/cli/path.js.map +1 -1
  179. package/dist/esm/cli/related.js +5 -3
  180. package/dist/esm/cli/related.js.map +1 -1
  181. package/dist/esm/commands/index.d.ts +6 -3
  182. package/dist/esm/commands/index.js +1 -0
  183. package/dist/esm/commands/index.js.map +1 -1
  184. package/dist/esm/commands/map.d.ts +14 -5
  185. package/dist/esm/commands/map.js +2 -0
  186. package/dist/esm/commands/map.js.map +1 -1
  187. package/dist/esm/commands/path.d.ts +14 -0
  188. package/dist/esm/commands/path.js +33 -0
  189. package/dist/esm/commands/path.js.map +1 -0
  190. package/dist/esm/commands/peek.d.ts +16 -1
  191. package/dist/esm/commands/peek.js +35 -9
  192. package/dist/esm/commands/peek.js.map +1 -1
  193. package/dist/esm/commands/related.d.ts +16 -3
  194. package/dist/esm/commands/related.js +45 -28
  195. package/dist/esm/commands/related.js.map +1 -1
  196. package/dist/esm/commands/scope.d.ts +1 -0
  197. package/dist/esm/commands/scope.js +58 -0
  198. package/dist/esm/commands/scope.js.map +1 -1
  199. package/dist/esm/commands/search.d.ts +26 -3
  200. package/dist/esm/commands/search.js +85 -18
  201. package/dist/esm/commands/search.js.map +1 -1
  202. package/dist/esm/commands/signals.d.ts +4 -3
  203. package/dist/esm/commands/signals.js +11 -4
  204. package/dist/esm/commands/signals.js.map +1 -1
  205. package/dist/esm/commands/snapshot.d.ts +3 -0
  206. package/dist/esm/commands/snapshot.js +25 -0
  207. package/dist/esm/commands/snapshot.js.map +1 -0
  208. package/dist/esm/embed/cohere.js +35 -10
  209. package/dist/esm/embed/cohere.js.map +1 -1
  210. package/dist/esm/embed/endpoint.d.ts +2 -0
  211. package/dist/esm/embed/endpoint.js +11 -0
  212. package/dist/esm/embed/endpoint.js.map +1 -0
  213. package/dist/esm/embed/handoff.d.ts +7 -2
  214. package/dist/esm/embed/handoff.js +7 -0
  215. package/dist/esm/embed/handoff.js.map +1 -1
  216. package/dist/esm/embed/http.d.ts +18 -1
  217. package/dist/esm/embed/http.js +137 -17
  218. package/dist/esm/embed/http.js.map +1 -1
  219. package/dist/esm/embed/openai.js +34 -12
  220. package/dist/esm/embed/openai.js.map +1 -1
  221. package/dist/esm/embed/query.d.ts +9 -3
  222. package/dist/esm/embed/query.js +98 -26
  223. package/dist/esm/embed/query.js.map +1 -1
  224. package/dist/esm/embed/registry.d.ts +2 -2
  225. package/dist/esm/embed/registry.js +34 -5
  226. package/dist/esm/embed/registry.js.map +1 -1
  227. package/dist/esm/embed/static.js +10 -2
  228. package/dist/esm/embed/static.js.map +1 -1
  229. package/dist/esm/embed/store.js +30 -21
  230. package/dist/esm/embed/store.js.map +1 -1
  231. package/dist/esm/embed/types.d.ts +5 -2
  232. package/dist/esm/embed/types.js.map +1 -1
  233. package/dist/esm/features/embed.js +82 -21
  234. package/dist/esm/features/embed.js.map +1 -1
  235. package/dist/esm/graph/traverse.d.ts +2 -2
  236. package/dist/esm/graph/traverse.js +4 -2
  237. package/dist/esm/graph/traverse.js.map +1 -1
  238. package/dist/esm/index.d.ts +2 -2
  239. package/dist/esm/index.js +1 -1
  240. package/dist/esm/index.js.map +1 -1
  241. package/dist/esm/output/output.d.ts +4 -36
  242. package/dist/esm/output/output.js +1 -2
  243. package/dist/esm/output/output.js.map +1 -1
  244. package/dist/esm/scan/pool.d.ts +2 -1
  245. package/dist/esm/scan/pool.js +80 -23
  246. package/dist/esm/scan/pool.js.map +1 -1
  247. package/dist/esm/scan/reparse.d.ts +1 -0
  248. package/dist/esm/scan/reparse.js +40 -12
  249. package/dist/esm/scan/reparse.js.map +1 -1
  250. package/dist/esm/store/builder.d.ts +11 -21
  251. package/dist/esm/store/builder.js +337 -133
  252. package/dist/esm/store/builder.js.map +1 -1
  253. package/dist/esm/store/duckdb/connection.js +9 -1
  254. package/dist/esm/store/duckdb/connection.js.map +1 -1
  255. package/dist/esm/store/duckdb/open.d.ts +1 -1
  256. package/dist/esm/store/duckdb/open.js +13 -9
  257. package/dist/esm/store/duckdb/open.js.map +1 -1
  258. package/dist/esm/store/duckdb/reconcile.js +145 -10
  259. package/dist/esm/store/duckdb/reconcile.js.map +1 -1
  260. package/dist/esm/store/embed-scope.js +16 -6
  261. package/dist/esm/store/embed-scope.js.map +1 -1
  262. package/dist/esm/store/index.d.ts +6 -0
  263. package/dist/esm/store/index.js +10 -4
  264. package/dist/esm/store/index.js.map +1 -1
  265. package/dist/esm/store/open.d.ts +6 -1
  266. package/dist/esm/store/open.js +77 -87
  267. package/dist/esm/store/open.js.map +1 -1
  268. package/dist/esm/store/readiness.d.ts +5 -0
  269. package/dist/esm/store/readiness.js +11 -0
  270. package/dist/esm/store/readiness.js.map +1 -0
  271. package/dist/esm/store/reconcile.d.ts +26 -1
  272. package/dist/esm/store/reconcile.js +142 -120
  273. package/dist/esm/store/reconcile.js.map +1 -1
  274. package/dist/esm/store/signature.d.ts +1 -0
  275. package/dist/esm/store/signature.js +8 -0
  276. package/dist/esm/store/signature.js.map +1 -1
  277. package/dist/esm/store/sqlite/open.d.ts +1 -1
  278. package/dist/esm/store/sqlite/open.js +12 -12
  279. package/dist/esm/store/sqlite/open.js.map +1 -1
  280. package/dist/esm/store/sqlite/reconcile.js +2 -2
  281. package/dist/esm/store/sqlite/reconcile.js.map +1 -1
  282. package/dist/esm/store/sqlite/store.js +21 -18
  283. package/dist/esm/store/sqlite/store.js.map +1 -1
  284. package/dist/esm/store/sqlite/vectors.d.ts +2 -2
  285. package/dist/esm/store/sqlite/vectors.js +7 -5
  286. package/dist/esm/store/sqlite/vectors.js.map +1 -1
  287. package/dist/esm/store/stages.js.map +1 -1
  288. package/dist/esm/store/turso/connection.d.ts +1 -0
  289. package/dist/esm/store/turso/connection.js +97 -28
  290. package/dist/esm/store/turso/connection.js.map +1 -1
  291. package/dist/esm/store/turso/open.d.ts +1 -1
  292. package/dist/esm/store/turso/open.js +9 -8
  293. package/dist/esm/store/turso/open.js.map +1 -1
  294. package/dist/esm/store/turso/store.js +16 -14
  295. package/dist/esm/store/turso/store.js.map +1 -1
  296. package/dist/esm/store/turso/vectors.d.ts +2 -2
  297. package/dist/esm/store/turso/vectors.js +27 -17
  298. package/dist/esm/store/turso/vectors.js.map +1 -1
  299. package/dist/esm/store/types.d.ts +4 -1
  300. package/dist/esm/store/types.js.map +1 -1
  301. package/dist/esm/store/vectors.d.ts +14 -1
  302. package/dist/esm/store/vectors.js +55 -0
  303. package/dist/esm/store/vectors.js.map +1 -1
  304. package/dist/esm/watch.d.ts +6 -0
  305. package/dist/esm/watch.js +40 -14
  306. package/dist/esm/watch.js.map +1 -1
  307. package/dist/esm/workers/parse.d.ts +4 -3
  308. package/dist/esm/workers/parse.js +19 -17
  309. package/dist/esm/workers/parse.js.map +1 -1
  310. package/package.json +1 -1
  311. package/skills/sense/SKILL.md +4 -2
  312. package/skills/sense/references/stores/duckdb.md +1 -1
  313. package/skills/sense-setup/SKILL.md +2 -2
  314. package/skills/sense-setup/references/embeddings.md +1 -1
  315. package/skills/sense-setup/references/store-benchmarks.md +5 -5
  316. package/skills/sense-setup/references/stores/duckdb.md +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/map.ts"],"sourcesContent":["import type { FeatureName, ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { featureEnabled, featureStates } from '../config/index.ts';\nimport { serialQuery } from '../lib/serial-query.ts';\nimport type { Row } from '../output/output.ts';\nimport type { FieldStat, Store } from '../store/types.ts';\nimport { INTERNAL_COLUMNS, scopedPaths, setupMapScope } from './scope.ts';\nimport type { PresetCoverage } from './status.ts';\nimport { presetCoverage } from './status.ts';\n\nexport interface TreeMap {\n docs: { count: number; bytes: number };\n fields: Row[]; // top 20 by coverage; fieldsTotal carries the real count\n fieldsTotal: number;\n features: { on: FeatureName[]; off: FeatureName[] };\n presets: PresetCoverage[];\n hubs: Row[];\n recent: Row[];\n recentCaveat: string | null;\n}\n\n// A result row is capped at SQLITE_MAX_COLUMN (2000, default); two aggregate expressions per\n// field keeps a chunk's row width safely under that regardless of how many fields the tree has.\nconst MAP_COLUMN_CHUNK = 300;\n\n// \"YYYY-MM-DD HH:MM:SS\" UTC, the exact shape sqlite's datetime(ms / 1000, 'unixepoch') prints;\n// formatted in JS so the query stays dialect-free.\nfunction utcSecond(ms: number): string {\n return new Date(ms).toISOString().slice(0, 19).replace('T', ' ');\n}\n\nfunction chunk<T>(items: T[], size: number): T[][] {\n const out: T[][] = [];\n for (let i = 0; i < items.length; i += size) out.push(items.slice(i, i + size));\n return out;\n}\n\n// What is this scope: fixed-size output regardless of tree size. Coverage and features stay\n// global -- they describe the tree, not the current question.\nexport function mapTree(store: Store, cfg: ResolvedConfig, overrides: SearchOverrides = {}): Promise<TreeMap> {\n return serialQuery(store, () => mapIndexed(store, cfg, overrides));\n}\n\nasync function mapIndexed(store: Store, cfg: ResolvedConfig, overrides: SearchOverrides): Promise<TreeMap> {\n return store.transaction(async () => {\n await setupMapScope(store, await scopedPaths(store, cfg, overrides));\n const scopeWhere = 'WHERE \"path\" IN (SELECT \"path\" FROM _map_scope)';\n const scopeAnd = 'AND f.\"path\" IN (SELECT \"path\" FROM _map_scope)';\n\n const docs = (await (await store.prepare(`SELECT COUNT(*) AS count, COALESCE(SUM(\"_size\"), 0) AS bytes FROM frontmatter ${scopeWhere}`)).get()) as { count: number; bytes: number };\n\n const columns = (await store.docs.columns()).filter((name) => !INTERNAL_COLUMNS.has(name));\n // Observed types, not declared: a field can be text in most notes and numeric in a few, so\n // every distinct type observed across the scope is reported, not just the first.\n const allFields: FieldStat[] = [];\n for (const group of chunk(columns, MAP_COLUMN_CHUNK)) allFields.push(...(await store.docs.fieldStats(group, scopeWhere)));\n allFields.sort((a, b) => b.coverage - a.coverage);\n const fields = allFields.slice(0, 20) as unknown as Row[];\n\n const hubs = featureEnabled(cfg, 'rank')\n ? ((await (await store.prepare(`SELECT f.\"path\" AS path, round(f.\"_rank\" * 100, 2) AS rank, content.title FROM frontmatter f JOIN content ON content.path = f.\"path\" WHERE f.\"_rank\" IS NOT NULL ${scopeAnd} ORDER BY f.\"_rank\" DESC, f.\"path\" ASC LIMIT 8`)).all()) as Row[])\n : [];\n\n const recent = ((await (await store.prepare(`SELECT \"path\", \"_mtime\" AS mtime FROM frontmatter ${scopeWhere} ORDER BY \"_mtime\" DESC, \"path\" ASC LIMIT 5`)).all()) as Array<{ path: string; mtime: number }>).map((r) => ({ path: r.path, modified: utcSecond(r.mtime) }));\n\n // A fresh clone/copy stamps files with checkout time, not edit history; second granularity\n // matches the `recent` table above and is coarse enough to catch that without an exact-ms match.\n const topSecond = (await (await store.prepare(`SELECT COUNT(*) AS n FROM frontmatter ${scopeWhere} GROUP BY CAST(\"_mtime\" / 1000 AS INTEGER) ORDER BY n DESC LIMIT 1`)).get()) as { n: number } | undefined;\n const recentCaveat = topSecond && docs.count > 1 && topSecond.n > docs.count / 2 ? `${topSecond.n} of ${docs.count} files share one modified second, so recency likely reflects a checkout or copy, not edit history` : null;\n\n return { docs, fields, fieldsTotal: allFields.length, features: featureStates(cfg), presets: await presetCoverage(store, cfg), hubs, recent, recentCaveat };\n });\n}\n"],"names":["mapTree","MAP_COLUMN_CHUNK","utcSecond","ms","Date","toISOString","slice","replace","chunk","items","size","out","i","length","push","store","cfg","overrides","serialQuery","mapIndexed","transaction","allFields","scopeWhere","scopeAnd","docs","columns","group","fields","hubs","recent","topSecond","recentCaveat","scopedPaths","setupMapScope","prepare","get","filter","name","INTERNAL_COLUMNS","has","fieldStats","sort","a","b","coverage","featureEnabled","all","map","r","path","modified","mtime","count","n","fieldsTotal","features","featureStates","presetCoverage","presets"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/map.ts"],"sourcesContent":["import type { FeatureName, ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { featureEnabled, featureStates } from '../config/index.ts';\nimport { serialQuery } from '../lib/serial-query.ts';\nimport type { FieldStat, Store } from '../store/types.ts';\nimport { INTERNAL_COLUMNS, scopedPaths, setupMapScope } from './scope.ts';\nimport { assertQuerySnapshot } from './snapshot.ts';\nimport type { PresetCoverage } from './status.ts';\nimport { presetCoverage } from './status.ts';\n\nexport interface TreeMap {\n docs: { count: number; bytes: number };\n fields: TreeMapField[]; // top 20 by coverage; fieldsTotal carries the real count\n fieldsTotal: number;\n features: { on: FeatureName[]; off: FeatureName[] };\n presets: PresetCoverage[];\n hubs: TreeMapHub[];\n recent: TreeMapRecent[];\n recentCaveat: string | null;\n}\n\nexport type TreeMapField = FieldStat;\n\nexport type TreeMapHub = {\n path: string;\n rank: number;\n title: string;\n};\n\nexport type TreeMapRecent = {\n path: string;\n modified: string;\n};\n\n// A result row is capped at SQLITE_MAX_COLUMN (2000, default); two aggregate expressions per\n// field keeps a chunk's row width safely under that regardless of how many fields the tree has.\nconst MAP_COLUMN_CHUNK = 300;\n\n// \"YYYY-MM-DD HH:MM:SS\" UTC, the exact shape sqlite's datetime(ms / 1000, 'unixepoch') prints;\n// formatted in JS so the query stays dialect-free.\nfunction utcSecond(ms: number): string {\n return new Date(ms).toISOString().slice(0, 19).replace('T', ' ');\n}\n\nfunction chunk<T>(items: T[], size: number): T[][] {\n const out: T[][] = [];\n for (let i = 0; i < items.length; i += size) out.push(items.slice(i, i + size));\n return out;\n}\n\n// What is this scope: fixed-size output regardless of tree size. Coverage and features stay\n// global -- they describe the tree, not the current question.\nexport function mapTree(store: Store, cfg: ResolvedConfig, overrides: SearchOverrides = {}): Promise<TreeMap> {\n return serialQuery(store, () => mapIndexed(store, cfg, overrides));\n}\n\nasync function mapIndexed(store: Store, cfg: ResolvedConfig, overrides: SearchOverrides): Promise<TreeMap> {\n return store.transaction(async () => {\n await assertQuerySnapshot(store, cfg);\n await setupMapScope(store, await scopedPaths(store, cfg, overrides));\n const scopeWhere = 'WHERE \"path\" IN (SELECT \"path\" FROM _map_scope)';\n const scopeAnd = 'AND f.\"path\" IN (SELECT \"path\" FROM _map_scope)';\n\n const docs = (await (await store.prepare(`SELECT COUNT(*) AS count, COALESCE(SUM(\"_size\"), 0) AS bytes FROM frontmatter ${scopeWhere}`)).get()) as { count: number; bytes: number };\n\n const columns = (await store.docs.columns()).filter((name) => !INTERNAL_COLUMNS.has(name));\n // Observed types, not declared: a field can be text in most notes and numeric in a few, so\n // every distinct type observed across the scope is reported, not just the first.\n const allFields: FieldStat[] = [];\n for (const group of chunk(columns, MAP_COLUMN_CHUNK)) allFields.push(...(await store.docs.fieldStats(group, scopeWhere)));\n allFields.sort((a, b) => b.coverage - a.coverage);\n const fields = allFields.slice(0, 20);\n\n const hubs = featureEnabled(cfg, 'rank')\n ? ((await (await store.prepare(`SELECT f.\"path\" AS path, round(f.\"_rank\" * 100, 2) AS rank, content.title FROM frontmatter f JOIN content ON content.path = f.\"path\" WHERE f.\"_rank\" IS NOT NULL ${scopeAnd} ORDER BY f.\"_rank\" DESC, f.\"path\" ASC LIMIT 8`)).all()) as TreeMapHub[])\n : [];\n\n const recent = ((await (await store.prepare(`SELECT \"path\", \"_mtime\" AS mtime FROM frontmatter ${scopeWhere} ORDER BY \"_mtime\" DESC, \"path\" ASC LIMIT 5`)).all()) as Array<{ path: string; mtime: number }>).map((r) => ({ path: r.path, modified: utcSecond(r.mtime) }));\n\n // A fresh clone/copy stamps files with checkout time, not edit history; second granularity\n // matches the `recent` table above and is coarse enough to catch that without an exact-ms match.\n const topSecond = (await (await store.prepare(`SELECT COUNT(*) AS n FROM frontmatter ${scopeWhere} GROUP BY CAST(\"_mtime\" / 1000 AS INTEGER) ORDER BY n DESC LIMIT 1`)).get()) as { n: number } | undefined;\n const recentCaveat = topSecond && docs.count > 1 && topSecond.n > docs.count / 2 ? `${topSecond.n} of ${docs.count} files share one modified second, so recency likely reflects a checkout or copy, not edit history` : null;\n\n return { docs, fields, fieldsTotal: allFields.length, features: featureStates(cfg), presets: await presetCoverage(store, cfg), hubs, recent, recentCaveat };\n });\n}\n"],"names":["mapTree","MAP_COLUMN_CHUNK","utcSecond","ms","Date","toISOString","slice","replace","chunk","items","size","out","i","length","push","store","cfg","overrides","serialQuery","mapIndexed","transaction","allFields","scopeWhere","scopeAnd","docs","columns","group","fields","hubs","recent","topSecond","recentCaveat","assertQuerySnapshot","scopedPaths","setupMapScope","prepare","get","filter","name","INTERNAL_COLUMNS","has","fieldStats","sort","a","b","coverage","featureEnabled","all","map","r","path","modified","mtime","count","n","fieldsTotal","features","featureStates","presetCoverage","presets"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { ResolvedConfig, SearchOverrides } from '../config/index.js';
2
+ import type { Store } from '../store/types.js';
3
+ /**
4
+ * Options for {@link findPath}. Scope fields constrain intermediate nodes; `maxDepth` limits the
5
+ * number of traversed links and must be a positive integer when supplied.
6
+ */
7
+ export type PathOptions = Omit<SearchOverrides, 'k'> & {
8
+ maxDepth?: number;
9
+ };
10
+ /**
11
+ * Finds the shortest undirected link path between two indexed notes. Endpoints resolve across
12
+ * the indexed tree and remain permitted outside the scope applied to intermediate nodes.
13
+ */
14
+ export declare function findPath(store: Store, cfg: ResolvedConfig, fromArg: string, toArg: string, options?: PathOptions): Promise<string[] | null>;
@@ -0,0 +1,14 @@
1
+ import type { ResolvedConfig, SearchOverrides } from '../config/index.js';
2
+ import type { Store } from '../store/types.js';
3
+ /**
4
+ * Options for {@link findPath}. Scope fields constrain intermediate nodes; `maxDepth` limits the
5
+ * number of traversed links and must be a positive integer when supplied.
6
+ */
7
+ export type PathOptions = Omit<SearchOverrides, 'k'> & {
8
+ maxDepth?: number;
9
+ };
10
+ /**
11
+ * Finds the shortest undirected link path between two indexed notes. Endpoints resolve across
12
+ * the indexed tree and remain permitted outside the scope applied to intermediate nodes.
13
+ */
14
+ export declare function findPath(store: Store, cfg: ResolvedConfig, fromArg: string, toArg: string, options?: PathOptions): Promise<string[] | null>;
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "findPath", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return findPath;
9
+ }
10
+ });
11
+ var _indexts = require("../config/index.js");
12
+ var _errorsts = require("../errors.js");
13
+ var _traversets = require("../graph/traverse.js");
14
+ var _serialqueryts = require("../lib/serial-query.js");
15
+ var _peekts = require("./peek.js");
16
+ var _scopets = require("./scope.js");
17
+ var _snapshotts = require("./snapshot.js");
18
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
19
+ try {
20
+ var info = gen[key](arg);
21
+ var value = info.value;
22
+ } catch (error) {
23
+ reject(error);
24
+ return;
25
+ }
26
+ if (info.done) resolve(value);
27
+ else Promise.resolve(value).then(_next, _throw);
28
+ }
29
+ function _async_to_generator(fn) {
30
+ return function() {
31
+ var self = this, args = arguments;
32
+ return new Promise(function(resolve, reject) {
33
+ var gen = fn.apply(self, args);
34
+ function _next(value) {
35
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
36
+ }
37
+ function _throw(err) {
38
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
39
+ }
40
+ _next(undefined);
41
+ });
42
+ };
43
+ }
44
+ function _ts_generator(thisArg, body) {
45
+ var f, y, t, _ = {
46
+ label: 0,
47
+ sent: function() {
48
+ if (t[0] & 1) throw t[1];
49
+ return t[1];
50
+ },
51
+ trys: [],
52
+ ops: []
53
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
54
+ return d(g, "next", {
55
+ value: verb(0)
56
+ }), d(g, "throw", {
57
+ value: verb(1)
58
+ }), d(g, "return", {
59
+ value: verb(2)
60
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
61
+ value: function() {
62
+ return this;
63
+ }
64
+ }), g;
65
+ function verb(n) {
66
+ return function(v) {
67
+ return step([
68
+ n,
69
+ v
70
+ ]);
71
+ };
72
+ }
73
+ function step(op) {
74
+ if (f) throw new TypeError("Generator is already executing.");
75
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
76
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
77
+ if (y = 0, t) op = [
78
+ op[0] & 2,
79
+ t.value
80
+ ];
81
+ switch(op[0]){
82
+ case 0:
83
+ case 1:
84
+ t = op;
85
+ break;
86
+ case 4:
87
+ _.label++;
88
+ return {
89
+ value: op[1],
90
+ done: false
91
+ };
92
+ case 5:
93
+ _.label++;
94
+ y = op[1];
95
+ op = [
96
+ 0
97
+ ];
98
+ continue;
99
+ case 7:
100
+ op = _.ops.pop();
101
+ _.trys.pop();
102
+ continue;
103
+ default:
104
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
105
+ _ = 0;
106
+ continue;
107
+ }
108
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
109
+ _.label = op[1];
110
+ break;
111
+ }
112
+ if (op[0] === 6 && _.label < t[1]) {
113
+ _.label = t[1];
114
+ t = op;
115
+ break;
116
+ }
117
+ if (t && _.label < t[2]) {
118
+ _.label = t[2];
119
+ _.ops.push(op);
120
+ break;
121
+ }
122
+ if (t[2]) _.ops.pop();
123
+ _.trys.pop();
124
+ continue;
125
+ }
126
+ op = body.call(thisArg, _);
127
+ } catch (e) {
128
+ op = [
129
+ 6,
130
+ e
131
+ ];
132
+ y = 0;
133
+ } finally{
134
+ f = t = 0;
135
+ }
136
+ if (op[0] & 5) throw op[1];
137
+ return {
138
+ value: op[0] ? op[1] : void 0,
139
+ done: true
140
+ };
141
+ }
142
+ }
143
+ function findPath(store, cfg, fromArg, toArg) {
144
+ var options = arguments.length > 4 && arguments[4] !== void 0 ? arguments[4] : {};
145
+ return (0, _serialqueryts.serialQuery)(store, function() {
146
+ return findScopedPath(store, cfg, fromArg, toArg, options);
147
+ });
148
+ }
149
+ function findScopedPath(store, cfg, fromArg, toArg, options) {
150
+ return _async_to_generator(function() {
151
+ return _ts_generator(this, function(_state) {
152
+ if (options.maxDepth !== undefined && (!Number.isFinite(options.maxDepth) || !Number.isInteger(options.maxDepth) || options.maxDepth <= 0)) {
153
+ throw new _errorsts.SenseError('SEARCH_OPTION_INVALID', 'path option "maxDepth" must be a positive finite integer, got '.concat(String(options.maxDepth)));
154
+ }
155
+ // Validate the named preset before opening the snapshot; repeat it inside because preset_files
156
+ // and the compatibility assertion below belong to the final published generation.
157
+ (0, _indexts.resolveSearch)(cfg, options);
158
+ return [
159
+ 2,
160
+ store.transaction(function() {
161
+ return _async_to_generator(function() {
162
+ var paths, from, to, allowed;
163
+ return _ts_generator(this, function(_state) {
164
+ switch(_state.label){
165
+ case 0:
166
+ return [
167
+ 4,
168
+ (0, _snapshotts.assertQuerySnapshot)(store, cfg)
169
+ ];
170
+ case 1:
171
+ _state.sent();
172
+ (0, _indexts.resolveSearch)(cfg, options);
173
+ return [
174
+ 4,
175
+ store.prepare('SELECT "path" FROM frontmatter')
176
+ ];
177
+ case 2:
178
+ return [
179
+ 4,
180
+ _state.sent().all()
181
+ ];
182
+ case 3:
183
+ paths = _state.sent().map(function(row) {
184
+ return row.path;
185
+ });
186
+ from = (0, _peekts.resolveNote)(paths, fromArg);
187
+ to = (0, _peekts.resolveNote)(paths, toArg);
188
+ return [
189
+ 4,
190
+ (0, _scopets.scopedPaths)(store, cfg, options)
191
+ ];
192
+ case 4:
193
+ allowed = _state.sent();
194
+ return [
195
+ 2,
196
+ (0, _traversets.findPathInSnapshot)(store, from, to, {
197
+ maxDepth: options.maxDepth,
198
+ allowed: allowed
199
+ })
200
+ ];
201
+ }
202
+ });
203
+ })();
204
+ })
205
+ ];
206
+ });
207
+ })();
208
+ }
209
+ /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/path.ts"],"sourcesContent":["import type { ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { resolveSearch } from '../config/index.ts';\nimport { SenseError } from '../errors.ts';\nimport { findPathInSnapshot } from '../graph/traverse.ts';\nimport { serialQuery } from '../lib/serial-query.ts';\nimport type { Store } from '../store/types.ts';\nimport { resolveNote } from './peek.ts';\nimport { scopedPaths } from './scope.ts';\nimport { assertQuerySnapshot } from './snapshot.ts';\n\n/**\n * Options for {@link findPath}. Scope fields constrain intermediate nodes; `maxDepth` limits the\n * number of traversed links and must be a positive integer when supplied.\n */\nexport type PathOptions = Omit<SearchOverrides, 'k'> & {\n maxDepth?: number;\n};\n\n/**\n * Finds the shortest undirected link path between two indexed notes. Endpoints resolve across\n * the indexed tree and remain permitted outside the scope applied to intermediate nodes.\n */\nexport function findPath(store: Store, cfg: ResolvedConfig, fromArg: string, toArg: string, options: PathOptions = {}): Promise<string[] | null> {\n return serialQuery(store, () => findScopedPath(store, cfg, fromArg, toArg, options));\n}\n\nasync function findScopedPath(store: Store, cfg: ResolvedConfig, fromArg: string, toArg: string, options: PathOptions): Promise<string[] | null> {\n if (options.maxDepth !== undefined && (!Number.isFinite(options.maxDepth) || !Number.isInteger(options.maxDepth) || options.maxDepth <= 0)) {\n throw new SenseError('SEARCH_OPTION_INVALID', `path option \"maxDepth\" must be a positive finite integer, got ${String(options.maxDepth)}`);\n }\n // Validate the named preset before opening the snapshot; repeat it inside because preset_files\n // and the compatibility assertion below belong to the final published generation.\n resolveSearch(cfg, options);\n return store.transaction(async () => {\n await assertQuerySnapshot(store, cfg);\n resolveSearch(cfg, options);\n const paths = ((await (await store.prepare('SELECT \"path\" FROM frontmatter')).all()) as Array<{ path: string }>).map((row) => row.path);\n const from = resolveNote(paths, fromArg);\n const to = resolveNote(paths, toArg);\n const allowed = await scopedPaths(store, cfg, options);\n return findPathInSnapshot(store, from, to, { maxDepth: options.maxDepth, allowed });\n });\n}\n"],"names":["findPath","store","cfg","fromArg","toArg","options","serialQuery","findScopedPath","maxDepth","undefined","Number","isFinite","isInteger","SenseError","String","resolveSearch","transaction","paths","from","to","allowed","assertQuerySnapshot","prepare","all","map","row","path","resolveNote","scopedPaths","findPathInSnapshot"],"mappings":";;;;+BAsBgBA;;;eAAAA;;;uBArBc;wBACH;0BACQ;6BACP;sBAEA;uBACA;0BACQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAc7B,SAASA,SAASC,KAAY,EAAEC,GAAmB,EAAEC,OAAe,EAAEC,KAAa;QAAEC,UAAAA,iEAAuB,CAAC;IAClH,OAAOC,IAAAA,0BAAW,EAACL,OAAO;eAAMM,eAAeN,OAAOC,KAAKC,SAASC,OAAOC;;AAC7E;AAEA,SAAeE,eAAeN,KAAY,EAAEC,GAAmB,EAAEC,OAAe,EAAEC,KAAa,EAAEC,OAAoB;;;YACnH,IAAIA,QAAQG,QAAQ,KAAKC,aAAc,CAAA,CAACC,OAAOC,QAAQ,CAACN,QAAQG,QAAQ,KAAK,CAACE,OAAOE,SAAS,CAACP,QAAQG,QAAQ,KAAKH,QAAQG,QAAQ,IAAI,CAAA,GAAI;gBAC1I,MAAM,IAAIK,oBAAU,CAAC,yBAAyB,AAAC,iEAAyF,OAAzBC,OAAOT,QAAQG,QAAQ;YACxI;YACA,+FAA+F;YAC/F,kFAAkF;YAClFO,IAAAA,sBAAa,EAACb,KAAKG;YACnB;;gBAAOJ,MAAMe,WAAW,CAAC;;4BAGjBC,OACAC,MACAC,IACAC;;;;oCALN;;wCAAMC,IAAAA,+BAAmB,EAACpB,OAAOC;;;oCAAjC;oCACAa,IAAAA,sBAAa,EAACb,KAAKG;oCACI;;wCAAMJ,MAAMqB,OAAO,CAAC;;;oCAA3B;;wCAAO,cAAuDC,GAAG;;;oCAA3EN,QAAQ,AAAE,cAAiGO,GAAG,CAAC,SAACC;+CAAQA,IAAIC,IAAI;;oCAChIR,OAAOS,IAAAA,mBAAW,EAACV,OAAOd;oCAC1BgB,KAAKQ,IAAAA,mBAAW,EAACV,OAAOb;oCACd;;wCAAMwB,IAAAA,oBAAW,EAAC3B,OAAOC,KAAKG;;;oCAAxCe,UAAU;oCAChB;;wCAAOS,IAAAA,8BAAkB,EAAC5B,OAAOiB,MAAMC,IAAI;4CAAEX,UAAUH,QAAQG,QAAQ;4CAAEY,SAAAA;wCAAQ;;;;oBACnF;;;;IACF"}
@@ -2,19 +2,34 @@ import type { FeatureName, ResolvedConfig, SearchOverrides } from '../config/ind
2
2
  import type { Row } from '../output/output.js';
3
3
  import type { Store } from '../store/types.js';
4
4
  export declare function resolveNote(paths: string[], arg: string): string;
5
+ /** Structured, bounded metadata returned by the root {@link peek} API. */
5
6
  export interface Peek {
6
7
  path: string;
7
8
  tokens: number;
8
9
  frontmatter: Row;
10
+ /** Set when frontmatter parsing failed, distinguishing that case from an empty block. */
9
11
  parseError: string | null;
10
- sections: Row[];
12
+ sections: PeekSection[];
11
13
  outbound: string[];
12
14
  backlinks: string[];
13
15
  unresolved: string[];
16
+ /** Totals before each bounded list is truncated. */
14
17
  sectionsTotal: number;
15
18
  outboundTotal: number;
16
19
  backlinksTotal: number;
17
20
  unresolvedTotal: number;
21
+ /** Disabled features whose result blocks are omitted rather than returned empty. */
18
22
  off: FeatureName[];
19
23
  }
24
+ export interface PeekSection {
25
+ level: number;
26
+ heading: string;
27
+ start_line: number;
28
+ end_line: number;
29
+ tokens: number;
30
+ }
31
+ /**
32
+ * Returns indexed metadata for a note in scope. Exact excluded paths fail before scoped basename
33
+ * resolution; resolved neighbors stay in scope, while unresolved written targets remain visible.
34
+ */
20
35
  export declare function peek(store: Store, cfg: ResolvedConfig, pathArg: string, overrides?: SearchOverrides): Promise<Peek>;
@@ -2,19 +2,34 @@ import type { FeatureName, ResolvedConfig, SearchOverrides } from '../config/ind
2
2
  import type { Row } from '../output/output.js';
3
3
  import type { Store } from '../store/types.js';
4
4
  export declare function resolveNote(paths: string[], arg: string): string;
5
+ /** Structured, bounded metadata returned by the root {@link peek} API. */
5
6
  export interface Peek {
6
7
  path: string;
7
8
  tokens: number;
8
9
  frontmatter: Row;
10
+ /** Set when frontmatter parsing failed, distinguishing that case from an empty block. */
9
11
  parseError: string | null;
10
- sections: Row[];
12
+ sections: PeekSection[];
11
13
  outbound: string[];
12
14
  backlinks: string[];
13
15
  unresolved: string[];
16
+ /** Totals before each bounded list is truncated. */
14
17
  sectionsTotal: number;
15
18
  outboundTotal: number;
16
19
  backlinksTotal: number;
17
20
  unresolvedTotal: number;
21
+ /** Disabled features whose result blocks are omitted rather than returned empty. */
18
22
  off: FeatureName[];
19
23
  }
24
+ export interface PeekSection {
25
+ level: number;
26
+ heading: string;
27
+ start_line: number;
28
+ end_line: number;
29
+ tokens: number;
30
+ }
31
+ /**
32
+ * Returns indexed metadata for a note in scope. Exact excluded paths fail before scoped basename
33
+ * resolution; resolved neighbors stay in scope, while unresolved written targets remain visible.
34
+ */
20
35
  export declare function peek(store: Store, cfg: ResolvedConfig, pathArg: string, overrides?: SearchOverrides): Promise<Peek>;
@@ -22,6 +22,7 @@ var _indexts1 = require("../config/index.js");
22
22
  var _errorsts = require("../errors.js");
23
23
  var _serialqueryts = require("../lib/serial-query.js");
24
24
  var _scopets = require("./scope.js");
25
+ var _snapshotts = require("./snapshot.js");
25
26
  function _array_like_to_array(arr, len) {
26
27
  if (len == null || len > arr.length) len = arr.length;
27
28
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
@@ -59,6 +60,12 @@ function _async_to_generator(fn) {
59
60
  });
60
61
  };
61
62
  }
63
+ function _instanceof(left, right) {
64
+ "@swc/helpers - instanceof";
65
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
66
+ return !!right[Symbol.hasInstance](left);
67
+ } else return left instanceof right;
68
+ }
62
69
  function _interop_require_default(obj) {
63
70
  return obj && obj.__esModule ? obj : {
64
71
  default: obj
@@ -239,36 +246,67 @@ function peekIndexed(store, cfg, pathArg, overrides) {
239
246
  2,
240
247
  store.transaction(function() {
241
248
  return _async_to_generator(function() {
242
- var _row__parse_error, _row__size, _this, pathsStmt, paths, path, rowStmt, row, parseError, frontmatter, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _step_value, key, value, sectionsTotal, sections, outbound, backlinks, unresolved, backlinksTotal, out, body, byteTokens, tokens;
249
+ var _row__parse_error, _row__size, _this, pathsStmt, paths, allowed, path, excludedPath, rowStmt, row, parseError, frontmatter, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _step_value, key, value, sectionsTotal, sections, outbound, backlinks, unresolved, backlinksTotal, out, body, byteTokens, tokens;
243
250
  return _ts_generator(this, function(_state) {
244
251
  switch(_state.label){
245
252
  case 0:
246
253
  return [
247
254
  4,
248
- store.prepare('SELECT "path" FROM frontmatter')
255
+ (0, _snapshotts.assertQuerySnapshot)(store, cfg)
249
256
  ];
250
257
  case 1:
258
+ _state.sent();
259
+ return [
260
+ 4,
261
+ store.prepare('SELECT "path" FROM frontmatter')
262
+ ];
263
+ case 2:
251
264
  pathsStmt = _state.sent();
252
265
  return [
253
266
  4,
254
267
  pathsStmt.all()
255
268
  ];
256
- case 2:
269
+ case 3:
257
270
  paths = _state.sent().map(function(r) {
258
271
  return r.path;
259
272
  });
260
- path = resolveNote(paths, pathArg);
273
+ return [
274
+ 4,
275
+ (0, _scopets.scopedPaths)(store, cfg, overrides)
276
+ ];
277
+ case 4:
278
+ allowed = _state.sent();
279
+ if (paths.includes(pathArg) && !allowed.has(pathArg)) {
280
+ throw new _errorsts.SenseError('NOTE_NOT_FOUND', 'note "'.concat(pathArg, '" exists but is outside the current scope; change the preset, include/exclude patterns, or where condition'));
281
+ }
282
+ try {
283
+ path = resolveNote(_to_consumable_array(allowed), pathArg);
284
+ } catch (err) {
285
+ if (_instanceof(err, _errorsts.SenseError) && err.code === 'NOTE_NOT_FOUND') {
286
+ ;
287
+ try {
288
+ excludedPath = resolveNote(paths, pathArg);
289
+ } catch (unscopedErr) {
290
+ if (_instanceof(unscopedErr, _errorsts.SenseError) && unscopedErr.code === 'NOTE_AMBIGUOUS') {
291
+ throw new _errorsts.SenseError('NOTE_NOT_FOUND', 'no note in the current scope matches "'.concat(pathArg, '"; indexed matches exist outside the scope, so change the preset, include/exclude patterns, or where condition'));
292
+ }
293
+ throw err;
294
+ }
295
+ throw new _errorsts.SenseError('NOTE_NOT_FOUND', 'note "'.concat(excludedPath, '" exists but is outside the current scope; change the preset, include/exclude patterns, or where condition'));
296
+ }
297
+ throw err;
298
+ }
261
299
  return [
262
300
  4,
263
301
  store.prepare('SELECT * FROM frontmatter WHERE "path" = ?')
264
302
  ];
265
- case 3:
303
+ case 5:
266
304
  rowStmt = _state.sent();
267
305
  return [
268
306
  4,
269
307
  rowStmt.get(path)
270
308
  ];
271
- case 4:
309
+ case 6:
272
310
  row = _state.sent();
273
311
  parseError = (_row__parse_error = row._parse_error) !== null && _row__parse_error !== void 0 ? _row__parse_error : null;
274
312
  frontmatter = {};
@@ -296,56 +334,56 @@ function peekIndexed(store, cfg, pathArg, overrides) {
296
334
  sections = [];
297
335
  if (!(0, _indexts1.featureEnabled)(cfg, 'sections')) return [
298
336
  3,
299
- 9
337
+ 11
300
338
  ];
301
339
  return [
302
340
  4,
303
341
  store.prepare('SELECT COUNT(*) AS n FROM sections WHERE "path" = ?')
304
342
  ];
305
- case 5:
343
+ case 7:
306
344
  return [
307
345
  4,
308
346
  _state.sent().get(path)
309
347
  ];
310
- case 6:
348
+ case 8:
311
349
  sectionsTotal = _state.sent().n;
312
350
  return [
313
351
  4,
314
352
  store.prepare('SELECT level, heading, start_line, end_line, tokens FROM sections WHERE "path" = ? ORDER BY idx LIMIT ?')
315
353
  ];
316
- case 7:
354
+ case 9:
317
355
  return [
318
356
  4,
319
357
  _state.sent().all(path, PEEK_LIST_LIMIT)
320
358
  ];
321
- case 8:
359
+ case 10:
322
360
  sections = _state.sent();
323
- _state.label = 9;
324
- case 9:
361
+ _state.label = 11;
362
+ case 11:
325
363
  outbound = [];
326
364
  backlinks = [];
327
365
  unresolved = [];
328
366
  backlinksTotal = 0;
329
- return [
330
- 4,
331
- (0, _scopets.scopedPaths)(store, cfg, overrides)
332
- ];
333
- case 10:
334
- _state.sent(); // validates --preset/--where/--include/--exclude even though peek's own output isn't scope-filtered
335
367
  if (!(0, _indexts1.featureEnabled)(cfg, 'links')) return [
336
368
  3,
337
- 17
369
+ 19
338
370
  ];
339
371
  return [
340
372
  4,
341
- store.prepare('SELECT target, dst FROM links WHERE src = ? AND (dst IS NULL OR dst != src) ORDER BY target')
373
+ (0, _scopets.materializeScope)(store, '_peek_scope', allowed)
342
374
  ];
343
- case 11:
375
+ case 12:
376
+ _state.sent();
377
+ return [
378
+ 4,
379
+ store.prepare('SELECT target, dst FROM links WHERE src = ? AND (dst IS NULL OR (dst != src AND dst IN (SELECT "path" FROM _peek_scope))) ORDER BY target')
380
+ ];
381
+ case 13:
344
382
  return [
345
383
  4,
346
384
  _state.sent().all(path)
347
385
  ];
348
- case 12:
386
+ case 14:
349
387
  out = _state.sent();
350
388
  outbound = _to_consumable_array(new Set(out.filter(function(l) {
351
389
  return l.dst !== null;
@@ -359,40 +397,40 @@ function peekIndexed(store, cfg, pathArg, overrides) {
359
397
  });
360
398
  return [
361
399
  4,
362
- store.prepare('SELECT COUNT(DISTINCT src) AS n FROM links WHERE dst = ? AND src != dst')
400
+ store.prepare('SELECT COUNT(DISTINCT src) AS n FROM links WHERE dst = ? AND src != dst AND src IN (SELECT "path" FROM _peek_scope)')
363
401
  ];
364
- case 13:
402
+ case 15:
365
403
  return [
366
404
  4,
367
405
  _state.sent().get(path)
368
406
  ];
369
- case 14:
407
+ case 16:
370
408
  backlinksTotal = _state.sent().n;
371
409
  return [
372
410
  4,
373
- store.prepare('SELECT DISTINCT src FROM links WHERE dst = ? AND src != dst ORDER BY src LIMIT ?')
411
+ store.prepare('SELECT DISTINCT src FROM links WHERE dst = ? AND src != dst AND src IN (SELECT "path" FROM _peek_scope) ORDER BY src LIMIT ?')
374
412
  ];
375
- case 15:
413
+ case 17:
376
414
  return [
377
415
  4,
378
416
  _state.sent().all(path, PEEK_LIST_LIMIT)
379
417
  ];
380
- case 16:
418
+ case 18:
381
419
  backlinks = _state.sent().map(function(r) {
382
420
  return r.src;
383
421
  });
384
- _state.label = 17;
385
- case 17:
422
+ _state.label = 19;
423
+ case 19:
386
424
  return [
387
425
  4,
388
426
  store.prepare('SELECT text FROM content WHERE "path" = ?')
389
427
  ];
390
- case 18:
428
+ case 20:
391
429
  return [
392
430
  4,
393
431
  _state.sent().get(path)
394
432
  ];
395
- case 19:
433
+ case 21:
396
434
  body = (_this = _state.sent()) === null || _this === void 0 ? void 0 : _this.text;
397
435
  byteTokens = Math.ceil(((_row__size = row._size) !== null && _row__size !== void 0 ? _row__size : 0) / 4);
398
436
  tokens = body !== undefined ? Math.max(Math.ceil((0, _indexts.estimateTokens)(body)), byteTokens) : byteTokens;