sensemaking 0.7.2 → 0.9.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 (207) hide show
  1. package/README.md +90 -61
  2. package/dist/cjs/cli/check.js +367 -0
  3. package/dist/cjs/cli/check.js.map +1 -0
  4. package/dist/cjs/{commands → cli}/index.js +2 -2
  5. package/dist/cjs/cli/index.js.map +1 -0
  6. package/dist/cjs/{commands → cli}/init.js +3 -0
  7. package/dist/cjs/cli/init.js.map +1 -0
  8. package/dist/cjs/{commands → cli}/map.js +2 -2
  9. package/dist/cjs/cli/map.js.map +1 -0
  10. package/dist/cjs/{commands → cli}/named.d.cts +1 -1
  11. package/dist/cjs/{commands → cli}/named.d.ts +1 -1
  12. package/dist/cjs/cli/named.js +219 -0
  13. package/dist/cjs/cli/named.js.map +1 -0
  14. package/dist/cjs/{commands → cli}/peek.js +2 -2
  15. package/dist/cjs/cli/peek.js.map +1 -0
  16. package/dist/cjs/cli/query.js.map +1 -0
  17. package/dist/cjs/cli/rebuild.js.map +1 -0
  18. package/dist/cjs/cli/search.d.cts +3 -0
  19. package/dist/cjs/cli/search.d.ts +3 -0
  20. package/dist/cjs/{commands/find.js → cli/search.js} +9 -8
  21. package/dist/cjs/cli/search.js.map +1 -0
  22. package/dist/cjs/{commands → cli}/shared.d.cts +1 -0
  23. package/dist/{esm/commands → cjs/cli}/shared.d.ts +1 -0
  24. package/dist/cjs/{commands → cli}/shared.js +9 -0
  25. package/dist/cjs/cli/shared.js.map +1 -0
  26. package/dist/cjs/{commands → cli}/status.js +36 -13
  27. package/dist/cjs/cli/status.js.map +1 -0
  28. package/dist/cjs/{commands → cli}/types.d.cts +3 -1
  29. package/dist/{esm/commands → cjs/cli}/types.d.ts +3 -1
  30. package/dist/cjs/cli/watch.js.map +1 -0
  31. package/dist/cjs/cli.js +42 -17
  32. package/dist/cjs/cli.js.map +1 -1
  33. package/dist/{esm/verbs.d.ts → cjs/commands.d.cts} +15 -5
  34. package/dist/cjs/{verbs.d.cts → commands.d.ts} +15 -5
  35. package/dist/cjs/{verbs.js → commands.js} +329 -39
  36. package/dist/cjs/commands.js.map +1 -0
  37. package/dist/cjs/config.d.cts +45 -12
  38. package/dist/cjs/config.d.ts +45 -12
  39. package/dist/cjs/config.js +464 -125
  40. package/dist/cjs/config.js.map +1 -1
  41. package/dist/cjs/db.d.cts +1 -1
  42. package/dist/cjs/db.d.ts +1 -1
  43. package/dist/cjs/db.js +293 -76
  44. package/dist/cjs/db.js.map +1 -1
  45. package/dist/cjs/errors.d.cts +1 -1
  46. package/dist/cjs/errors.d.ts +1 -1
  47. package/dist/cjs/errors.js.map +1 -1
  48. package/dist/cjs/features/embed.js +19 -3
  49. package/dist/cjs/features/embed.js.map +1 -1
  50. package/dist/cjs/features/links.js +201 -24
  51. package/dist/cjs/features/links.js.map +1 -1
  52. package/dist/cjs/features/rank.js +8 -1
  53. package/dist/cjs/features/rank.js.map +1 -1
  54. package/dist/cjs/features/types.d.cts +12 -4
  55. package/dist/cjs/features/types.d.ts +12 -4
  56. package/dist/cjs/index.d.cts +3 -3
  57. package/dist/cjs/index.d.ts +3 -3
  58. package/dist/cjs/index.js +9 -6
  59. package/dist/cjs/index.js.map +1 -1
  60. package/dist/cjs/output.d.cts +16 -0
  61. package/dist/cjs/output.d.ts +16 -0
  62. package/dist/cjs/output.js +27 -5
  63. package/dist/cjs/output.js.map +1 -1
  64. package/dist/cjs/progress.d.cts +5 -0
  65. package/dist/cjs/progress.d.ts +5 -0
  66. package/dist/cjs/progress.js +54 -0
  67. package/dist/cjs/progress.js.map +1 -0
  68. package/dist/cjs/scan.d.cts +4 -0
  69. package/dist/cjs/scan.d.ts +4 -0
  70. package/dist/cjs/scan.js +87 -6
  71. package/dist/cjs/scan.js.map +1 -1
  72. package/dist/esm/{commands → cli}/check.js +41 -22
  73. package/dist/esm/cli/check.js.map +1 -0
  74. package/dist/esm/{commands → cli}/index.js +1 -1
  75. package/dist/esm/cli/index.js.map +1 -0
  76. package/dist/esm/{commands → cli}/init.js +3 -0
  77. package/dist/esm/cli/init.js.map +1 -0
  78. package/dist/esm/{commands → cli}/map.js +1 -1
  79. package/dist/esm/cli/map.js.map +1 -0
  80. package/dist/esm/{commands → cli}/named.d.ts +1 -1
  81. package/dist/esm/cli/named.js +41 -0
  82. package/dist/esm/cli/named.js.map +1 -0
  83. package/dist/esm/{commands → cli}/peek.js +1 -1
  84. package/dist/esm/cli/peek.js.map +1 -0
  85. package/dist/esm/cli/query.js.map +1 -0
  86. package/dist/esm/cli/rebuild.js.map +1 -0
  87. package/dist/esm/cli/search.d.ts +3 -0
  88. package/dist/esm/cli/search.js +16 -0
  89. package/dist/esm/cli/search.js.map +1 -0
  90. package/dist/{cjs/commands → esm/cli}/shared.d.ts +1 -0
  91. package/dist/esm/{commands → cli}/shared.js +9 -0
  92. package/dist/esm/cli/shared.js.map +1 -0
  93. package/dist/esm/{commands → cli}/status.js +17 -11
  94. package/dist/esm/cli/status.js.map +1 -0
  95. package/dist/{cjs/commands → esm/cli}/types.d.ts +3 -1
  96. package/dist/esm/cli/types.js.map +1 -0
  97. package/dist/esm/cli/watch.js.map +1 -0
  98. package/dist/esm/cli.js +24 -6
  99. package/dist/esm/cli.js.map +1 -1
  100. package/dist/{cjs/verbs.d.ts → esm/commands.d.ts} +15 -5
  101. package/dist/esm/commands.js +386 -0
  102. package/dist/esm/commands.js.map +1 -0
  103. package/dist/esm/config.d.ts +45 -12
  104. package/dist/esm/config.js +367 -93
  105. package/dist/esm/config.js.map +1 -1
  106. package/dist/esm/db.d.ts +1 -1
  107. package/dist/esm/db.js +126 -17
  108. package/dist/esm/db.js.map +1 -1
  109. package/dist/esm/errors.d.ts +1 -1
  110. package/dist/esm/errors.js.map +1 -1
  111. package/dist/esm/features/embed.js +18 -2
  112. package/dist/esm/features/embed.js.map +1 -1
  113. package/dist/esm/features/links.js +130 -20
  114. package/dist/esm/features/links.js.map +1 -1
  115. package/dist/esm/features/rank.js +8 -1
  116. package/dist/esm/features/rank.js.map +1 -1
  117. package/dist/esm/features/types.d.ts +12 -4
  118. package/dist/esm/features/types.js.map +1 -1
  119. package/dist/esm/index.d.ts +3 -3
  120. package/dist/esm/index.js +1 -1
  121. package/dist/esm/index.js.map +1 -1
  122. package/dist/esm/output.d.ts +16 -0
  123. package/dist/esm/output.js +20 -5
  124. package/dist/esm/output.js.map +1 -1
  125. package/dist/esm/progress.d.ts +5 -0
  126. package/dist/esm/progress.js +44 -0
  127. package/dist/esm/progress.js.map +1 -0
  128. package/dist/esm/scan.d.ts +4 -0
  129. package/dist/esm/scan.js +37 -6
  130. package/dist/esm/scan.js.map +1 -1
  131. package/package.json +12 -2
  132. package/schema.json +85 -50
  133. package/skills/sense/EXAMPLES.md +16 -12
  134. package/skills/sense/SKILL.md +74 -55
  135. package/skills/sense-setup/EXAMPLES.md +121 -0
  136. package/skills/sense-setup/SKILL.md +73 -54
  137. package/dist/cjs/commands/check.js +0 -143
  138. package/dist/cjs/commands/check.js.map +0 -1
  139. package/dist/cjs/commands/find.d.cts +0 -3
  140. package/dist/cjs/commands/find.d.ts +0 -3
  141. package/dist/cjs/commands/find.js.map +0 -1
  142. package/dist/cjs/commands/index.js.map +0 -1
  143. package/dist/cjs/commands/init.js.map +0 -1
  144. package/dist/cjs/commands/map.js.map +0 -1
  145. package/dist/cjs/commands/named.js +0 -23
  146. package/dist/cjs/commands/named.js.map +0 -1
  147. package/dist/cjs/commands/peek.js.map +0 -1
  148. package/dist/cjs/commands/query.js.map +0 -1
  149. package/dist/cjs/commands/rebuild.js.map +0 -1
  150. package/dist/cjs/commands/shared.js.map +0 -1
  151. package/dist/cjs/commands/status.js.map +0 -1
  152. package/dist/cjs/commands/watch.js.map +0 -1
  153. package/dist/cjs/verbs.js.map +0 -1
  154. package/dist/esm/commands/check.js.map +0 -1
  155. package/dist/esm/commands/find.d.ts +0 -3
  156. package/dist/esm/commands/find.js +0 -15
  157. package/dist/esm/commands/find.js.map +0 -1
  158. package/dist/esm/commands/index.js.map +0 -1
  159. package/dist/esm/commands/init.js.map +0 -1
  160. package/dist/esm/commands/map.js.map +0 -1
  161. package/dist/esm/commands/named.js +0 -12
  162. package/dist/esm/commands/named.js.map +0 -1
  163. package/dist/esm/commands/peek.js.map +0 -1
  164. package/dist/esm/commands/query.js.map +0 -1
  165. package/dist/esm/commands/rebuild.js.map +0 -1
  166. package/dist/esm/commands/shared.js.map +0 -1
  167. package/dist/esm/commands/status.js.map +0 -1
  168. package/dist/esm/commands/types.js.map +0 -1
  169. package/dist/esm/commands/watch.js.map +0 -1
  170. package/dist/esm/verbs.js +0 -190
  171. package/dist/esm/verbs.js.map +0 -1
  172. /package/dist/cjs/{commands → cli}/check.d.cts +0 -0
  173. /package/dist/cjs/{commands → cli}/check.d.ts +0 -0
  174. /package/dist/cjs/{commands → cli}/index.d.cts +0 -0
  175. /package/dist/cjs/{commands → cli}/index.d.ts +0 -0
  176. /package/dist/cjs/{commands → cli}/init.d.cts +0 -0
  177. /package/dist/cjs/{commands → cli}/init.d.ts +0 -0
  178. /package/dist/cjs/{commands → cli}/map.d.cts +0 -0
  179. /package/dist/cjs/{commands → cli}/map.d.ts +0 -0
  180. /package/dist/cjs/{commands → cli}/peek.d.cts +0 -0
  181. /package/dist/cjs/{commands → cli}/peek.d.ts +0 -0
  182. /package/dist/cjs/{commands → cli}/query.d.cts +0 -0
  183. /package/dist/cjs/{commands → cli}/query.d.ts +0 -0
  184. /package/dist/cjs/{commands → cli}/query.js +0 -0
  185. /package/dist/cjs/{commands → cli}/rebuild.d.cts +0 -0
  186. /package/dist/cjs/{commands → cli}/rebuild.d.ts +0 -0
  187. /package/dist/cjs/{commands → cli}/rebuild.js +0 -0
  188. /package/dist/cjs/{commands → cli}/status.d.cts +0 -0
  189. /package/dist/cjs/{commands → cli}/status.d.ts +0 -0
  190. /package/dist/cjs/{commands → cli}/types.js +0 -0
  191. /package/dist/cjs/{commands → cli}/types.js.map +0 -0
  192. /package/dist/cjs/{commands → cli}/watch.d.cts +0 -0
  193. /package/dist/cjs/{commands → cli}/watch.d.ts +0 -0
  194. /package/dist/cjs/{commands → cli}/watch.js +0 -0
  195. /package/dist/esm/{commands → cli}/check.d.ts +0 -0
  196. /package/dist/esm/{commands → cli}/index.d.ts +0 -0
  197. /package/dist/esm/{commands → cli}/init.d.ts +0 -0
  198. /package/dist/esm/{commands → cli}/map.d.ts +0 -0
  199. /package/dist/esm/{commands → cli}/peek.d.ts +0 -0
  200. /package/dist/esm/{commands → cli}/query.d.ts +0 -0
  201. /package/dist/esm/{commands → cli}/query.js +0 -0
  202. /package/dist/esm/{commands → cli}/rebuild.d.ts +0 -0
  203. /package/dist/esm/{commands → cli}/rebuild.js +0 -0
  204. /package/dist/esm/{commands → cli}/status.d.ts +0 -0
  205. /package/dist/esm/{commands → cli}/types.js +0 -0
  206. /package/dist/esm/{commands → cli}/watch.d.ts +0 -0
  207. /package/dist/esm/{commands → cli}/watch.js +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/check.ts"],"sourcesContent":["import { open } from '../db.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } from '../output.ts';\nimport { printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// A saved query that returns zero rows looks identical to a true empty result, so a broken\n// one can sit unnoticed -- one field report had `WHERE flag = 'true'` against a numeric\n// column reading as \"nothing tagged yet\" for hours. Preparing each query catches syntax and\n// unknown-column errors without executing it; queries that take no parameters are also run\n// for a row count. Parameterised queries are validated but not counted: inventing arguments\n// would report a count for a query nobody ran.\nconst check: Command = (ctx) => {\n const cfg = ctx.resolveConfig();\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n\n const rows: Row[] = [];\n let failed = 0;\n for (const [name, sql] of Object.entries(cfg.queries ?? {})) {\n const params = (sql.match(/\\?/g) ?? []).length;\n const expectEmpty = cfg.checks?.[name] === 'empty';\n try {\n const statement = db.prepare(sql);\n if (params > 0) {\n rows.push({ query: name, params, rows: '—', status: 'ok (not run: needs parameters)' });\n continue;\n }\n const count = (statement.all() as unknown[]).length;\n if (expectEmpty) {\n // An invariant query: rows are violations, so 0 is the pass, anything else fails.\n if (count > 0) failed++;\n rows.push({ query: name, params, rows: count, status: count === 0 ? 'ok (empty, as asserted)' : `FAILED: expected empty, returned ${count} row(s)` });\n } else {\n rows.push({ query: name, params, rows: count, status: count === 0 ? 'ok, but returns 0 rows' : 'ok' });\n }\n } catch (err) {\n failed++;\n rows.push({ query: name, params, rows: '—', status: `FAILED: ${(err as Error).message}` });\n }\n }\n\n db.close();\n if (rows.length === 0) {\n console.log('no saved queries in config');\n return;\n }\n printRows(rows, ctx.format);\n if (failed > 0) process.exit(1);\n};\nexport default check;\n"],"names":["check","ctx","cfg","resolveConfig","open","db","warnings","printWarnings","rows","failed","Object","entries","queries","name","sql","params","match","length","expectEmpty","checks","statement","prepare","push","query","status","count","all","err","message","close","console","log","printRows","format","process","exit"],"mappings":";;;;+BAkDA;;;eAAA;;;oBAlDqB;wBAEK;wBACI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAG9B,2FAA2F;AAC3F,wFAAwF;AACxF,4FAA4F;AAC5F,2FAA2F;AAC3F,4FAA4F;AAC5F,+CAA+C;AAC/C,IAAMA,QAAiB,eAACC;QAOmBC;IANzC,IAAMA,MAAMD,IAAIE,aAAa;IAC7B,IAAyBC,QAAAA,IAAAA,UAAI,EAACF,MAAtBG,KAAiBD,MAAjBC,IAAIC,WAAaF,MAAbE;IACZC,IAAAA,uBAAa,EAACD;IAEd,IAAME,OAAc,EAAE;IACtB,IAAIC,SAAS;QACR,kCAAA,2BAAA;;QAAL,QAAK,YAAqBC,OAAOC,OAAO,EAACT,eAAAA,IAAIU,OAAO,cAAXV,0BAAAA,eAAe,CAAC,uBAApD,SAAA,6BAAA,QAAA,yBAAA,iCAAwD;YAAxD,mCAAA,iBAAOW,uBAAMC;gBACAA;gBACIZ;YADpB,IAAMa,SAAS,EAACD,aAAAA,IAAIE,KAAK,CAAC,oBAAVF,wBAAAA,aAAoB,EAAE,EAAEG,MAAM;YAC9C,IAAMC,cAAchB,EAAAA,cAAAA,IAAIiB,MAAM,cAAVjB,kCAAAA,WAAY,CAACW,KAAK,MAAK;YAC3C,IAAI;gBACF,IAAMO,YAAYf,GAAGgB,OAAO,CAACP;gBAC7B,IAAIC,SAAS,GAAG;oBACdP,KAAKc,IAAI,CAAC;wBAAEC,OAAOV;wBAAME,QAAAA;wBAAQP,MAAM;wBAAKgB,QAAQ;oBAAiC;oBACrF;gBACF;gBACA,IAAMC,QAAQ,AAACL,UAAUM,GAAG,GAAiBT,MAAM;gBACnD,IAAIC,aAAa;oBACf,kFAAkF;oBAClF,IAAIO,QAAQ,GAAGhB;oBACfD,KAAKc,IAAI,CAAC;wBAAEC,OAAOV;wBAAME,QAAAA;wBAAQP,MAAMiB;wBAAOD,QAAQC,UAAU,IAAI,4BAA4B,AAAC,oCAAyC,OAANA,OAAM;oBAAS;gBACrJ,OAAO;oBACLjB,KAAKc,IAAI,CAAC;wBAAEC,OAAOV;wBAAME,QAAAA;wBAAQP,MAAMiB;wBAAOD,QAAQC,UAAU,IAAI,2BAA2B;oBAAK;gBACtG;YACF,EAAE,OAAOE,KAAK;gBACZlB;gBACAD,KAAKc,IAAI,CAAC;oBAAEC,OAAOV;oBAAME,QAAAA;oBAAQP,MAAM;oBAAKgB,QAAQ,AAAC,WAAiC,OAAvB,AAACG,IAAcC,OAAO;gBAAG;YAC1F;QACF;;QArBK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAuBLvB,GAAGwB,KAAK;IACR,IAAIrB,KAAKS,MAAM,KAAK,GAAG;QACrBa,QAAQC,GAAG,CAAC;QACZ;IACF;IACAC,IAAAA,mBAAS,EAACxB,MAAMP,IAAIgC,MAAM;IAC1B,IAAIxB,SAAS,GAAGyB,QAAQC,IAAI,CAAC;AAC/B;IACA,WAAenC"}
@@ -1,3 +0,0 @@
1
- import type { Command } from './types.js';
2
- declare const findCmd: Command;
3
- export default findCmd;
@@ -1,3 +0,0 @@
1
- import type { Command } from './types.js';
2
- declare const findCmd: Command;
3
- export default findCmd;
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/find.ts"],"sourcesContent":["import { printRows } from '../output.ts';\nimport { find } from '../verbs.ts';\nimport { withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst findCmd: Command = async (ctx) => {\n const [terms] = ctx.rest;\n if (!terms) ctx.usageError(`usage: ${ctx.name} find \"<terms>\" [--where \"<sql>\"] [--k n] [--semantic]`);\n const k = ctx.values.k === undefined ? undefined : Number.parseInt(ctx.values.k, 10);\n if (ctx.values.k !== undefined && !Number.isInteger(k)) ctx.usageError(`--k expects an integer, got \"${ctx.values.k}\"`);\n await withDb(ctx, async (db, cfg) => printRows(await find(db, cfg, terms, { k, where: ctx.values.where, semantic: ctx.values.semantic }), ctx.format));\n};\nexport default findCmd;\n"],"names":["findCmd","ctx","terms","k","rest","usageError","name","values","undefined","Number","parseInt","isInteger","withDb","db","cfg","find","where","semantic","printRows","format"],"mappings":";;;;+BAYA;;;eAAA;;;wBAZ0B;uBACL;wBACE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGvB,IAAMA,UAAmB,iBAAOC;;YACdA,WAATC,OAEDC;;;;oBAFUF,6BAAAA,IAAIG,IAAI,MAAjBF,QAASD;oBAChB,IAAI,CAACC,OAAOD,IAAII,UAAU,CAAC,AAAC,UAAkB,OAATJ,IAAIK,IAAI,EAAC;oBACxCH,IAAIF,IAAIM,MAAM,CAACJ,CAAC,KAAKK,YAAYA,YAAYC,OAAOC,QAAQ,CAACT,IAAIM,MAAM,CAACJ,CAAC,EAAE;oBACjF,IAAIF,IAAIM,MAAM,CAACJ,CAAC,KAAKK,aAAa,CAACC,OAAOE,SAAS,CAACR,IAAIF,IAAII,UAAU,CAAC,AAAC,gCAA4C,OAAbJ,IAAIM,MAAM,CAACJ,CAAC,EAAC;oBACpH;;wBAAMS,IAAAA,gBAAM,EAACX,KAAK,SAAOY,IAAIC;;;;;4CAAkB;;gDAAMC,IAAAA,aAAI,EAACF,IAAIC,KAAKZ,OAAO;oDAAEC,GAAAA;oDAAGa,OAAOf,IAAIM,MAAM,CAACS,KAAK;oDAAEC,UAAUhB,IAAIM,MAAM,CAACU,QAAQ;gDAAC;;;;;gDAAjGC,mBAAS;oDAAC;oDAA2FjB,IAAIkB,MAAM;;;;;;;;;oBAApJ;;;;;;IACF;;IACA,WAAenB"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/index.ts"],"sourcesContent":["import type { Command } from './types.ts';\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: a named\n// query in config can never shadow them.\nexport const COMMANDS: Record<string, () => Promise<{ default: Command }>> = {\n init: () => import('./init.ts'),\n watch: () => import('./watch.ts'),\n status: () => import('./status.ts'),\n check: () => import('./check.ts'),\n rebuild: () => import('./rebuild.ts'),\n query: () => import('./query.ts'),\n find: () => import('./find.ts'),\n map: () => import('./map.ts'),\n peek: () => import('./peek.ts'),\n};\n\nexport type { Command, Ctx } from './types.ts';\n"],"names":["COMMANDS","init","watch","status","check","rebuild","query","find","map","peek"],"mappings":";;;;+BAKaA;;;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAN,IAAMA,WAAgE;IAC3EC,MAAM,SAANA;eAAY;2DAAA,QAAO;;;IACnBC,OAAO,SAAPA;eAAa;2DAAA,QAAO;;;IACpBC,QAAQ,SAARA;eAAc;2DAAA,QAAO;;;IACrBC,OAAO,SAAPA;eAAa;2DAAA,QAAO;;;IACpBC,SAAS,SAATA;eAAe;2DAAA,QAAO;;;IACtBC,OAAO,SAAPA;eAAa;2DAAA,QAAO;;;IACpBC,MAAM,SAANA;eAAY;2DAAA,QAAO;;;IACnBC,KAAK,SAALA;eAAW;2DAAA,QAAO;;;IAClBC,MAAM,SAANA;eAAY;2DAAA,QAAO;;;AACrB"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/init.ts"],"sourcesContent":["import { initConfig } from '../config.ts';\nimport type { Command } from './types.ts';\n\nconst init: Command = (ctx) => {\n const configPath = initConfig(process.cwd());\n console.log(`created ${configPath}`);\n console.log(`query away: ${ctx.name} query \"SELECT path FROM frontmatter LIMIT 10\"`);\n};\nexport default init;\n"],"names":["init","ctx","configPath","initConfig","process","cwd","console","log","name"],"mappings":";;;;+BAQA;;;eAAA;;;wBAR2B;AAG3B,IAAMA,OAAgB,cAACC;IACrB,IAAMC,aAAaC,IAAAA,oBAAU,EAACC,QAAQC,GAAG;IACzCC,QAAQC,GAAG,CAAC,AAAC,WAAqB,OAAXL;IACvBI,QAAQC,GAAG,CAAC,AAAC,eAAuB,OAATN,IAAIO,IAAI,EAAC;AACtC;IACA,WAAeR"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/map.ts"],"sourcesContent":["import { renderMap } from '../output.ts';\nimport { mapTree } from '../verbs.ts';\nimport { withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst map: Command = (ctx) =>\n withDb(ctx, (db, cfg) => {\n const result = mapTree(db, cfg);\n console.log(ctx.format === 'json' ? JSON.stringify(result, null, 2) : renderMap(result));\n });\nexport default map;\n"],"names":["map","ctx","withDb","db","cfg","result","mapTree","console","log","format","JSON","stringify","renderMap"],"mappings":";;;;+BAUA;;;eAAA;;;wBAV0B;uBACF;wBACD;AAGvB,IAAMA,MAAe,aAACC;WACpBC,IAAAA,gBAAM,EAACD,KAAK,SAACE,IAAIC;QACf,IAAMC,SAASC,IAAAA,gBAAO,EAACH,IAAIC;QAC3BG,QAAQC,GAAG,CAACP,IAAIQ,MAAM,KAAK,SAASC,KAAKC,SAAS,CAACN,QAAQ,MAAM,KAAKO,IAAAA,mBAAS,EAACP;IAClF;;IACF,WAAeL"}
@@ -1,23 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, // Fallback when the first positional is not a command: a named query from config.
6
- "default", {
7
- enumerable: true,
8
- get: function() {
9
- return named;
10
- }
11
- });
12
- var _sharedts = require("./shared.js");
13
- function named(ctx, queryName, params) {
14
- var cfg = ctx.resolveConfig();
15
- var sql = cfg.queries[queryName];
16
- if (!sql) {
17
- console.error('unknown query: "'.concat(queryName, '"'));
18
- console.error("valid queries: ".concat(Object.keys(cfg.queries).sort().join(', ')));
19
- process.exit(2);
20
- }
21
- (0, _sharedts.runSql)(cfg, sql, params, ctx.format, 'query "'.concat(queryName, '"'));
22
- }
23
- /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/named.ts"],"sourcesContent":["import { runSql } from './shared.ts';\nimport type { Ctx } from './types.ts';\n\n// Fallback when the first positional is not a command: a named query from config.\nexport default function named(ctx: Ctx, queryName: string, params: string[]): void {\n const cfg = ctx.resolveConfig();\n const sql = cfg.queries[queryName];\n if (!sql) {\n console.error(`unknown query: \"${queryName}\"`);\n console.error(`valid queries: ${Object.keys(cfg.queries).sort().join(', ')}`);\n process.exit(2);\n }\n runSql(cfg, sql, params, ctx.format, `query \"${queryName}\"`);\n}\n"],"names":["named","ctx","queryName","params","cfg","resolveConfig","sql","queries","console","error","Object","keys","sort","join","process","exit","runSql","format"],"mappings":";;;;+BAGA,kFAAkF;AAClF;;;eAAwBA;;;wBAJD;AAIR,SAASA,MAAMC,GAAQ,EAAEC,SAAiB,EAAEC,MAAgB;IACzE,IAAMC,MAAMH,IAAII,aAAa;IAC7B,IAAMC,MAAMF,IAAIG,OAAO,CAACL,UAAU;IAClC,IAAI,CAACI,KAAK;QACRE,QAAQC,KAAK,CAAC,AAAC,mBAA4B,OAAVP,WAAU;QAC3CM,QAAQC,KAAK,CAAC,AAAC,kBAA4D,OAA3CC,OAAOC,IAAI,CAACP,IAAIG,OAAO,EAAEK,IAAI,GAAGC,IAAI,CAAC;QACrEC,QAAQC,IAAI,CAAC;IACf;IACAC,IAAAA,gBAAM,EAACZ,KAAKE,KAAKH,QAAQF,IAAIgB,MAAM,EAAE,AAAC,UAAmB,OAAVf,WAAU;AAC3D"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/peek.ts"],"sourcesContent":["import { renderPeek } from '../output.ts';\nimport { peek } from '../verbs.ts';\nimport { withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst peekCmd: Command = (ctx) => {\n const [pathArg] = ctx.rest;\n if (!pathArg) ctx.usageError(`usage: ${ctx.name} peek <path>`);\n return withDb(ctx, (db, cfg) => {\n const result = peek(db, cfg, pathArg);\n console.log(ctx.format === 'json' ? JSON.stringify(result, null, 2) : renderPeek(result));\n });\n};\nexport default peekCmd;\n"],"names":["peekCmd","ctx","rest","pathArg","usageError","name","withDb","db","cfg","result","peek","console","log","format","JSON","stringify","renderPeek"],"mappings":";;;;+BAaA;;;eAAA;;;wBAb2B;uBACN;wBACE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGvB,IAAMA,UAAmB,iBAACC;IACxB,IAAkBA,6BAAAA,IAAIC,IAAI,MAAnBC,UAAWF;IAClB,IAAI,CAACE,SAASF,IAAIG,UAAU,CAAC,AAAC,UAAkB,OAATH,IAAII,IAAI,EAAC;IAChD,OAAOC,IAAAA,gBAAM,EAACL,KAAK,SAACM,IAAIC;QACtB,IAAMC,SAASC,IAAAA,aAAI,EAACH,IAAIC,KAAKL;QAC7BQ,QAAQC,GAAG,CAACX,IAAIY,MAAM,KAAK,SAASC,KAAKC,SAAS,CAACN,QAAQ,MAAM,KAAKO,IAAAA,oBAAU,EAACP;IACnF;AACF;IACA,WAAeT"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/query.ts"],"sourcesContent":["import { runSql } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst query: Command = (ctx) => {\n const [sql, ...params] = ctx.rest;\n if (!sql) ctx.usageError(`usage: ${ctx.name} query \"<sql>\" [params...]`);\n runSql(ctx.resolveConfig(), sql, params, ctx.format, 'ad-hoc query');\n};\nexport default query;\n"],"names":["query","ctx","rest","sql","params","usageError","name","runSql","resolveConfig","format"],"mappings":";;;;+BAQA;;;eAAA;;;wBARuB;;;;;;;;;;;;;;;;;;;;;;;;;;AAGvB,IAAMA,QAAiB,eAACC;IACtB,IAAyBA,sBAAAA,IAAIC,IAAI,GAA1BC,MAAkBF,cAAb,AAAGG,SAAUH,gBAAb;IACZ,IAAI,CAACE,KAAKF,IAAII,UAAU,CAAC,AAAC,UAAkB,OAATJ,IAAIK,IAAI,EAAC;IAC5CC,IAAAA,gBAAM,EAACN,IAAIO,aAAa,IAAIL,KAAKC,QAAQH,IAAIQ,MAAM,EAAE;AACvD;IACA,WAAeT"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/rebuild.ts"],"sourcesContent":["import { docCount, rebuild } from '../db.ts';\nimport { printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst rebuildCmd: Command = (ctx) => {\n const result = rebuild(ctx.resolveConfig());\n printWarnings(result.warnings);\n console.log(`rebuilt: ${docCount(result.db)} docs`);\n result.db.close();\n};\nexport default rebuildCmd;\n"],"names":["rebuildCmd","ctx","result","rebuild","resolveConfig","printWarnings","warnings","console","log","docCount","db","close"],"mappings":";;;;+BAUA;;;eAAA;;;oBAVkC;wBACJ;AAG9B,IAAMA,aAAsB,oBAACC;IAC3B,IAAMC,SAASC,IAAAA,aAAO,EAACF,IAAIG,aAAa;IACxCC,IAAAA,uBAAa,EAACH,OAAOI,QAAQ;IAC7BC,QAAQC,GAAG,CAAC,AAAC,YAA+B,OAApBC,IAAAA,cAAQ,EAACP,OAAOQ,EAAE,GAAE;IAC5CR,OAAOQ,EAAE,CAACC,KAAK;AACjB;IACA,WAAeX"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/shared.ts"],"sourcesContent":["import type { ResolvedConfig } from '../config.ts';\nimport type { OpenResult } from '../db.ts';\nimport { open } from '../db.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } from '../output.ts';\nimport { searchError } from '../search-error.ts';\nimport type { Ctx } from './types.ts';\n\n// Shared open-query-close envelope for commands that touch the tree.\n\nexport function printWarnings(warnings: string[]): void {\n for (const w of warnings) console.warn(w);\n}\n\nexport async function withDb(ctx: Ctx, fn: (db: OpenResult['db'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void> {\n const cfg = ctx.resolveConfig();\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n try {\n await fn(db, cfg);\n } finally {\n db.close();\n }\n}\n\n// An unbound `?` silently binds NULL, so mismatched param counts fail loudly instead.\nexport function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: 'table' | 'json', label: string): void {\n const placeholderCount = (sql.match(/\\?/g) ?? []).length;\n if (params.length !== placeholderCount) {\n console.error(`${label} expects ${placeholderCount} parameter(s), got ${params.length}`);\n process.exit(2);\n }\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n let rows: Row[];\n try {\n rows = db.prepare(sql).all(...params) as Row[];\n } catch (err) {\n db.close();\n // A saved query or ad-hoc SQL can carry `content MATCH ?` too, so the same FTS5\n // punctuation trap applies -- the bound parameters are the search terms there. SQL\n // without MATCH gets its error verbatim; search advice on a plain typo would mislead.\n if (/\\bMATCH\\b/i.test(sql)) throw searchError(err as Error, params.join(' '));\n throw err;\n }\n printRows(rows, format);\n db.close();\n}\n"],"names":["printWarnings","runSql","withDb","warnings","w","console","warn","ctx","fn","cfg","open","db","resolveConfig","close","sql","params","format","label","placeholderCount","match","length","error","process","exit","rows","prepare","all","err","test","searchError","join","printRows"],"mappings":";;;;;;;;;;;QAUgBA;eAAAA;;QAgBAC;eAAAA;;QAZMC;eAAAA;;;oBAZD;wBAEK;6BACE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKrB,SAASF,cAAcG,QAAkB;QACzC,kCAAA,2BAAA;;QAAL,QAAK,YAAWA,6BAAX,SAAA,6BAAA,QAAA,yBAAA;YAAA,IAAMC,IAAN;YAAqBC,QAAQC,IAAI,CAACF;;;QAAlC;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;AACP;AAEO,SAAeF,OAAOK,GAAQ,EAAEC,EAAuE;;YACtGC,KACmBC,OAAjBC,IAAIR;;;;oBADNM,MAAMF,IAAIK,aAAa;oBACJF,QAAAA,IAAAA,UAAI,EAACD,MAAtBE,KAAiBD,MAAjBC,IAAIR,WAAaO,MAAbP;oBACZH,cAAcG;;;;;;;;;oBAEZ;;wBAAMK,GAAGG,IAAIF;;;oBAAb;;;;;;oBAEAE,GAAGE,KAAK;;;;;;;;;;IAEZ;;AAGO,SAASZ,OAAOQ,GAAmB,EAAEK,GAAW,EAAEC,MAAgB,EAAEC,MAAwB,EAAEC,KAAa;QACtFH;IAA1B,IAAMI,mBAAmB,EAACJ,aAAAA,IAAIK,KAAK,CAAC,oBAAVL,wBAAAA,aAAoB,EAAE,EAAEM,MAAM;IACxD,IAAIL,OAAOK,MAAM,KAAKF,kBAAkB;QACtCb,QAAQgB,KAAK,CAAC,AAAC,GAAmBH,OAAjBD,OAAM,aAAiDF,OAAtCG,kBAAiB,uBAAmC,OAAdH,OAAOK,MAAM;QACrFE,QAAQC,IAAI,CAAC;IACf;IACA,IAAyBb,QAAAA,IAAAA,UAAI,EAACD,MAAtBE,KAAiBD,MAAjBC,IAAIR,WAAaO,MAAbP;IACZH,cAAcG;IACd,IAAIqB;IACJ,IAAI;YACKb;QAAPa,OAAOb,CAAAA,cAAAA,GAAGc,OAAO,CAACX,MAAKY,GAAG,OAAnBf,aAAoB,qBAAGI;IAChC,EAAE,OAAOY,KAAK;QACZhB,GAAGE,KAAK;QACR,gFAAgF;QAChF,mFAAmF;QACnF,sFAAsF;QACtF,IAAI,aAAae,IAAI,CAACd,MAAM,MAAMe,IAAAA,0BAAW,EAACF,KAAcZ,OAAOe,IAAI,CAAC;QACxE,MAAMH;IACR;IACAI,IAAAA,mBAAS,EAACP,MAAMR;IAChBL,GAAGE,KAAK;AACV"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/status.ts"],"sourcesContent":["import { embedConfig, featureStates } from '../config.ts';\nimport { docCount, getMeta, open } from '../db.ts';\nimport { printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// Vectors are computed on the first semantic query, not at reconcile, so a tree can be\n// embed-enabled with nothing embedded yet -- reported here because a fast `rebuild` on an\n// embed tree otherwise reads as \"the feature isn't on\".\nfunction vectorState(db: ReturnType<typeof open>['db']): { embedded: number; pending: number } | null {\n try {\n const row = db.prepare('SELECT COUNT(vector) AS embedded, COUNT(*) - COUNT(vector) AS pending FROM embeddings').get() as { embedded: number; pending: number };\n return row;\n } catch {\n return null;\n }\n}\n\nconst status: Command = (ctx) => {\n const cfg = ctx.resolveConfig();\n const { db, dbPath, warnings } = open(cfg);\n printWarnings(warnings);\n\n const features = featureStates(cfg);\n const e = embedConfig(cfg);\n const vectors = e ? vectorState(db) : null;\n const heartbeat = getMeta(db, 'watch_heartbeat');\n const result = {\n db: dbPath,\n docs: docCount(db),\n features: features.on,\n featuresOff: features.off,\n embed: e ? { type: e.type, model: e.model, ...(vectors ?? {}) } : null,\n findDefaultWhere: cfg.defaults?.find?.where ?? null,\n watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null,\n };\n\n if (ctx.format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(`db: ${result.db}`);\n console.log(`docs: ${result.docs}`);\n const off = features.off.length > 0 ? ` · off: ${features.off.map((name) => `${name} (features.${name})`).join(', ')}` : '';\n console.log(`features: ${features.on.join(', ')}${off}`);\n if (e) console.log(`embed: ${e.type} ${e.model}${vectors ? ` (vectors: ${vectors.embedded} embedded, ${vectors.pending} pending — embedded on first --semantic query)` : ''}`);\n if (result.findDefaultWhere) console.log(`find default scope: ${result.findDefaultWhere} (--where replaces it)`);\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: no watcher' : `watcher: last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n }\n db.close();\n};\nexport default status;\n"],"names":["vectorState","db","row","prepare","get","status","ctx","cfg","resolveConfig","open","dbPath","warnings","printWarnings","features","featureStates","e","embedConfig","vectors","heartbeat","getMeta","result","docs","docCount","on","featuresOff","off","embed","type","model","findDefaultWhere","defaults","find","where","watcherHeartbeatSecondsAgo","Math","round","Date","now","parse","format","console","log","JSON","stringify","length","map","name","join","embedded","pending","close"],"mappings":";;;;+BAiDA;;;eAAA;;;wBAjD2C;oBACH;wBACV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAG9B,uFAAuF;AACvF,0FAA0F;AAC1F,wDAAwD;AACxD,SAASA,YAAYC,EAAiC;IACpD,IAAI;QACF,IAAMC,MAAMD,GAAGE,OAAO,CAAC,yFAAyFC,GAAG;QACnH,OAAOF;IACT,EAAE,eAAM;QACN,OAAO;IACT;AACF;AAEA,IAAMG,SAAkB,gBAACC;;QAeHC,oBAAAA;IAdpB,IAAMA,MAAMD,IAAIE,aAAa;IAC7B,IAAiCC,QAAAA,IAAAA,UAAI,EAACF,MAA9BN,KAAyBQ,MAAzBR,IAAIS,SAAqBD,MAArBC,QAAQC,WAAaF,MAAbE;IACpBC,IAAAA,uBAAa,EAACD;IAEd,IAAME,WAAWC,IAAAA,uBAAa,EAACP;IAC/B,IAAMQ,IAAIC,IAAAA,qBAAW,EAACT;IACtB,IAAMU,UAAUF,IAAIf,YAAYC,MAAM;IACtC,IAAMiB,YAAYC,IAAAA,aAAO,EAAClB,IAAI;IAC9B,IAAMmB,SAAS;QACbnB,IAAIS;QACJW,MAAMC,IAAAA,cAAQ,EAACrB;QACfY,UAAUA,SAASU,EAAE;QACrBC,aAAaX,SAASY,GAAG;QACzBC,OAAOX,IAAI;YAAEY,MAAMZ,EAAEY,IAAI;YAAEC,OAAOb,EAAEa,KAAK;WAAMX,oBAAAA,qBAAAA,UAAW,CAAC,KAAO;QAClEY,gBAAgB,WAAEtB,gBAAAA,IAAIuB,QAAQ,cAAZvB,qCAAAA,qBAAAA,cAAcwB,IAAI,cAAlBxB,yCAAAA,mBAAoByB,KAAK,uCAAI;QAC/CC,4BAA4Bf,YAAYgB,KAAKC,KAAK,CAAC,AAACC,CAAAA,KAAKC,GAAG,KAAKD,KAAKE,KAAK,CAACpB,UAAS,IAAK,QAAQ;IACpG;IAEA,IAAIZ,IAAIiC,MAAM,KAAK,QAAQ;QACzBC,QAAQC,GAAG,CAACC,KAAKC,SAAS,CAACvB,QAAQ,MAAM;IAC3C,OAAO;QACLoB,QAAQC,GAAG,CAAC,AAAC,OAAgB,OAAVrB,OAAOnB,EAAE;QAC5BuC,QAAQC,GAAG,CAAC,AAAC,SAAoB,OAAZrB,OAAOC,IAAI;QAChC,IAAMI,MAAMZ,SAASY,GAAG,CAACmB,MAAM,GAAG,IAAI,AAAC,cAA8E,OAApE/B,SAASY,GAAG,CAACoB,GAAG,CAAC,SAACC;mBAAS,AAAC,GAAoBA,OAAlBA,MAAK,eAAkB,OAALA,MAAK;WAAIC,IAAI,CAAC,SAAU;QACzHP,QAAQC,GAAG,CAAC,AAAC,aAAqChB,OAAzBZ,SAASU,EAAE,CAACwB,IAAI,CAAC,OAAY,OAAJtB;QAClD,IAAIV,GAAGyB,QAAQC,GAAG,CAAC,AAAC,UAAmB1B,OAAVA,EAAEY,IAAI,EAAC,KAAaV,OAAVF,EAAEa,KAAK,EAA8H,OAA3HX,UAAU,AAAC,cAA2CA,OAA9BA,QAAQ+B,QAAQ,EAAC,eAA6B,OAAhB/B,QAAQgC,OAAO,EAAC,oDAAkD;QACzK,IAAI7B,OAAOS,gBAAgB,EAAEW,QAAQC,GAAG,CAAC,AAAC,uBAA8C,OAAxBrB,OAAOS,gBAAgB,EAAC;QACxFW,QAAQC,GAAG,CAACrB,OAAOa,0BAA0B,KAAK,OAAO,wBAAwB,AAAC,2BAA4D,OAAlCb,OAAOa,0BAA0B,EAAC;IAChJ;IACAhC,GAAGiD,KAAK;AACV;IACA,WAAe7C"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/watch.ts"],"sourcesContent":["import type { WatchEvent } from '../watch.ts';\nimport { runWatch } from '../watch.ts';\nimport { printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst watch: Command = async (ctx) => {\n await runWatch(ctx.resolveConfig(), {\n force: ctx.values.force,\n onEvent: (event: WatchEvent) => {\n if (event.type === 'started') {\n console.log(`${ctx.name} watch: watching ${event.baseDir}`);\n console.log(`${ctx.name} watch: db ${event.dbPath}`);\n } else if (event.type === 'reconciled') {\n printWarnings(event.warnings);\n if (event.parsed > 0) console.log(`${ctx.name} watch: reconciled, ${event.parsed} file(s) reparsed (${event.total} total)`);\n } else {\n console.error(`${ctx.name} watch: reconcile error: ${event.message}`);\n }\n },\n });\n};\nexport default watch;\n"],"names":["watch","ctx","runWatch","resolveConfig","force","values","onEvent","event","type","console","log","name","baseDir","dbPath","printWarnings","warnings","parsed","total","error","message"],"mappings":";;;;+BAqBA;;;eAAA;;;uBApByB;wBACK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAG9B,IAAMA,QAAiB,eAAOC;;;;;oBAC5B;;wBAAMC,IAAAA,iBAAQ,EAACD,IAAIE,aAAa,IAAI;4BAClCC,OAAOH,IAAII,MAAM,CAACD,KAAK;4BACvBE,SAAS,SAATA,QAAUC;gCACR,IAAIA,MAAMC,IAAI,KAAK,WAAW;oCAC5BC,QAAQC,GAAG,CAAC,AAAC,GAA8BH,OAA5BN,IAAIU,IAAI,EAAC,qBAAiC,OAAdJ,MAAMK,OAAO;oCACxDH,QAAQC,GAAG,CAAC,AAAC,GAAwBH,OAAtBN,IAAIU,IAAI,EAAC,eAA0B,OAAbJ,MAAMM,MAAM;gCACnD,OAAO,IAAIN,MAAMC,IAAI,KAAK,cAAc;oCACtCM,IAAAA,uBAAa,EAACP,MAAMQ,QAAQ;oCAC5B,IAAIR,MAAMS,MAAM,GAAG,GAAGP,QAAQC,GAAG,CAAC,AAAC,GAAiCH,OAA/BN,IAAIU,IAAI,EAAC,wBAAwDJ,OAAlCA,MAAMS,MAAM,EAAC,uBAAiC,OAAZT,MAAMU,KAAK,EAAC;gCACpH,OAAO;oCACLR,QAAQS,KAAK,CAAC,AAAC,GAAsCX,OAApCN,IAAIU,IAAI,EAAC,6BAAyC,OAAdJ,MAAMY,OAAO;gCACpE;4BACF;wBACF;;;oBAbA;;;;;;IAcF;;IACA,WAAenB"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/verbs.ts"],"sourcesContent":["import posix from 'node:path/posix';\nimport type { DatabaseSync } from 'node:sqlite';\nimport type { Config, FeatureName } from './config.ts';\nimport { featureEnabled, featureStates } from './config.ts';\nimport { SenseError } from './errors.ts';\nimport { semanticCandidates } from './features/embed.ts';\nimport { linkEdges } from './features/index.ts';\nimport { personalizedRank } from './graph.ts';\nimport type { Row } from './output.ts';\nimport { searchError } from './search-error.ts';\n\n// The three layer verbs: mapTree (orient), find (locate), peek (structure).\n// Each returns data; cli.ts renders. All of them degrade when a feature is off.\n\nconst WEIGHTED_BM25 = 'bm25(content, 10.0, 5.0, 1.0)';\nconst RRF_K = 60;\n\nexport interface FindOptions {\n k?: number;\n where?: string; // SQL fragment against frontmatter alias `f`, e.g. \"f.status = 'active'\"\n semantic?: boolean; // invoke vector expansion (requires features.embed); rows gain via 'vector' and a lines column\n}\n\n// Layer 1: BM25 + link-graph expansion, fused by reciprocal rank. `via` says which\n// signal produced each row so the agent knows what evidence it is trusting.\n// Semantic expansion is per-query opt-in: without opts.semantic the result is\n// byte-for-byte independent of the embed feature.\nexport async function find(db: DatabaseSync, cfg: Config, terms: string, opts: FindOptions = {}): Promise<Row[]> {\n const k = opts.k ?? 10;\n const fetch = Math.max(k * 3, 30);\n\n // Terms pass verbatim to FTS5 MATCH: bare words AND-join, operators are the caller's.\n // Invalid syntax propagates as an error, zero matches return zero -- no silent rewrites.\n // --where applies inside the candidate query (a post-filter over the top-N would drop\n // matches ranked past the pool) and again on the final select for link-derived rows.\n // An explicit --where replaces the tree's declared default rather than ANDing with it,\n // so a caller can always widen back to the whole tree.\n const scope = opts.where ?? cfg.defaults?.find?.where;\n const whereJoin = scope ? `JOIN frontmatter f ON f.\"path\" = content.path` : '';\n const whereCond = scope ? `AND (${scope})` : '';\n const matchSql = `SELECT content.path AS path, snippet(content, -1, '«', '»', '…', 10) AS hit FROM content ${whereJoin} WHERE content MATCH ? ${whereCond} ORDER BY ${WEIGHTED_BM25} LIMIT ${fetch}`;\n let matchRows: Array<{ path: string; hit: string }>;\n try {\n matchRows = db.prepare(matchSql).all(terms) as Array<{ path: string; hit: string }>;\n } catch (err) {\n throw searchError(err as Error, terms, scope);\n }\n\n const hits = new Map(matchRows.map((r) => [r.path, r.hit]));\n const candidates = new Map<string, { score: number; via: string }>();\n matchRows.forEach((r, i) => {\n candidates.set(r.path, { score: 1 / (RRF_K + i), via: 'match' });\n });\n\n const edges = featureEnabled(cfg, 'links') && matchRows.length > 0 ? linkEdges(db) : [];\n if (edges.length > 0) {\n // `linked` gates the label only, not the score: PPR restart mass gives every seed a\n // nonzero rank even without an incident edge, which is not link evidence — but dropping\n // that mass from the score list reweights fusion toward connectivity and measurably\n // wrecks ranking on link-dense corpora (FEVER hit@10 0.997 -> 0.907; fusion-tuning.md).\n const linked = new Set(edges.flat());\n const nodes = (db.prepare('SELECT \"path\" FROM frontmatter').all() as Array<{ path: string }>).map((r) => r.path);\n const seeds = new Map(matchRows.map((r, i) => [r.path, 1 / (i + 1)]));\n const ranked = [...personalizedRank(nodes, edges, seeds)]\n .filter(([, score]) => score > 1e-9)\n .sort((a, b) => b[1] - a[1])\n .slice(0, fetch);\n ranked.forEach(([path], i) => {\n const existing = candidates.get(path);\n if (existing) {\n existing.score += 1 / (RRF_K + i);\n if (linked.has(path)) existing.via = 'match+link';\n } else {\n candidates.set(path, { score: 1 / (RRF_K + i), via: 'link' });\n }\n });\n }\n\n // Vector expansion, invoked only: a third RRF list at the swept flat-region constants\n // (weight 1, pool = fetch). Each row carries its best chunk's line range.\n const chunkLines = new Map<string, string>();\n const chunkSimilarity = new Map<string, number>();\n if (opts.semantic) {\n const vec = await semanticCandidates(db, cfg, terms, fetch);\n vec.forEach(({ path, lines, similarity }, i) => {\n chunkLines.set(path, lines);\n chunkSimilarity.set(path, similarity);\n const existing = candidates.get(path);\n if (existing) {\n existing.score += 1 / (RRF_K + i);\n existing.via = `${existing.via}+vector`;\n } else {\n candidates.set(path, { score: 1 / (RRF_K + i), via: 'vector' });\n }\n });\n }\n\n db.exec('DROP TABLE IF EXISTS _find');\n db.exec('CREATE TEMP TABLE _find (\"path\" TEXT PRIMARY KEY, score REAL, via TEXT, hit TEXT, lines TEXT, similarity REAL)');\n const insert = db.prepare('INSERT INTO _find (\"path\", score, via, hit, lines, similarity) VALUES (?, ?, ?, ?, ?, ?)');\n for (const [path, c] of candidates) insert.run(path, c.score, c.via, hits.get(path) ?? null, chunkLines.get(path) ?? null, chunkSimilarity.get(path) ?? null);\n\n const where = scope ? `WHERE ${scope}` : '';\n const linesCol = opts.semantic ? ', _find.lines, _find.similarity' : '';\n return db\n .prepare(\n `SELECT f.\"path\" AS path, content.title, content.summary, _find.hit, _find.via, round(_find.score, 4) AS score${linesCol}\n FROM _find JOIN frontmatter f ON f.\"path\" = _find.\"path\" JOIN content ON content.path = _find.\"path\"\n ${where} ORDER BY _find.score DESC LIMIT ?`\n )\n .all(k) as Row[];\n}\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 hubs: Row[];\n recent: Row[];\n}\n\nconst INTERNAL_COLUMNS = new Set(['path', '_mtime', '_size', '_rank']);\n\n// Layer 0: what is this tree. Fixed-size output regardless of tree size.\nexport function mapTree(db: DatabaseSync, cfg: Config): TreeMap {\n const docs = db.prepare('SELECT COUNT(*) AS count, COALESCE(SUM(\"_size\"), 0) AS bytes FROM frontmatter').get() as { count: number; bytes: number };\n\n const columns = (db.prepare('PRAGMA table_info(frontmatter)').all() as Array<{ name: string }>).map((r) => r.name).filter((name) => !INTERNAL_COLUMNS.has(name));\n const allFields = columns\n .map((name) => {\n const quoted = `\"${name.split('\"').join('\"\"')}\"`;\n // Observed storage class, not a declared one: these columns are added dynamically and\n // SQLite types per value, so a field can be text in most notes and numeric in a few.\n // Listing every distinct type makes both the type and any drift visible.\n const { n, types } = db.prepare(`SELECT COUNT(${quoted}) AS n, GROUP_CONCAT(DISTINCT typeof(${quoted})) AS types FROM frontmatter WHERE ${quoted} IS NOT NULL`).get() as { n: number; types: string | null };\n return { field: name, coverage: n, type: types ?? '' };\n })\n .sort((a, b) => (b.coverage as number) - (a.coverage as number)) as Row[];\n const fields = allFields.slice(0, 20);\n\n const hubs = featureEnabled(cfg, 'rank') ? (db.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 ORDER BY f.\"_rank\" DESC LIMIT 8`).all() as Row[]) : [];\n\n const recent = db.prepare(`SELECT \"path\", datetime(\"_mtime\" / 1000, 'unixepoch') AS modified FROM frontmatter ORDER BY \"_mtime\" DESC LIMIT 5`).all() as Row[];\n\n return { docs, fields, fieldsTotal: allFields.length, features: featureStates(cfg), hubs, recent };\n}\n\nexport interface Peek {\n path: string;\n tokens: number;\n frontmatter: Row;\n sections: Row[];\n outbound: string[];\n backlinks: string[];\n unresolved: string[];\n // Totals before truncation: a hub can have thousands of backlinks, and peek's whole\n // point is bounded output. Query the links table directly for the full list.\n outboundTotal: number;\n backlinksTotal: number;\n unresolvedTotal: number;\n off: FeatureName[]; // disabled features whose blocks are omitted (not empty)\n}\n\nconst PEEK_LINK_LIMIT = 20;\n\n// Layer 2: everything about one note except its prose -- frontmatter, outline with line\n// ranges + token estimates (so the follow-up Read is a range, not the file), links both ways.\nexport function peek(db: DatabaseSync, cfg: Config, pathArg: string): Peek {\n const paths = (db.prepare('SELECT \"path\" FROM frontmatter').all() as Array<{ path: string }>).map((r) => r.path);\n let path = paths.find((p) => p === pathArg);\n if (!path) {\n const base = posix.basename(pathArg).replace(/\\.md$/i, '').toLowerCase();\n const matches = paths.filter((p) => posix.basename(p).replace(/\\.md$/i, '').toLowerCase() === base);\n if (matches.length === 1) path = matches[0];\n else if (matches.length > 1) throw new SenseError('NOTE_AMBIGUOUS', `\"${pathArg}\" is ambiguous: ${matches.join(', ')}`);\n else throw new SenseError('NOTE_NOT_FOUND', `no note matches \"${pathArg}\"`);\n }\n\n const row = db.prepare('SELECT * FROM frontmatter WHERE \"path\" = ?').get(path) as Row;\n const frontmatter: Row = {};\n for (const [key, value] of Object.entries(row)) {\n if (!INTERNAL_COLUMNS.has(key) && value !== null) frontmatter[key] = value;\n }\n\n const sections = featureEnabled(cfg, 'sections') ? (db.prepare('SELECT level, heading, start_line, end_line, tokens FROM sections WHERE \"path\" = ? ORDER BY idx').all(path) as Row[]) : [];\n\n let outbound: string[] = [];\n let backlinks: string[] = [];\n let unresolved: string[] = [];\n let backlinksTotal = 0;\n if (featureEnabled(cfg, 'links')) {\n const out = db.prepare('SELECT target, dst FROM links WHERE src = ? ORDER BY target').all(path) as Array<{ target: string; dst: string | null }>;\n outbound = [...new Set(out.filter((l) => l.dst !== null).map((l) => l.dst as string))];\n unresolved = out.filter((l) => l.dst === null).map((l) => l.target);\n backlinksTotal = (db.prepare('SELECT COUNT(DISTINCT src) AS n FROM links WHERE dst = ?').get(path) as { n: number }).n;\n backlinks = (db.prepare('SELECT DISTINCT src FROM links WHERE dst = ? ORDER BY src LIMIT ?').all(path, PEEK_LINK_LIMIT) as Array<{ src: string }>).map((r) => r.src);\n }\n\n return {\n path,\n tokens: Math.ceil(((row._size as number) ?? 0) / 4),\n frontmatter,\n sections,\n outbound: outbound.slice(0, PEEK_LINK_LIMIT),\n backlinks,\n unresolved: unresolved.slice(0, PEEK_LINK_LIMIT),\n outboundTotal: outbound.length,\n backlinksTotal,\n unresolvedTotal: unresolved.length,\n off: (['sections', 'links'] as FeatureName[]).filter((name) => !featureEnabled(cfg, name)),\n };\n}\n"],"names":["find","mapTree","peek","WEIGHTED_BM25","RRF_K","db","cfg","terms","opts","hits","chunkLines","chunkSimilarity","k","fetch","scope","whereJoin","whereCond","matchSql","matchRows","candidates","edges","linked","nodes","seeds","ranked","vec","insert","path","c","where","linesCol","Math","max","defaults","prepare","all","err","searchError","Map","map","r","hit","forEach","i","set","score","via","featureEnabled","length","linkEdges","Set","flat","personalizedRank","filter","sort","a","b","slice","existing","get","has","semantic","semanticCandidates","lines","similarity","exec","run","INTERNAL_COLUMNS","docs","columns","name","allFields","quoted","split","join","n","types","field","coverage","type","fields","hubs","recent","fieldsTotal","features","featureStates","PEEK_LINK_LIMIT","pathArg","row","paths","p","base","posix","basename","replace","toLowerCase","matches","SenseError","frontmatter","Object","entries","key","value","sections","outbound","backlinks","unresolved","backlinksTotal","out","l","dst","target","src","tokens","ceil","_size","outboundTotal","unresolvedTotal","off"],"mappings":";;;;;;;;;;;QA2BsBA;eAAAA;;QAkGNC;eAAAA;;QA2CAC;eAAAA;;;4DAxKE;wBAG4B;wBACnB;uBACQ;uBACT;uBACO;6BAEL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE5B,4EAA4E;AAC5E,gFAAgF;AAEhF,IAAMC,gBAAgB;AACtB,IAAMC,QAAQ;AAYP,SAAeJ;wCAAKK,EAAgB,EAAEC,GAAW,EAAEC,KAAa;YAAEC,MAC7DA,SASIA,aA+DuDC,WAAwBC,iBAA8BC,sBA/D/FL,oBAAAA,eATtBM,GACAC,OAQAC,OACAC,WACAC,WACAC,UACFC,WAOET,MACAU,YAKAC,OAMEC,QACAC,OACAC,OACAC,QAiBFd,YACAC,iBAEEc,KAgBFC,QACD,2BAAA,mBAAA,gBAAA,WAAA,oBAAOC,MAAMC,GAEZC,OACAC;;;;;oBA5EiEtB,OAAAA,oEAAoB,CAAC;oBACtFI,KAAIJ,UAAAA,KAAKI,CAAC,cAANJ,qBAAAA,UAAU;oBACdK,QAAQkB,KAAKC,GAAG,CAACpB,IAAI,GAAG;oBAE9B,sFAAsF;oBACtF,yFAAyF;oBACzF,sFAAsF;oBACtF,qFAAqF;oBACrF,uFAAuF;oBACvF,uDAAuD;oBACjDE,SAAQN,cAAAA,KAAKqB,KAAK,cAAVrB,yBAAAA,eAAcF,gBAAAA,IAAI2B,QAAQ,cAAZ3B,qCAAAA,qBAAAA,cAAcN,IAAI,cAAlBM,yCAAAA,mBAAoBuB,KAAK;oBAC/Cd,YAAYD,QAAQ,kDAAkD;oBACtEE,YAAYF,QAAQ,AAAC,QAAa,OAANA,OAAM,OAAK;oBACvCG,WAAW,AAAC,kGAA8HD,OAAnCD,WAAU,2BAA+CZ,OAAtBa,WAAU,cAAmCH,OAAvBV,eAAc,WAAe,OAANU;oBAE7L,IAAI;wBACFK,YAAYb,GAAG6B,OAAO,CAACjB,UAAUkB,GAAG,CAAC5B;oBACvC,EAAE,OAAO6B,KAAK;wBACZ,MAAMC,IAAAA,0BAAW,EAACD,KAAc7B,OAAOO;oBACzC;oBAEML,OAAO,IAAI6B,IAAIpB,UAAUqB,GAAG,CAAC,SAACC;+BAAM;4BAACA,EAAEb,IAAI;4BAAEa,EAAEC,GAAG;yBAAC;;oBACnDtB,aAAa,IAAImB;oBACvBpB,UAAUwB,OAAO,CAAC,SAACF,GAAGG;wBACpBxB,WAAWyB,GAAG,CAACJ,EAAEb,IAAI,EAAE;4BAAEkB,OAAO,IAAKzC,CAAAA,QAAQuC,CAAAA;4BAAIG,KAAK;wBAAQ;oBAChE;oBAEM1B,QAAQ2B,IAAAA,wBAAc,EAACzC,KAAK,YAAYY,UAAU8B,MAAM,GAAG,IAAIC,IAAAA,kBAAS,EAAC5C;oBAC/E,IAAIe,MAAM4B,MAAM,GAAG,GAAG;wBACpB,oFAAoF;wBACpF,wFAAwF;wBACxF,oFAAoF;wBACpF,wFAAwF;wBAClF3B,SAAS,IAAI6B,IAAI9B,MAAM+B,IAAI;wBAC3B7B,QAAQ,AAACjB,GAAG6B,OAAO,CAAC,kCAAkCC,GAAG,GAA+BI,GAAG,CAAC,SAACC;mCAAMA,EAAEb,IAAI;;wBACzGJ,QAAQ,IAAIe,IAAIpB,UAAUqB,GAAG,CAAC,SAACC,GAAGG;mCAAM;gCAACH,EAAEb,IAAI;gCAAE,IAAKgB,CAAAA,IAAI,CAAA;6BAAG;;wBAC7DnB,SAAS,AAAC,qBAAG4B,IAAAA,yBAAgB,EAAC9B,OAAOF,OAAOG,QAC/C8B,MAAM,CAAC;qEAAIR;mCAAWA,QAAQ;2BAC9BS,IAAI,CAAC,SAACC,GAAGC;mCAAMA,CAAC,CAAC,EAAE,GAAGD,CAAC,CAAC,EAAE;2BAC1BE,KAAK,CAAC,GAAG5C;wBACZW,OAAOkB,OAAO,CAAC,gBAASC;qEAAPhB;4BACf,IAAM+B,WAAWvC,WAAWwC,GAAG,CAAChC;4BAChC,IAAI+B,UAAU;gCACZA,SAASb,KAAK,IAAI,IAAKzC,CAAAA,QAAQuC,CAAAA;gCAC/B,IAAItB,OAAOuC,GAAG,CAACjC,OAAO+B,SAASZ,GAAG,GAAG;4BACvC,OAAO;gCACL3B,WAAWyB,GAAG,CAACjB,MAAM;oCAAEkB,OAAO,IAAKzC,CAAAA,QAAQuC,CAAAA;oCAAIG,KAAK;gCAAO;4BAC7D;wBACF;oBACF;oBAEA,sFAAsF;oBACtF,0EAA0E;oBACpEpC,aAAa,IAAI4B;oBACjB3B,kBAAkB,IAAI2B;yBACxB9B,KAAKqD,QAAQ,EAAbrD;;;;oBACU;;wBAAMsD,IAAAA,2BAAkB,EAACzD,IAAIC,KAAKC,OAAOM;;;oBAA/CY,MAAM;oBACZA,IAAIiB,OAAO,CAAC,gBAA8BC;4BAA3BhB,aAAAA,MAAMoC,cAAAA,OAAOC,mBAAAA;wBAC1BtD,WAAWkC,GAAG,CAACjB,MAAMoC;wBACrBpD,gBAAgBiC,GAAG,CAACjB,MAAMqC;wBAC1B,IAAMN,WAAWvC,WAAWwC,GAAG,CAAChC;wBAChC,IAAI+B,UAAU;4BACZA,SAASb,KAAK,IAAI,IAAKzC,CAAAA,QAAQuC,CAAAA;4BAC/Be,SAASZ,GAAG,GAAG,AAAC,GAAe,OAAbY,SAASZ,GAAG,EAAC;wBACjC,OAAO;4BACL3B,WAAWyB,GAAG,CAACjB,MAAM;gCAAEkB,OAAO,IAAKzC,CAAAA,QAAQuC,CAAAA;gCAAIG,KAAK;4BAAS;wBAC/D;oBACF;;;oBAGFzC,GAAG4D,IAAI,CAAC;oBACR5D,GAAG4D,IAAI,CAAC;oBACFvC,SAASrB,GAAG6B,OAAO,CAAC;oBACrB,kCAAA,2BAAA;;wBAAL,IAAK,YAAmBf,iCAAnB,6BAAA,QAAA,yBAAA;2DAAA,iBAAOQ,uBAAMC;4BAAkBF,OAAOwC,GAAG,CAACvC,MAAMC,EAAEiB,KAAK,EAAEjB,EAAEkB,GAAG,GAAErC,YAAAA,KAAKkD,GAAG,CAAChC,mBAATlB,uBAAAA,YAAkB,OAAMC,kBAAAA,WAAWiD,GAAG,CAAChC,mBAAfjB,6BAAAA,kBAAwB,OAAMC,uBAAAA,gBAAgBgD,GAAG,CAAChC,mBAApBhB,kCAAAA,uBAA6B;;;wBAAnJ;wBAAA;;;iCAAA,6BAAA;gCAAA;;;gCAAA;sCAAA;;;;oBAECkB,QAAQf,QAAQ,AAAC,SAAc,OAANA,SAAU;oBACnCgB,WAAWtB,KAAKqD,QAAQ,GAAG,oCAAoC;oBACrE;;wBAAOxD,GACJ6B,OAAO,CACN,AAAC,gHAEEL,OAF6GC,UAAS,0HAEhH,OAAND,OAAM,uCAEVM,GAAG,CAACvB;;;;IACT;;AAWA,IAAMuD,mBAAmB,IAAIjB,IAAI;IAAC;IAAQ;IAAU;IAAS;CAAQ;AAG9D,SAASjD,QAAQI,EAAgB,EAAEC,GAAW;IACnD,IAAM8D,OAAO/D,GAAG6B,OAAO,CAAC,iFAAiFyB,GAAG;IAE5G,IAAMU,UAAU,AAAChE,GAAG6B,OAAO,CAAC,kCAAkCC,GAAG,GAA+BI,GAAG,CAAC,SAACC;eAAMA,EAAE8B,IAAI;OAAEjB,MAAM,CAAC,SAACiB;eAAS,CAACH,iBAAiBP,GAAG,CAACU;;IAC1J,IAAMC,YAAYF,QACf9B,GAAG,CAAC,SAAC+B;QACJ,IAAME,SAAS,AAAC,IAA8B,OAA3BF,KAAKG,KAAK,CAAC,KAAKC,IAAI,CAAC,OAAM;QAC9C,sFAAsF;QACtF,qFAAqF;QACrF,yEAAyE;QACzE,IAAqBrE,kBAAAA,GAAG6B,OAAO,CAAC,AAAC,gBAA6DsC,OAA9CA,QAAO,yCAAmFA,OAA5CA,QAAO,uCAA4C,OAAPA,QAAO,iBAAeb,GAAG,IAA3JgB,IAAatE,gBAAbsE,GAAGC,QAAUvE,gBAAVuE;QACX,OAAO;YAAEC,OAAOP;YAAMQ,UAAUH;YAAGI,IAAI,EAAEH,kBAAAA,mBAAAA,QAAS;QAAG;IACvD,GACCtB,IAAI,CAAC,SAACC,GAAGC;eAAM,AAACA,EAAEsB,QAAQ,GAAevB,EAAEuB,QAAQ;;IACtD,IAAME,SAAST,UAAUd,KAAK,CAAC,GAAG;IAElC,IAAMwB,OAAOlC,IAAAA,wBAAc,EAACzC,KAAK,UAAWD,GAAG6B,OAAO,CAAC,oMAAoMC,GAAG,KAAe,EAAE;IAE/Q,IAAM+C,SAAS7E,GAAG6B,OAAO,CAAC,uHAAqHC,GAAG;IAElJ,OAAO;QAAEiC,MAAAA;QAAMY,QAAAA;QAAQG,aAAaZ,UAAUvB,MAAM;QAAEoC,UAAUC,IAAAA,uBAAa,EAAC/E;QAAM2E,MAAAA;QAAMC,QAAAA;IAAO;AACnG;AAkBA,IAAMI,kBAAkB;AAIjB,SAASpF,KAAKG,EAAgB,EAAEC,GAAW,EAAEiF,OAAe;QAiC3CC;IAhCtB,IAAMC,QAAQ,AAACpF,GAAG6B,OAAO,CAAC,kCAAkCC,GAAG,GAA+BI,GAAG,CAAC,SAACC;eAAMA,EAAEb,IAAI;;IAC/G,IAAIA,OAAO8D,MAAMzF,IAAI,CAAC,SAAC0F;eAAMA,MAAMH;;IACnC,IAAI,CAAC5D,MAAM;QACT,IAAMgE,OAAOC,cAAK,CAACC,QAAQ,CAACN,SAASO,OAAO,CAAC,UAAU,IAAIC,WAAW;QACtE,IAAMC,UAAUP,MAAMpC,MAAM,CAAC,SAACqC;mBAAME,cAAK,CAACC,QAAQ,CAACH,GAAGI,OAAO,CAAC,UAAU,IAAIC,WAAW,OAAOJ;;QAC9F,IAAIK,QAAQhD,MAAM,KAAK,GAAGrB,OAAOqE,OAAO,CAAC,EAAE;aACtC,IAAIA,QAAQhD,MAAM,GAAG,GAAG,MAAM,IAAIiD,oBAAU,CAAC,kBAAkB,AAAC,IAA6BD,OAA1BT,SAAQ,oBAAqC,OAAnBS,QAAQtB,IAAI,CAAC;aAC1G,MAAM,IAAIuB,oBAAU,CAAC,kBAAkB,AAAC,oBAA2B,OAARV,SAAQ;IAC1E;IAEA,IAAMC,MAAMnF,GAAG6B,OAAO,CAAC,8CAA8CyB,GAAG,CAAChC;IACzE,IAAMuE,cAAmB,CAAC;QACrB,kCAAA,2BAAA;;QAAL,QAAK,YAAsBC,OAAOC,OAAO,CAACZ,yBAArC,SAAA,6BAAA,QAAA,yBAAA,iCAA2C;YAA3C,mCAAA,iBAAOa,sBAAKC;YACf,IAAI,CAACnC,iBAAiBP,GAAG,CAACyC,QAAQC,UAAU,MAAMJ,WAAW,CAACG,IAAI,GAAGC;QACvE;;QAFK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAIL,IAAMC,WAAWxD,IAAAA,wBAAc,EAACzC,KAAK,cAAeD,GAAG6B,OAAO,CAAC,mGAAmGC,GAAG,CAACR,QAAkB,EAAE;IAE1L,IAAI6E,WAAqB,EAAE;IAC3B,IAAIC,YAAsB,EAAE;IAC5B,IAAIC,aAAuB,EAAE;IAC7B,IAAIC,iBAAiB;IACrB,IAAI5D,IAAAA,wBAAc,EAACzC,KAAK,UAAU;QAChC,IAAMsG,MAAMvG,GAAG6B,OAAO,CAAC,+DAA+DC,GAAG,CAACR;QAC1F6E,WAAY,qBAAG,IAAItD,IAAI0D,IAAIvD,MAAM,CAAC,SAACwD;mBAAMA,EAAEC,GAAG,KAAK;WAAMvE,GAAG,CAAC,SAACsE;mBAAMA,EAAEC,GAAG;;QACzEJ,aAAaE,IAAIvD,MAAM,CAAC,SAACwD;mBAAMA,EAAEC,GAAG,KAAK;WAAMvE,GAAG,CAAC,SAACsE;mBAAMA,EAAEE,MAAM;;QAClEJ,iBAAiB,AAACtG,GAAG6B,OAAO,CAAC,4DAA4DyB,GAAG,CAAChC,MAAwBgD,CAAC;QACtH8B,YAAY,AAACpG,GAAG6B,OAAO,CAAC,qEAAqEC,GAAG,CAACR,MAAM2D,iBAA4C/C,GAAG,CAAC,SAACC;mBAAMA,EAAEwE,GAAG;;IACrK;IAEA,OAAO;QACLrF,MAAAA;QACAsF,QAAQlF,KAAKmF,IAAI,CAAC,EAAE1B,aAAAA,IAAI2B,KAAK,cAAT3B,wBAAAA,aAAwB,KAAK;QACjDU,aAAAA;QACAK,UAAAA;QACAC,UAAUA,SAAS/C,KAAK,CAAC,GAAG6B;QAC5BmB,WAAAA;QACAC,YAAYA,WAAWjD,KAAK,CAAC,GAAG6B;QAChC8B,eAAeZ,SAASxD,MAAM;QAC9B2D,gBAAAA;QACAU,iBAAiBX,WAAW1D,MAAM;QAClCsE,KAAK,AAAC;YAAC;YAAY;SAAQ,CAAmBjE,MAAM,CAAC,SAACiB;mBAAS,CAACvB,IAAAA,wBAAc,EAACzC,KAAKgE;;IACtF;AACF"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/check.ts"],"sourcesContent":["import { open } from '../db.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } from '../output.ts';\nimport { printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// A saved query that returns zero rows looks identical to a true empty result, so a broken\n// one can sit unnoticed -- one field report had `WHERE flag = 'true'` against a numeric\n// column reading as \"nothing tagged yet\" for hours. Preparing each query catches syntax and\n// unknown-column errors without executing it; queries that take no parameters are also run\n// for a row count. Parameterised queries are validated but not counted: inventing arguments\n// would report a count for a query nobody ran.\nconst check: Command = (ctx) => {\n const cfg = ctx.resolveConfig();\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n\n const rows: Row[] = [];\n let failed = 0;\n for (const [name, sql] of Object.entries(cfg.queries ?? {})) {\n const params = (sql.match(/\\?/g) ?? []).length;\n const expectEmpty = cfg.checks?.[name] === 'empty';\n try {\n const statement = db.prepare(sql);\n if (params > 0) {\n rows.push({ query: name, params, rows: '—', status: 'ok (not run: needs parameters)' });\n continue;\n }\n const count = (statement.all() as unknown[]).length;\n if (expectEmpty) {\n // An invariant query: rows are violations, so 0 is the pass, anything else fails.\n if (count > 0) failed++;\n rows.push({ query: name, params, rows: count, status: count === 0 ? 'ok (empty, as asserted)' : `FAILED: expected empty, returned ${count} row(s)` });\n } else {\n rows.push({ query: name, params, rows: count, status: count === 0 ? 'ok, but returns 0 rows' : 'ok' });\n }\n } catch (err) {\n failed++;\n rows.push({ query: name, params, rows: '—', status: `FAILED: ${(err as Error).message}` });\n }\n }\n\n db.close();\n if (rows.length === 0) {\n console.log('no saved queries in config');\n return;\n }\n printRows(rows, ctx.format);\n if (failed > 0) process.exit(1);\n};\nexport default check;\n"],"names":["open","printRows","printWarnings","check","ctx","cfg","resolveConfig","db","warnings","rows","failed","name","sql","Object","entries","queries","params","match","length","expectEmpty","checks","statement","prepare","push","query","status","count","all","err","message","close","console","log","format","process","exit"],"mappings":"AAAA,SAASA,IAAI,QAAQ,WAAW;AAEhC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,aAAa,QAAQ,cAAc;AAG5C,2FAA2F;AAC3F,wFAAwF;AACxF,4FAA4F;AAC5F,2FAA2F;AAC3F,4FAA4F;AAC5F,+CAA+C;AAC/C,MAAMC,QAAiB,CAACC;QAOmBC;IANzC,MAAMA,MAAMD,IAAIE,aAAa;IAC7B,MAAM,EAAEC,EAAE,EAAEC,QAAQ,EAAE,GAAGR,KAAKK;IAC9BH,cAAcM;IAEd,MAAMC,OAAc,EAAE;IACtB,IAAIC,SAAS;IACb,KAAK,MAAM,CAACC,MAAMC,IAAI,IAAIC,OAAOC,OAAO,EAACT,eAAAA,IAAIU,OAAO,cAAXV,0BAAAA,eAAe,CAAC,GAAI;YAC3CO;YACIP;QADpB,MAAMW,SAAS,EAACJ,aAAAA,IAAIK,KAAK,CAAC,oBAAVL,wBAAAA,aAAoB,EAAE,EAAEM,MAAM;QAC9C,MAAMC,cAAcd,EAAAA,cAAAA,IAAIe,MAAM,cAAVf,kCAAAA,WAAY,CAACM,KAAK,MAAK;QAC3C,IAAI;YACF,MAAMU,YAAYd,GAAGe,OAAO,CAACV;YAC7B,IAAII,SAAS,GAAG;gBACdP,KAAKc,IAAI,CAAC;oBAAEC,OAAOb;oBAAMK;oBAAQP,MAAM;oBAAKgB,QAAQ;gBAAiC;gBACrF;YACF;YACA,MAAMC,QAAQ,AAACL,UAAUM,GAAG,GAAiBT,MAAM;YACnD,IAAIC,aAAa;gBACf,kFAAkF;gBAClF,IAAIO,QAAQ,GAAGhB;gBACfD,KAAKc,IAAI,CAAC;oBAAEC,OAAOb;oBAAMK;oBAAQP,MAAMiB;oBAAOD,QAAQC,UAAU,IAAI,4BAA4B,CAAC,iCAAiC,EAAEA,MAAM,OAAO,CAAC;gBAAC;YACrJ,OAAO;gBACLjB,KAAKc,IAAI,CAAC;oBAAEC,OAAOb;oBAAMK;oBAAQP,MAAMiB;oBAAOD,QAAQC,UAAU,IAAI,2BAA2B;gBAAK;YACtG;QACF,EAAE,OAAOE,KAAK;YACZlB;YACAD,KAAKc,IAAI,CAAC;gBAAEC,OAAOb;gBAAMK;gBAAQP,MAAM;gBAAKgB,QAAQ,CAAC,QAAQ,EAAE,AAACG,IAAcC,OAAO,EAAE;YAAC;QAC1F;IACF;IAEAtB,GAAGuB,KAAK;IACR,IAAIrB,KAAKS,MAAM,KAAK,GAAG;QACrBa,QAAQC,GAAG,CAAC;QACZ;IACF;IACA/B,UAAUQ,MAAML,IAAI6B,MAAM;IAC1B,IAAIvB,SAAS,GAAGwB,QAAQC,IAAI,CAAC;AAC/B;AACA,eAAehC,MAAM"}
@@ -1,3 +0,0 @@
1
- import type { Command } from './types.js';
2
- declare const findCmd: Command;
3
- export default findCmd;
@@ -1,15 +0,0 @@
1
- import { printRows } from '../output.js';
2
- import { find } from '../verbs.js';
3
- import { withDb } from './shared.js';
4
- const findCmd = async (ctx)=>{
5
- const [terms] = ctx.rest;
6
- if (!terms) ctx.usageError(`usage: ${ctx.name} find "<terms>" [--where "<sql>"] [--k n] [--semantic]`);
7
- const k = ctx.values.k === undefined ? undefined : Number.parseInt(ctx.values.k, 10);
8
- if (ctx.values.k !== undefined && !Number.isInteger(k)) ctx.usageError(`--k expects an integer, got "${ctx.values.k}"`);
9
- await withDb(ctx, async (db, cfg)=>printRows(await find(db, cfg, terms, {
10
- k,
11
- where: ctx.values.where,
12
- semantic: ctx.values.semantic
13
- }), ctx.format));
14
- };
15
- export default findCmd;
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/find.ts"],"sourcesContent":["import { printRows } from '../output.ts';\nimport { find } from '../verbs.ts';\nimport { withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst findCmd: Command = async (ctx) => {\n const [terms] = ctx.rest;\n if (!terms) ctx.usageError(`usage: ${ctx.name} find \"<terms>\" [--where \"<sql>\"] [--k n] [--semantic]`);\n const k = ctx.values.k === undefined ? undefined : Number.parseInt(ctx.values.k, 10);\n if (ctx.values.k !== undefined && !Number.isInteger(k)) ctx.usageError(`--k expects an integer, got \"${ctx.values.k}\"`);\n await withDb(ctx, async (db, cfg) => printRows(await find(db, cfg, terms, { k, where: ctx.values.where, semantic: ctx.values.semantic }), ctx.format));\n};\nexport default findCmd;\n"],"names":["printRows","find","withDb","findCmd","ctx","terms","rest","usageError","name","k","values","undefined","Number","parseInt","isInteger","db","cfg","where","semantic","format"],"mappings":"AAAA,SAASA,SAAS,QAAQ,eAAe;AACzC,SAASC,IAAI,QAAQ,cAAc;AACnC,SAASC,MAAM,QAAQ,cAAc;AAGrC,MAAMC,UAAmB,OAAOC;IAC9B,MAAM,CAACC,MAAM,GAAGD,IAAIE,IAAI;IACxB,IAAI,CAACD,OAAOD,IAAIG,UAAU,CAAC,CAAC,OAAO,EAAEH,IAAII,IAAI,CAAC,sDAAsD,CAAC;IACrG,MAAMC,IAAIL,IAAIM,MAAM,CAACD,CAAC,KAAKE,YAAYA,YAAYC,OAAOC,QAAQ,CAACT,IAAIM,MAAM,CAACD,CAAC,EAAE;IACjF,IAAIL,IAAIM,MAAM,CAACD,CAAC,KAAKE,aAAa,CAACC,OAAOE,SAAS,CAACL,IAAIL,IAAIG,UAAU,CAAC,CAAC,6BAA6B,EAAEH,IAAIM,MAAM,CAACD,CAAC,CAAC,CAAC,CAAC;IACtH,MAAMP,OAAOE,KAAK,OAAOW,IAAIC,MAAQhB,UAAU,MAAMC,KAAKc,IAAIC,KAAKX,OAAO;YAAEI;YAAGQ,OAAOb,IAAIM,MAAM,CAACO,KAAK;YAAEC,UAAUd,IAAIM,MAAM,CAACQ,QAAQ;QAAC,IAAId,IAAIe,MAAM;AACtJ;AACA,eAAehB,QAAQ"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/index.ts"],"sourcesContent":["import type { Command } from './types.ts';\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: a named\n// query in config can never shadow them.\nexport const COMMANDS: Record<string, () => Promise<{ default: Command }>> = {\n init: () => import('./init.ts'),\n watch: () => import('./watch.ts'),\n status: () => import('./status.ts'),\n check: () => import('./check.ts'),\n rebuild: () => import('./rebuild.ts'),\n query: () => import('./query.ts'),\n find: () => import('./find.ts'),\n map: () => import('./map.ts'),\n peek: () => import('./peek.ts'),\n};\n\nexport type { Command, Ctx } from './types.ts';\n"],"names":["COMMANDS","init","watch","status","check","rebuild","query","find","map","peek"],"mappings":"AAEA,0FAA0F;AAC1F,0FAA0F;AAC1F,yCAAyC;AACzC,OAAO,MAAMA,WAAgE;IAC3EC,MAAM,IAAM,MAAM,CAAC;IACnBC,OAAO,IAAM,MAAM,CAAC;IACpBC,QAAQ,IAAM,MAAM,CAAC;IACrBC,OAAO,IAAM,MAAM,CAAC;IACpBC,SAAS,IAAM,MAAM,CAAC;IACtBC,OAAO,IAAM,MAAM,CAAC;IACpBC,MAAM,IAAM,MAAM,CAAC;IACnBC,KAAK,IAAM,MAAM,CAAC;IAClBC,MAAM,IAAM,MAAM,CAAC;AACrB,EAAE"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/init.ts"],"sourcesContent":["import { initConfig } from '../config.ts';\nimport type { Command } from './types.ts';\n\nconst init: Command = (ctx) => {\n const configPath = initConfig(process.cwd());\n console.log(`created ${configPath}`);\n console.log(`query away: ${ctx.name} query \"SELECT path FROM frontmatter LIMIT 10\"`);\n};\nexport default init;\n"],"names":["initConfig","init","ctx","configPath","process","cwd","console","log","name"],"mappings":"AAAA,SAASA,UAAU,QAAQ,eAAe;AAG1C,MAAMC,OAAgB,CAACC;IACrB,MAAMC,aAAaH,WAAWI,QAAQC,GAAG;IACzCC,QAAQC,GAAG,CAAC,CAAC,QAAQ,EAAEJ,YAAY;IACnCG,QAAQC,GAAG,CAAC,CAAC,YAAY,EAAEL,IAAIM,IAAI,CAAC,8CAA8C,CAAC;AACrF;AACA,eAAeP,KAAK"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/map.ts"],"sourcesContent":["import { renderMap } from '../output.ts';\nimport { mapTree } from '../verbs.ts';\nimport { withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst map: Command = (ctx) =>\n withDb(ctx, (db, cfg) => {\n const result = mapTree(db, cfg);\n console.log(ctx.format === 'json' ? JSON.stringify(result, null, 2) : renderMap(result));\n });\nexport default map;\n"],"names":["renderMap","mapTree","withDb","map","ctx","db","cfg","result","console","log","format","JSON","stringify"],"mappings":"AAAA,SAASA,SAAS,QAAQ,eAAe;AACzC,SAASC,OAAO,QAAQ,cAAc;AACtC,SAASC,MAAM,QAAQ,cAAc;AAGrC,MAAMC,MAAe,CAACC,MACpBF,OAAOE,KAAK,CAACC,IAAIC;QACf,MAAMC,SAASN,QAAQI,IAAIC;QAC3BE,QAAQC,GAAG,CAACL,IAAIM,MAAM,KAAK,SAASC,KAAKC,SAAS,CAACL,QAAQ,MAAM,KAAKP,UAAUO;IAClF;AACF,eAAeJ,IAAI"}
@@ -1,12 +0,0 @@
1
- import { runSql } from './shared.js';
2
- // Fallback when the first positional is not a command: a named query from config.
3
- export default function named(ctx, queryName, params) {
4
- const cfg = ctx.resolveConfig();
5
- const sql = cfg.queries[queryName];
6
- if (!sql) {
7
- console.error(`unknown query: "${queryName}"`);
8
- console.error(`valid queries: ${Object.keys(cfg.queries).sort().join(', ')}`);
9
- process.exit(2);
10
- }
11
- runSql(cfg, sql, params, ctx.format, `query "${queryName}"`);
12
- }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/named.ts"],"sourcesContent":["import { runSql } from './shared.ts';\nimport type { Ctx } from './types.ts';\n\n// Fallback when the first positional is not a command: a named query from config.\nexport default function named(ctx: Ctx, queryName: string, params: string[]): void {\n const cfg = ctx.resolveConfig();\n const sql = cfg.queries[queryName];\n if (!sql) {\n console.error(`unknown query: \"${queryName}\"`);\n console.error(`valid queries: ${Object.keys(cfg.queries).sort().join(', ')}`);\n process.exit(2);\n }\n runSql(cfg, sql, params, ctx.format, `query \"${queryName}\"`);\n}\n"],"names":["runSql","named","ctx","queryName","params","cfg","resolveConfig","sql","queries","console","error","Object","keys","sort","join","process","exit","format"],"mappings":"AAAA,SAASA,MAAM,QAAQ,cAAc;AAGrC,kFAAkF;AAClF,eAAe,SAASC,MAAMC,GAAQ,EAAEC,SAAiB,EAAEC,MAAgB;IACzE,MAAMC,MAAMH,IAAII,aAAa;IAC7B,MAAMC,MAAMF,IAAIG,OAAO,CAACL,UAAU;IAClC,IAAI,CAACI,KAAK;QACRE,QAAQC,KAAK,CAAC,CAAC,gBAAgB,EAAEP,UAAU,CAAC,CAAC;QAC7CM,QAAQC,KAAK,CAAC,CAAC,eAAe,EAAEC,OAAOC,IAAI,CAACP,IAAIG,OAAO,EAAEK,IAAI,GAAGC,IAAI,CAAC,OAAO;QAC5EC,QAAQC,IAAI,CAAC;IACf;IACAhB,OAAOK,KAAKE,KAAKH,QAAQF,IAAIe,MAAM,EAAE,CAAC,OAAO,EAAEd,UAAU,CAAC,CAAC;AAC7D"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/peek.ts"],"sourcesContent":["import { renderPeek } from '../output.ts';\nimport { peek } from '../verbs.ts';\nimport { withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst peekCmd: Command = (ctx) => {\n const [pathArg] = ctx.rest;\n if (!pathArg) ctx.usageError(`usage: ${ctx.name} peek <path>`);\n return withDb(ctx, (db, cfg) => {\n const result = peek(db, cfg, pathArg);\n console.log(ctx.format === 'json' ? JSON.stringify(result, null, 2) : renderPeek(result));\n });\n};\nexport default peekCmd;\n"],"names":["renderPeek","peek","withDb","peekCmd","ctx","pathArg","rest","usageError","name","db","cfg","result","console","log","format","JSON","stringify"],"mappings":"AAAA,SAASA,UAAU,QAAQ,eAAe;AAC1C,SAASC,IAAI,QAAQ,cAAc;AACnC,SAASC,MAAM,QAAQ,cAAc;AAGrC,MAAMC,UAAmB,CAACC;IACxB,MAAM,CAACC,QAAQ,GAAGD,IAAIE,IAAI;IAC1B,IAAI,CAACD,SAASD,IAAIG,UAAU,CAAC,CAAC,OAAO,EAAEH,IAAII,IAAI,CAAC,YAAY,CAAC;IAC7D,OAAON,OAAOE,KAAK,CAACK,IAAIC;QACtB,MAAMC,SAASV,KAAKQ,IAAIC,KAAKL;QAC7BO,QAAQC,GAAG,CAACT,IAAIU,MAAM,KAAK,SAASC,KAAKC,SAAS,CAACL,QAAQ,MAAM,KAAKX,WAAWW;IACnF;AACF;AACA,eAAeR,QAAQ"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/query.ts"],"sourcesContent":["import { runSql } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst query: Command = (ctx) => {\n const [sql, ...params] = ctx.rest;\n if (!sql) ctx.usageError(`usage: ${ctx.name} query \"<sql>\" [params...]`);\n runSql(ctx.resolveConfig(), sql, params, ctx.format, 'ad-hoc query');\n};\nexport default query;\n"],"names":["runSql","query","ctx","sql","params","rest","usageError","name","resolveConfig","format"],"mappings":"AAAA,SAASA,MAAM,QAAQ,cAAc;AAGrC,MAAMC,QAAiB,CAACC;IACtB,MAAM,CAACC,KAAK,GAAGC,OAAO,GAAGF,IAAIG,IAAI;IACjC,IAAI,CAACF,KAAKD,IAAII,UAAU,CAAC,CAAC,OAAO,EAAEJ,IAAIK,IAAI,CAAC,0BAA0B,CAAC;IACvEP,OAAOE,IAAIM,aAAa,IAAIL,KAAKC,QAAQF,IAAIO,MAAM,EAAE;AACvD;AACA,eAAeR,MAAM"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/rebuild.ts"],"sourcesContent":["import { docCount, rebuild } from '../db.ts';\nimport { printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst rebuildCmd: Command = (ctx) => {\n const result = rebuild(ctx.resolveConfig());\n printWarnings(result.warnings);\n console.log(`rebuilt: ${docCount(result.db)} docs`);\n result.db.close();\n};\nexport default rebuildCmd;\n"],"names":["docCount","rebuild","printWarnings","rebuildCmd","ctx","result","resolveConfig","warnings","console","log","db","close"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,OAAO,QAAQ,WAAW;AAC7C,SAASC,aAAa,QAAQ,cAAc;AAG5C,MAAMC,aAAsB,CAACC;IAC3B,MAAMC,SAASJ,QAAQG,IAAIE,aAAa;IACxCJ,cAAcG,OAAOE,QAAQ;IAC7BC,QAAQC,GAAG,CAAC,CAAC,SAAS,EAAET,SAASK,OAAOK,EAAE,EAAE,KAAK,CAAC;IAClDL,OAAOK,EAAE,CAACC,KAAK;AACjB;AACA,eAAeR,WAAW"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/shared.ts"],"sourcesContent":["import type { ResolvedConfig } from '../config.ts';\nimport type { OpenResult } from '../db.ts';\nimport { open } from '../db.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } from '../output.ts';\nimport { searchError } from '../search-error.ts';\nimport type { Ctx } from './types.ts';\n\n// Shared open-query-close envelope for commands that touch the tree.\n\nexport function printWarnings(warnings: string[]): void {\n for (const w of warnings) console.warn(w);\n}\n\nexport async function withDb(ctx: Ctx, fn: (db: OpenResult['db'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void> {\n const cfg = ctx.resolveConfig();\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n try {\n await fn(db, cfg);\n } finally {\n db.close();\n }\n}\n\n// An unbound `?` silently binds NULL, so mismatched param counts fail loudly instead.\nexport function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: 'table' | 'json', label: string): void {\n const placeholderCount = (sql.match(/\\?/g) ?? []).length;\n if (params.length !== placeholderCount) {\n console.error(`${label} expects ${placeholderCount} parameter(s), got ${params.length}`);\n process.exit(2);\n }\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n let rows: Row[];\n try {\n rows = db.prepare(sql).all(...params) as Row[];\n } catch (err) {\n db.close();\n // A saved query or ad-hoc SQL can carry `content MATCH ?` too, so the same FTS5\n // punctuation trap applies -- the bound parameters are the search terms there. SQL\n // without MATCH gets its error verbatim; search advice on a plain typo would mislead.\n if (/\\bMATCH\\b/i.test(sql)) throw searchError(err as Error, params.join(' '));\n throw err;\n }\n printRows(rows, format);\n db.close();\n}\n"],"names":["open","printRows","searchError","printWarnings","warnings","w","console","warn","withDb","ctx","fn","cfg","resolveConfig","db","close","runSql","sql","params","format","label","placeholderCount","match","length","error","process","exit","rows","prepare","all","err","test","join"],"mappings":"AAEA,SAASA,IAAI,QAAQ,WAAW;AAEhC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,WAAW,QAAQ,qBAAqB;AAGjD,qEAAqE;AAErE,OAAO,SAASC,cAAcC,QAAkB;IAC9C,KAAK,MAAMC,KAAKD,SAAUE,QAAQC,IAAI,CAACF;AACzC;AAEA,OAAO,eAAeG,OAAOC,GAAQ,EAAEC,EAAuE;IAC5G,MAAMC,MAAMF,IAAIG,aAAa;IAC7B,MAAM,EAAEC,EAAE,EAAET,QAAQ,EAAE,GAAGJ,KAAKW;IAC9BR,cAAcC;IACd,IAAI;QACF,MAAMM,GAAGG,IAAIF;IACf,SAAU;QACRE,GAAGC,KAAK;IACV;AACF;AAEA,sFAAsF;AACtF,OAAO,SAASC,OAAOJ,GAAmB,EAAEK,GAAW,EAAEC,MAAgB,EAAEC,MAAwB,EAAEC,KAAa;QACtFH;IAA1B,MAAMI,mBAAmB,EAACJ,aAAAA,IAAIK,KAAK,CAAC,oBAAVL,wBAAAA,aAAoB,EAAE,EAAEM,MAAM;IACxD,IAAIL,OAAOK,MAAM,KAAKF,kBAAkB;QACtCd,QAAQiB,KAAK,CAAC,GAAGJ,MAAM,SAAS,EAAEC,iBAAiB,mBAAmB,EAAEH,OAAOK,MAAM,EAAE;QACvFE,QAAQC,IAAI,CAAC;IACf;IACA,MAAM,EAAEZ,EAAE,EAAET,QAAQ,EAAE,GAAGJ,KAAKW;IAC9BR,cAAcC;IACd,IAAIsB;IACJ,IAAI;QACFA,OAAOb,GAAGc,OAAO,CAACX,KAAKY,GAAG,IAAIX;IAChC,EAAE,OAAOY,KAAK;QACZhB,GAAGC,KAAK;QACR,gFAAgF;QAChF,mFAAmF;QACnF,sFAAsF;QACtF,IAAI,aAAagB,IAAI,CAACd,MAAM,MAAMd,YAAY2B,KAAcZ,OAAOc,IAAI,CAAC;QACxE,MAAMF;IACR;IACA5B,UAAUyB,MAAMR;IAChBL,GAAGC,KAAK;AACV"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/status.ts"],"sourcesContent":["import { embedConfig, featureStates } from '../config.ts';\nimport { docCount, getMeta, open } from '../db.ts';\nimport { printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// Vectors are computed on the first semantic query, not at reconcile, so a tree can be\n// embed-enabled with nothing embedded yet -- reported here because a fast `rebuild` on an\n// embed tree otherwise reads as \"the feature isn't on\".\nfunction vectorState(db: ReturnType<typeof open>['db']): { embedded: number; pending: number } | null {\n try {\n const row = db.prepare('SELECT COUNT(vector) AS embedded, COUNT(*) - COUNT(vector) AS pending FROM embeddings').get() as { embedded: number; pending: number };\n return row;\n } catch {\n return null;\n }\n}\n\nconst status: Command = (ctx) => {\n const cfg = ctx.resolveConfig();\n const { db, dbPath, warnings } = open(cfg);\n printWarnings(warnings);\n\n const features = featureStates(cfg);\n const e = embedConfig(cfg);\n const vectors = e ? vectorState(db) : null;\n const heartbeat = getMeta(db, 'watch_heartbeat');\n const result = {\n db: dbPath,\n docs: docCount(db),\n features: features.on,\n featuresOff: features.off,\n embed: e ? { type: e.type, model: e.model, ...(vectors ?? {}) } : null,\n findDefaultWhere: cfg.defaults?.find?.where ?? null,\n watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null,\n };\n\n if (ctx.format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(`db: ${result.db}`);\n console.log(`docs: ${result.docs}`);\n const off = features.off.length > 0 ? ` · off: ${features.off.map((name) => `${name} (features.${name})`).join(', ')}` : '';\n console.log(`features: ${features.on.join(', ')}${off}`);\n if (e) console.log(`embed: ${e.type} ${e.model}${vectors ? ` (vectors: ${vectors.embedded} embedded, ${vectors.pending} pending — embedded on first --semantic query)` : ''}`);\n if (result.findDefaultWhere) console.log(`find default scope: ${result.findDefaultWhere} (--where replaces it)`);\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: no watcher' : `watcher: last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n }\n db.close();\n};\nexport default status;\n"],"names":["embedConfig","featureStates","docCount","getMeta","open","printWarnings","vectorState","db","row","prepare","get","status","ctx","cfg","resolveConfig","dbPath","warnings","features","e","vectors","heartbeat","result","docs","on","featuresOff","off","embed","type","model","findDefaultWhere","defaults","find","where","watcherHeartbeatSecondsAgo","Math","round","Date","now","parse","format","console","log","JSON","stringify","length","map","name","join","embedded","pending","close"],"mappings":"AAAA,SAASA,WAAW,EAAEC,aAAa,QAAQ,eAAe;AAC1D,SAASC,QAAQ,EAAEC,OAAO,EAAEC,IAAI,QAAQ,WAAW;AACnD,SAASC,aAAa,QAAQ,cAAc;AAG5C,uFAAuF;AACvF,0FAA0F;AAC1F,wDAAwD;AACxD,SAASC,YAAYC,EAAiC;IACpD,IAAI;QACF,MAAMC,MAAMD,GAAGE,OAAO,CAAC,yFAAyFC,GAAG;QACnH,OAAOF;IACT,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,MAAMG,SAAkB,CAACC;;QAeHC,oBAAAA;IAdpB,MAAMA,MAAMD,IAAIE,aAAa;IAC7B,MAAM,EAAEP,EAAE,EAAEQ,MAAM,EAAEC,QAAQ,EAAE,GAAGZ,KAAKS;IACtCR,cAAcW;IAEd,MAAMC,WAAWhB,cAAcY;IAC/B,MAAMK,IAAIlB,YAAYa;IACtB,MAAMM,UAAUD,IAAIZ,YAAYC,MAAM;IACtC,MAAMa,YAAYjB,QAAQI,IAAI;IAC9B,MAAMc,SAAS;QACbd,IAAIQ;QACJO,MAAMpB,SAASK;QACfU,UAAUA,SAASM,EAAE;QACrBC,aAAaP,SAASQ,GAAG;QACzBC,OAAOR,IAAI;YAAES,MAAMT,EAAES,IAAI;YAAEC,OAAOV,EAAEU,KAAK;eAAMT,oBAAAA,qBAAAA,UAAW,CAAC,CAAhB;QAAmB,IAAI;QAClEU,gBAAgB,WAAEhB,gBAAAA,IAAIiB,QAAQ,cAAZjB,qCAAAA,qBAAAA,cAAckB,IAAI,cAAlBlB,yCAAAA,mBAAoBmB,KAAK,uCAAI;QAC/CC,4BAA4Bb,YAAYc,KAAKC,KAAK,CAAC,AAACC,CAAAA,KAAKC,GAAG,KAAKD,KAAKE,KAAK,CAAClB,UAAS,IAAK,QAAQ;IACpG;IAEA,IAAIR,IAAI2B,MAAM,KAAK,QAAQ;QACzBC,QAAQC,GAAG,CAACC,KAAKC,SAAS,CAACtB,QAAQ,MAAM;IAC3C,OAAO;QACLmB,QAAQC,GAAG,CAAC,CAAC,IAAI,EAAEpB,OAAOd,EAAE,EAAE;QAC9BiC,QAAQC,GAAG,CAAC,CAAC,MAAM,EAAEpB,OAAOC,IAAI,EAAE;QAClC,MAAMG,MAAMR,SAASQ,GAAG,CAACmB,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE3B,SAASQ,GAAG,CAACoB,GAAG,CAAC,CAACC,OAAS,GAAGA,KAAK,WAAW,EAAEA,KAAK,CAAC,CAAC,EAAEC,IAAI,CAAC,OAAO,GAAG;QACzHP,QAAQC,GAAG,CAAC,CAAC,UAAU,EAAExB,SAASM,EAAE,CAACwB,IAAI,CAAC,QAAQtB,KAAK;QACvD,IAAIP,GAAGsB,QAAQC,GAAG,CAAC,CAAC,OAAO,EAAEvB,EAAES,IAAI,CAAC,CAAC,EAAET,EAAEU,KAAK,GAAGT,UAAU,CAAC,WAAW,EAAEA,QAAQ6B,QAAQ,CAAC,WAAW,EAAE7B,QAAQ8B,OAAO,CAAC,8CAA8C,CAAC,GAAG,IAAI;QAC7K,IAAI5B,OAAOQ,gBAAgB,EAAEW,QAAQC,GAAG,CAAC,CAAC,oBAAoB,EAAEpB,OAAOQ,gBAAgB,CAAC,sBAAsB,CAAC;QAC/GW,QAAQC,GAAG,CAACpB,OAAOY,0BAA0B,KAAK,OAAO,wBAAwB,CAAC,wBAAwB,EAAEZ,OAAOY,0BAA0B,CAAC,KAAK,CAAC;IACtJ;IACA1B,GAAG2C,KAAK;AACV;AACA,eAAevC,OAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/types.ts"],"sourcesContent":["import type { ResolvedConfig } from '../config.ts';\n\n// Handed to every command; argv parsing stays in cli.ts.\nexport interface Ctx {\n name: string;\n rest: string[]; // positionals after the command word\n format: 'table' | 'json';\n values: { config?: string; where?: string; k?: string; force: boolean; semantic: boolean };\n resolveConfig(): ResolvedConfig;\n usageError(message: string): never;\n}\n\nexport type Command = (ctx: Ctx) => Promise<void> | void;\n"],"names":[],"mappings":"AAYA,WAAyD"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/watch.ts"],"sourcesContent":["import type { WatchEvent } from '../watch.ts';\nimport { runWatch } from '../watch.ts';\nimport { printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst watch: Command = async (ctx) => {\n await runWatch(ctx.resolveConfig(), {\n force: ctx.values.force,\n onEvent: (event: WatchEvent) => {\n if (event.type === 'started') {\n console.log(`${ctx.name} watch: watching ${event.baseDir}`);\n console.log(`${ctx.name} watch: db ${event.dbPath}`);\n } else if (event.type === 'reconciled') {\n printWarnings(event.warnings);\n if (event.parsed > 0) console.log(`${ctx.name} watch: reconciled, ${event.parsed} file(s) reparsed (${event.total} total)`);\n } else {\n console.error(`${ctx.name} watch: reconcile error: ${event.message}`);\n }\n },\n });\n};\nexport default watch;\n"],"names":["runWatch","printWarnings","watch","ctx","resolveConfig","force","values","onEvent","event","type","console","log","name","baseDir","dbPath","warnings","parsed","total","error","message"],"mappings":"AACA,SAASA,QAAQ,QAAQ,cAAc;AACvC,SAASC,aAAa,QAAQ,cAAc;AAG5C,MAAMC,QAAiB,OAAOC;IAC5B,MAAMH,SAASG,IAAIC,aAAa,IAAI;QAClCC,OAAOF,IAAIG,MAAM,CAACD,KAAK;QACvBE,SAAS,CAACC;YACR,IAAIA,MAAMC,IAAI,KAAK,WAAW;gBAC5BC,QAAQC,GAAG,CAAC,GAAGR,IAAIS,IAAI,CAAC,iBAAiB,EAAEJ,MAAMK,OAAO,EAAE;gBAC1DH,QAAQC,GAAG,CAAC,GAAGR,IAAIS,IAAI,CAAC,WAAW,EAAEJ,MAAMM,MAAM,EAAE;YACrD,OAAO,IAAIN,MAAMC,IAAI,KAAK,cAAc;gBACtCR,cAAcO,MAAMO,QAAQ;gBAC5B,IAAIP,MAAMQ,MAAM,GAAG,GAAGN,QAAQC,GAAG,CAAC,GAAGR,IAAIS,IAAI,CAAC,oBAAoB,EAAEJ,MAAMQ,MAAM,CAAC,mBAAmB,EAAER,MAAMS,KAAK,CAAC,OAAO,CAAC;YAC5H,OAAO;gBACLP,QAAQQ,KAAK,CAAC,GAAGf,IAAIS,IAAI,CAAC,yBAAyB,EAAEJ,MAAMW,OAAO,EAAE;YACtE;QACF;IACF;AACF;AACA,eAAejB,MAAM"}
package/dist/esm/verbs.js DELETED
@@ -1,190 +0,0 @@
1
- import posix from 'node:path/posix';
2
- import { featureEnabled, featureStates } from './config.js';
3
- import { SenseError } from './errors.js';
4
- import { semanticCandidates } from './features/embed.js';
5
- import { linkEdges } from './features/index.js';
6
- import { personalizedRank } from './graph.js';
7
- import { searchError } from './search-error.js';
8
- // The three layer verbs: mapTree (orient), find (locate), peek (structure).
9
- // Each returns data; cli.ts renders. All of them degrade when a feature is off.
10
- const WEIGHTED_BM25 = 'bm25(content, 10.0, 5.0, 1.0)';
11
- const RRF_K = 60;
12
- // Layer 1: BM25 + link-graph expansion, fused by reciprocal rank. `via` says which
13
- // signal produced each row so the agent knows what evidence it is trusting.
14
- // Semantic expansion is per-query opt-in: without opts.semantic the result is
15
- // byte-for-byte independent of the embed feature.
16
- export async function find(db, cfg, terms, opts = {}) {
17
- var _opts_k, _opts_where, _hits_get, _chunkLines_get, _chunkSimilarity_get;
18
- var _cfg_defaults_find, _cfg_defaults;
19
- const k = (_opts_k = opts.k) !== null && _opts_k !== void 0 ? _opts_k : 10;
20
- const fetch = Math.max(k * 3, 30);
21
- // Terms pass verbatim to FTS5 MATCH: bare words AND-join, operators are the caller's.
22
- // Invalid syntax propagates as an error, zero matches return zero -- no silent rewrites.
23
- // --where applies inside the candidate query (a post-filter over the top-N would drop
24
- // matches ranked past the pool) and again on the final select for link-derived rows.
25
- // An explicit --where replaces the tree's declared default rather than ANDing with it,
26
- // so a caller can always widen back to the whole tree.
27
- const scope = (_opts_where = opts.where) !== null && _opts_where !== void 0 ? _opts_where : (_cfg_defaults = cfg.defaults) === null || _cfg_defaults === void 0 ? void 0 : (_cfg_defaults_find = _cfg_defaults.find) === null || _cfg_defaults_find === void 0 ? void 0 : _cfg_defaults_find.where;
28
- const whereJoin = scope ? `JOIN frontmatter f ON f."path" = content.path` : '';
29
- const whereCond = scope ? `AND (${scope})` : '';
30
- const matchSql = `SELECT content.path AS path, snippet(content, -1, '«', '»', '…', 10) AS hit FROM content ${whereJoin} WHERE content MATCH ? ${whereCond} ORDER BY ${WEIGHTED_BM25} LIMIT ${fetch}`;
31
- let matchRows;
32
- try {
33
- matchRows = db.prepare(matchSql).all(terms);
34
- } catch (err) {
35
- throw searchError(err, terms, scope);
36
- }
37
- const hits = new Map(matchRows.map((r)=>[
38
- r.path,
39
- r.hit
40
- ]));
41
- const candidates = new Map();
42
- matchRows.forEach((r, i)=>{
43
- candidates.set(r.path, {
44
- score: 1 / (RRF_K + i),
45
- via: 'match'
46
- });
47
- });
48
- const edges = featureEnabled(cfg, 'links') && matchRows.length > 0 ? linkEdges(db) : [];
49
- if (edges.length > 0) {
50
- // `linked` gates the label only, not the score: PPR restart mass gives every seed a
51
- // nonzero rank even without an incident edge, which is not link evidence — but dropping
52
- // that mass from the score list reweights fusion toward connectivity and measurably
53
- // wrecks ranking on link-dense corpora (FEVER hit@10 0.997 -> 0.907; fusion-tuning.md).
54
- const linked = new Set(edges.flat());
55
- const nodes = db.prepare('SELECT "path" FROM frontmatter').all().map((r)=>r.path);
56
- const seeds = new Map(matchRows.map((r, i)=>[
57
- r.path,
58
- 1 / (i + 1)
59
- ]));
60
- const ranked = [
61
- ...personalizedRank(nodes, edges, seeds)
62
- ].filter(([, score])=>score > 1e-9).sort((a, b)=>b[1] - a[1]).slice(0, fetch);
63
- ranked.forEach(([path], i)=>{
64
- const existing = candidates.get(path);
65
- if (existing) {
66
- existing.score += 1 / (RRF_K + i);
67
- if (linked.has(path)) existing.via = 'match+link';
68
- } else {
69
- candidates.set(path, {
70
- score: 1 / (RRF_K + i),
71
- via: 'link'
72
- });
73
- }
74
- });
75
- }
76
- // Vector expansion, invoked only: a third RRF list at the swept flat-region constants
77
- // (weight 1, pool = fetch). Each row carries its best chunk's line range.
78
- const chunkLines = new Map();
79
- const chunkSimilarity = new Map();
80
- if (opts.semantic) {
81
- const vec = await semanticCandidates(db, cfg, terms, fetch);
82
- vec.forEach(({ path, lines, similarity }, i)=>{
83
- chunkLines.set(path, lines);
84
- chunkSimilarity.set(path, similarity);
85
- const existing = candidates.get(path);
86
- if (existing) {
87
- existing.score += 1 / (RRF_K + i);
88
- existing.via = `${existing.via}+vector`;
89
- } else {
90
- candidates.set(path, {
91
- score: 1 / (RRF_K + i),
92
- via: 'vector'
93
- });
94
- }
95
- });
96
- }
97
- db.exec('DROP TABLE IF EXISTS _find');
98
- db.exec('CREATE TEMP TABLE _find ("path" TEXT PRIMARY KEY, score REAL, via TEXT, hit TEXT, lines TEXT, similarity REAL)');
99
- const insert = db.prepare('INSERT INTO _find ("path", score, via, hit, lines, similarity) VALUES (?, ?, ?, ?, ?, ?)');
100
- for (const [path, c] of candidates)insert.run(path, c.score, c.via, (_hits_get = hits.get(path)) !== null && _hits_get !== void 0 ? _hits_get : null, (_chunkLines_get = chunkLines.get(path)) !== null && _chunkLines_get !== void 0 ? _chunkLines_get : null, (_chunkSimilarity_get = chunkSimilarity.get(path)) !== null && _chunkSimilarity_get !== void 0 ? _chunkSimilarity_get : null);
101
- const where = scope ? `WHERE ${scope}` : '';
102
- const linesCol = opts.semantic ? ', _find.lines, _find.similarity' : '';
103
- return db.prepare(`SELECT f."path" AS path, content.title, content.summary, _find.hit, _find.via, round(_find.score, 4) AS score${linesCol}
104
- FROM _find JOIN frontmatter f ON f."path" = _find."path" JOIN content ON content.path = _find."path"
105
- ${where} ORDER BY _find.score DESC LIMIT ?`).all(k);
106
- }
107
- const INTERNAL_COLUMNS = new Set([
108
- 'path',
109
- '_mtime',
110
- '_size',
111
- '_rank'
112
- ]);
113
- // Layer 0: what is this tree. Fixed-size output regardless of tree size.
114
- export function mapTree(db, cfg) {
115
- const docs = db.prepare('SELECT COUNT(*) AS count, COALESCE(SUM("_size"), 0) AS bytes FROM frontmatter').get();
116
- const columns = db.prepare('PRAGMA table_info(frontmatter)').all().map((r)=>r.name).filter((name)=>!INTERNAL_COLUMNS.has(name));
117
- const allFields = columns.map((name)=>{
118
- const quoted = `"${name.split('"').join('""')}"`;
119
- // Observed storage class, not a declared one: these columns are added dynamically and
120
- // SQLite types per value, so a field can be text in most notes and numeric in a few.
121
- // Listing every distinct type makes both the type and any drift visible.
122
- const { n, types } = db.prepare(`SELECT COUNT(${quoted}) AS n, GROUP_CONCAT(DISTINCT typeof(${quoted})) AS types FROM frontmatter WHERE ${quoted} IS NOT NULL`).get();
123
- return {
124
- field: name,
125
- coverage: n,
126
- type: types !== null && types !== void 0 ? types : ''
127
- };
128
- }).sort((a, b)=>b.coverage - a.coverage);
129
- const fields = allFields.slice(0, 20);
130
- const hubs = featureEnabled(cfg, 'rank') ? db.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 ORDER BY f."_rank" DESC LIMIT 8`).all() : [];
131
- const recent = db.prepare(`SELECT "path", datetime("_mtime" / 1000, 'unixepoch') AS modified FROM frontmatter ORDER BY "_mtime" DESC LIMIT 5`).all();
132
- return {
133
- docs,
134
- fields,
135
- fieldsTotal: allFields.length,
136
- features: featureStates(cfg),
137
- hubs,
138
- recent
139
- };
140
- }
141
- const PEEK_LINK_LIMIT = 20;
142
- // Layer 2: everything about one note except its prose -- frontmatter, outline with line
143
- // ranges + token estimates (so the follow-up Read is a range, not the file), links both ways.
144
- export function peek(db, cfg, pathArg) {
145
- var _row__size;
146
- const paths = db.prepare('SELECT "path" FROM frontmatter').all().map((r)=>r.path);
147
- let path = paths.find((p)=>p === pathArg);
148
- if (!path) {
149
- const base = posix.basename(pathArg).replace(/\.md$/i, '').toLowerCase();
150
- const matches = paths.filter((p)=>posix.basename(p).replace(/\.md$/i, '').toLowerCase() === base);
151
- if (matches.length === 1) path = matches[0];
152
- else if (matches.length > 1) throw new SenseError('NOTE_AMBIGUOUS', `"${pathArg}" is ambiguous: ${matches.join(', ')}`);
153
- else throw new SenseError('NOTE_NOT_FOUND', `no note matches "${pathArg}"`);
154
- }
155
- const row = db.prepare('SELECT * FROM frontmatter WHERE "path" = ?').get(path);
156
- const frontmatter = {};
157
- for (const [key, value] of Object.entries(row)){
158
- if (!INTERNAL_COLUMNS.has(key) && value !== null) frontmatter[key] = value;
159
- }
160
- const sections = featureEnabled(cfg, 'sections') ? db.prepare('SELECT level, heading, start_line, end_line, tokens FROM sections WHERE "path" = ? ORDER BY idx').all(path) : [];
161
- let outbound = [];
162
- let backlinks = [];
163
- let unresolved = [];
164
- let backlinksTotal = 0;
165
- if (featureEnabled(cfg, 'links')) {
166
- const out = db.prepare('SELECT target, dst FROM links WHERE src = ? ORDER BY target').all(path);
167
- outbound = [
168
- ...new Set(out.filter((l)=>l.dst !== null).map((l)=>l.dst))
169
- ];
170
- unresolved = out.filter((l)=>l.dst === null).map((l)=>l.target);
171
- backlinksTotal = db.prepare('SELECT COUNT(DISTINCT src) AS n FROM links WHERE dst = ?').get(path).n;
172
- backlinks = db.prepare('SELECT DISTINCT src FROM links WHERE dst = ? ORDER BY src LIMIT ?').all(path, PEEK_LINK_LIMIT).map((r)=>r.src);
173
- }
174
- return {
175
- path,
176
- tokens: Math.ceil(((_row__size = row._size) !== null && _row__size !== void 0 ? _row__size : 0) / 4),
177
- frontmatter,
178
- sections,
179
- outbound: outbound.slice(0, PEEK_LINK_LIMIT),
180
- backlinks,
181
- unresolved: unresolved.slice(0, PEEK_LINK_LIMIT),
182
- outboundTotal: outbound.length,
183
- backlinksTotal,
184
- unresolvedTotal: unresolved.length,
185
- off: [
186
- 'sections',
187
- 'links'
188
- ].filter((name)=>!featureEnabled(cfg, name))
189
- };
190
- }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/verbs.ts"],"sourcesContent":["import posix from 'node:path/posix';\nimport type { DatabaseSync } from 'node:sqlite';\nimport type { Config, FeatureName } from './config.ts';\nimport { featureEnabled, featureStates } from './config.ts';\nimport { SenseError } from './errors.ts';\nimport { semanticCandidates } from './features/embed.ts';\nimport { linkEdges } from './features/index.ts';\nimport { personalizedRank } from './graph.ts';\nimport type { Row } from './output.ts';\nimport { searchError } from './search-error.ts';\n\n// The three layer verbs: mapTree (orient), find (locate), peek (structure).\n// Each returns data; cli.ts renders. All of them degrade when a feature is off.\n\nconst WEIGHTED_BM25 = 'bm25(content, 10.0, 5.0, 1.0)';\nconst RRF_K = 60;\n\nexport interface FindOptions {\n k?: number;\n where?: string; // SQL fragment against frontmatter alias `f`, e.g. \"f.status = 'active'\"\n semantic?: boolean; // invoke vector expansion (requires features.embed); rows gain via 'vector' and a lines column\n}\n\n// Layer 1: BM25 + link-graph expansion, fused by reciprocal rank. `via` says which\n// signal produced each row so the agent knows what evidence it is trusting.\n// Semantic expansion is per-query opt-in: without opts.semantic the result is\n// byte-for-byte independent of the embed feature.\nexport async function find(db: DatabaseSync, cfg: Config, terms: string, opts: FindOptions = {}): Promise<Row[]> {\n const k = opts.k ?? 10;\n const fetch = Math.max(k * 3, 30);\n\n // Terms pass verbatim to FTS5 MATCH: bare words AND-join, operators are the caller's.\n // Invalid syntax propagates as an error, zero matches return zero -- no silent rewrites.\n // --where applies inside the candidate query (a post-filter over the top-N would drop\n // matches ranked past the pool) and again on the final select for link-derived rows.\n // An explicit --where replaces the tree's declared default rather than ANDing with it,\n // so a caller can always widen back to the whole tree.\n const scope = opts.where ?? cfg.defaults?.find?.where;\n const whereJoin = scope ? `JOIN frontmatter f ON f.\"path\" = content.path` : '';\n const whereCond = scope ? `AND (${scope})` : '';\n const matchSql = `SELECT content.path AS path, snippet(content, -1, '«', '»', '…', 10) AS hit FROM content ${whereJoin} WHERE content MATCH ? ${whereCond} ORDER BY ${WEIGHTED_BM25} LIMIT ${fetch}`;\n let matchRows: Array<{ path: string; hit: string }>;\n try {\n matchRows = db.prepare(matchSql).all(terms) as Array<{ path: string; hit: string }>;\n } catch (err) {\n throw searchError(err as Error, terms, scope);\n }\n\n const hits = new Map(matchRows.map((r) => [r.path, r.hit]));\n const candidates = new Map<string, { score: number; via: string }>();\n matchRows.forEach((r, i) => {\n candidates.set(r.path, { score: 1 / (RRF_K + i), via: 'match' });\n });\n\n const edges = featureEnabled(cfg, 'links') && matchRows.length > 0 ? linkEdges(db) : [];\n if (edges.length > 0) {\n // `linked` gates the label only, not the score: PPR restart mass gives every seed a\n // nonzero rank even without an incident edge, which is not link evidence — but dropping\n // that mass from the score list reweights fusion toward connectivity and measurably\n // wrecks ranking on link-dense corpora (FEVER hit@10 0.997 -> 0.907; fusion-tuning.md).\n const linked = new Set(edges.flat());\n const nodes = (db.prepare('SELECT \"path\" FROM frontmatter').all() as Array<{ path: string }>).map((r) => r.path);\n const seeds = new Map(matchRows.map((r, i) => [r.path, 1 / (i + 1)]));\n const ranked = [...personalizedRank(nodes, edges, seeds)]\n .filter(([, score]) => score > 1e-9)\n .sort((a, b) => b[1] - a[1])\n .slice(0, fetch);\n ranked.forEach(([path], i) => {\n const existing = candidates.get(path);\n if (existing) {\n existing.score += 1 / (RRF_K + i);\n if (linked.has(path)) existing.via = 'match+link';\n } else {\n candidates.set(path, { score: 1 / (RRF_K + i), via: 'link' });\n }\n });\n }\n\n // Vector expansion, invoked only: a third RRF list at the swept flat-region constants\n // (weight 1, pool = fetch). Each row carries its best chunk's line range.\n const chunkLines = new Map<string, string>();\n const chunkSimilarity = new Map<string, number>();\n if (opts.semantic) {\n const vec = await semanticCandidates(db, cfg, terms, fetch);\n vec.forEach(({ path, lines, similarity }, i) => {\n chunkLines.set(path, lines);\n chunkSimilarity.set(path, similarity);\n const existing = candidates.get(path);\n if (existing) {\n existing.score += 1 / (RRF_K + i);\n existing.via = `${existing.via}+vector`;\n } else {\n candidates.set(path, { score: 1 / (RRF_K + i), via: 'vector' });\n }\n });\n }\n\n db.exec('DROP TABLE IF EXISTS _find');\n db.exec('CREATE TEMP TABLE _find (\"path\" TEXT PRIMARY KEY, score REAL, via TEXT, hit TEXT, lines TEXT, similarity REAL)');\n const insert = db.prepare('INSERT INTO _find (\"path\", score, via, hit, lines, similarity) VALUES (?, ?, ?, ?, ?, ?)');\n for (const [path, c] of candidates) insert.run(path, c.score, c.via, hits.get(path) ?? null, chunkLines.get(path) ?? null, chunkSimilarity.get(path) ?? null);\n\n const where = scope ? `WHERE ${scope}` : '';\n const linesCol = opts.semantic ? ', _find.lines, _find.similarity' : '';\n return db\n .prepare(\n `SELECT f.\"path\" AS path, content.title, content.summary, _find.hit, _find.via, round(_find.score, 4) AS score${linesCol}\n FROM _find JOIN frontmatter f ON f.\"path\" = _find.\"path\" JOIN content ON content.path = _find.\"path\"\n ${where} ORDER BY _find.score DESC LIMIT ?`\n )\n .all(k) as Row[];\n}\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 hubs: Row[];\n recent: Row[];\n}\n\nconst INTERNAL_COLUMNS = new Set(['path', '_mtime', '_size', '_rank']);\n\n// Layer 0: what is this tree. Fixed-size output regardless of tree size.\nexport function mapTree(db: DatabaseSync, cfg: Config): TreeMap {\n const docs = db.prepare('SELECT COUNT(*) AS count, COALESCE(SUM(\"_size\"), 0) AS bytes FROM frontmatter').get() as { count: number; bytes: number };\n\n const columns = (db.prepare('PRAGMA table_info(frontmatter)').all() as Array<{ name: string }>).map((r) => r.name).filter((name) => !INTERNAL_COLUMNS.has(name));\n const allFields = columns\n .map((name) => {\n const quoted = `\"${name.split('\"').join('\"\"')}\"`;\n // Observed storage class, not a declared one: these columns are added dynamically and\n // SQLite types per value, so a field can be text in most notes and numeric in a few.\n // Listing every distinct type makes both the type and any drift visible.\n const { n, types } = db.prepare(`SELECT COUNT(${quoted}) AS n, GROUP_CONCAT(DISTINCT typeof(${quoted})) AS types FROM frontmatter WHERE ${quoted} IS NOT NULL`).get() as { n: number; types: string | null };\n return { field: name, coverage: n, type: types ?? '' };\n })\n .sort((a, b) => (b.coverage as number) - (a.coverage as number)) as Row[];\n const fields = allFields.slice(0, 20);\n\n const hubs = featureEnabled(cfg, 'rank') ? (db.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 ORDER BY f.\"_rank\" DESC LIMIT 8`).all() as Row[]) : [];\n\n const recent = db.prepare(`SELECT \"path\", datetime(\"_mtime\" / 1000, 'unixepoch') AS modified FROM frontmatter ORDER BY \"_mtime\" DESC LIMIT 5`).all() as Row[];\n\n return { docs, fields, fieldsTotal: allFields.length, features: featureStates(cfg), hubs, recent };\n}\n\nexport interface Peek {\n path: string;\n tokens: number;\n frontmatter: Row;\n sections: Row[];\n outbound: string[];\n backlinks: string[];\n unresolved: string[];\n // Totals before truncation: a hub can have thousands of backlinks, and peek's whole\n // point is bounded output. Query the links table directly for the full list.\n outboundTotal: number;\n backlinksTotal: number;\n unresolvedTotal: number;\n off: FeatureName[]; // disabled features whose blocks are omitted (not empty)\n}\n\nconst PEEK_LINK_LIMIT = 20;\n\n// Layer 2: everything about one note except its prose -- frontmatter, outline with line\n// ranges + token estimates (so the follow-up Read is a range, not the file), links both ways.\nexport function peek(db: DatabaseSync, cfg: Config, pathArg: string): Peek {\n const paths = (db.prepare('SELECT \"path\" FROM frontmatter').all() as Array<{ path: string }>).map((r) => r.path);\n let path = paths.find((p) => p === pathArg);\n if (!path) {\n const base = posix.basename(pathArg).replace(/\\.md$/i, '').toLowerCase();\n const matches = paths.filter((p) => posix.basename(p).replace(/\\.md$/i, '').toLowerCase() === base);\n if (matches.length === 1) path = matches[0];\n else if (matches.length > 1) throw new SenseError('NOTE_AMBIGUOUS', `\"${pathArg}\" is ambiguous: ${matches.join(', ')}`);\n else throw new SenseError('NOTE_NOT_FOUND', `no note matches \"${pathArg}\"`);\n }\n\n const row = db.prepare('SELECT * FROM frontmatter WHERE \"path\" = ?').get(path) as Row;\n const frontmatter: Row = {};\n for (const [key, value] of Object.entries(row)) {\n if (!INTERNAL_COLUMNS.has(key) && value !== null) frontmatter[key] = value;\n }\n\n const sections = featureEnabled(cfg, 'sections') ? (db.prepare('SELECT level, heading, start_line, end_line, tokens FROM sections WHERE \"path\" = ? ORDER BY idx').all(path) as Row[]) : [];\n\n let outbound: string[] = [];\n let backlinks: string[] = [];\n let unresolved: string[] = [];\n let backlinksTotal = 0;\n if (featureEnabled(cfg, 'links')) {\n const out = db.prepare('SELECT target, dst FROM links WHERE src = ? ORDER BY target').all(path) as Array<{ target: string; dst: string | null }>;\n outbound = [...new Set(out.filter((l) => l.dst !== null).map((l) => l.dst as string))];\n unresolved = out.filter((l) => l.dst === null).map((l) => l.target);\n backlinksTotal = (db.prepare('SELECT COUNT(DISTINCT src) AS n FROM links WHERE dst = ?').get(path) as { n: number }).n;\n backlinks = (db.prepare('SELECT DISTINCT src FROM links WHERE dst = ? ORDER BY src LIMIT ?').all(path, PEEK_LINK_LIMIT) as Array<{ src: string }>).map((r) => r.src);\n }\n\n return {\n path,\n tokens: Math.ceil(((row._size as number) ?? 0) / 4),\n frontmatter,\n sections,\n outbound: outbound.slice(0, PEEK_LINK_LIMIT),\n backlinks,\n unresolved: unresolved.slice(0, PEEK_LINK_LIMIT),\n outboundTotal: outbound.length,\n backlinksTotal,\n unresolvedTotal: unresolved.length,\n off: (['sections', 'links'] as FeatureName[]).filter((name) => !featureEnabled(cfg, name)),\n };\n}\n"],"names":["posix","featureEnabled","featureStates","SenseError","semanticCandidates","linkEdges","personalizedRank","searchError","WEIGHTED_BM25","RRF_K","find","db","cfg","terms","opts","hits","chunkLines","chunkSimilarity","k","fetch","Math","max","scope","where","defaults","whereJoin","whereCond","matchSql","matchRows","prepare","all","err","Map","map","r","path","hit","candidates","forEach","i","set","score","via","edges","length","linked","Set","flat","nodes","seeds","ranked","filter","sort","a","b","slice","existing","get","has","semantic","vec","lines","similarity","exec","insert","c","run","linesCol","INTERNAL_COLUMNS","mapTree","docs","columns","name","allFields","quoted","split","join","n","types","field","coverage","type","fields","hubs","recent","fieldsTotal","features","PEEK_LINK_LIMIT","peek","pathArg","row","paths","p","base","basename","replace","toLowerCase","matches","frontmatter","key","value","Object","entries","sections","outbound","backlinks","unresolved","backlinksTotal","out","l","dst","target","src","tokens","ceil","_size","outboundTotal","unresolvedTotal","off"],"mappings":"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"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes