sensemaking 0.5.0 → 0.7.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 (108) hide show
  1. package/README.md +13 -6
  2. package/dist/cjs/cli.js +8 -1
  3. package/dist/cjs/cli.js.map +1 -1
  4. package/dist/cjs/commands/check.d.cts +3 -0
  5. package/dist/cjs/commands/check.d.ts +3 -0
  6. package/dist/cjs/commands/check.js +130 -0
  7. package/dist/cjs/commands/check.js.map +1 -0
  8. package/dist/cjs/commands/find.js +173 -10
  9. package/dist/cjs/commands/find.js.map +1 -1
  10. package/dist/cjs/commands/index.js +5 -0
  11. package/dist/cjs/commands/index.js.map +1 -1
  12. package/dist/cjs/commands/map.js +1 -1
  13. package/dist/cjs/commands/map.js.map +1 -1
  14. package/dist/cjs/commands/peek.js +1 -1
  15. package/dist/cjs/commands/peek.js.map +1 -1
  16. package/dist/cjs/commands/shared.d.cts +1 -1
  17. package/dist/cjs/commands/shared.d.ts +1 -1
  18. package/dist/cjs/commands/shared.js +166 -8
  19. package/dist/cjs/commands/shared.js.map +1 -1
  20. package/dist/cjs/commands/status.js +72 -5
  21. package/dist/cjs/commands/status.js.map +1 -1
  22. package/dist/cjs/commands/types.d.cts +1 -0
  23. package/dist/cjs/commands/types.d.ts +1 -0
  24. package/dist/cjs/config.d.cts +32 -2
  25. package/dist/cjs/config.d.ts +32 -2
  26. package/dist/cjs/config.js +199 -11
  27. package/dist/cjs/config.js.map +1 -1
  28. package/dist/cjs/db.d.cts +1 -1
  29. package/dist/cjs/db.d.ts +1 -1
  30. package/dist/cjs/db.js +47 -17
  31. package/dist/cjs/db.js.map +1 -1
  32. package/dist/cjs/errors.d.cts +1 -1
  33. package/dist/cjs/errors.d.ts +1 -1
  34. package/dist/cjs/errors.js.map +1 -1
  35. package/dist/cjs/features/embed.d.cts +15 -0
  36. package/dist/cjs/features/embed.d.ts +15 -0
  37. package/dist/cjs/features/embed.js +844 -0
  38. package/dist/cjs/features/embed.js.map +1 -0
  39. package/dist/cjs/features/index.js +3 -1
  40. package/dist/cjs/features/index.js.map +1 -1
  41. package/dist/cjs/features/types.d.cts +4 -1
  42. package/dist/cjs/features/types.d.ts +4 -1
  43. package/dist/cjs/index.d.cts +1 -1
  44. package/dist/cjs/index.d.ts +1 -1
  45. package/dist/cjs/index.js.map +1 -1
  46. package/dist/cjs/output.d.cts +5 -0
  47. package/dist/cjs/output.d.ts +5 -0
  48. package/dist/cjs/output.js +48 -9
  49. package/dist/cjs/output.js.map +1 -1
  50. package/dist/cjs/scan.d.cts +1 -1
  51. package/dist/cjs/scan.d.ts +1 -1
  52. package/dist/cjs/scan.js +17 -10
  53. package/dist/cjs/scan.js.map +1 -1
  54. package/dist/cjs/verbs.d.cts +8 -2
  55. package/dist/cjs/verbs.d.ts +8 -2
  56. package/dist/cjs/verbs.js +308 -81
  57. package/dist/cjs/verbs.js.map +1 -1
  58. package/dist/esm/cli.js +8 -1
  59. package/dist/esm/cli.js.map +1 -1
  60. package/dist/esm/commands/check.d.ts +3 -0
  61. package/dist/esm/commands/check.js +56 -0
  62. package/dist/esm/commands/check.js.map +1 -0
  63. package/dist/esm/commands/find.js +5 -4
  64. package/dist/esm/commands/find.js.map +1 -1
  65. package/dist/esm/commands/index.js +1 -0
  66. package/dist/esm/commands/index.js.map +1 -1
  67. package/dist/esm/commands/map.js +1 -3
  68. package/dist/esm/commands/map.js.map +1 -1
  69. package/dist/esm/commands/peek.js +1 -1
  70. package/dist/esm/commands/peek.js.map +1 -1
  71. package/dist/esm/commands/shared.d.ts +1 -1
  72. package/dist/esm/commands/shared.js +2 -2
  73. package/dist/esm/commands/shared.js.map +1 -1
  74. package/dist/esm/commands/status.js +43 -5
  75. package/dist/esm/commands/status.js.map +1 -1
  76. package/dist/esm/commands/types.d.ts +1 -0
  77. package/dist/esm/commands/types.js.map +1 -1
  78. package/dist/esm/config.d.ts +32 -2
  79. package/dist/esm/config.js +98 -9
  80. package/dist/esm/config.js.map +1 -1
  81. package/dist/esm/db.d.ts +1 -1
  82. package/dist/esm/db.js +20 -11
  83. package/dist/esm/db.js.map +1 -1
  84. package/dist/esm/errors.d.ts +1 -1
  85. package/dist/esm/errors.js.map +1 -1
  86. package/dist/esm/features/embed.d.ts +15 -0
  87. package/dist/esm/features/embed.js +299 -0
  88. package/dist/esm/features/embed.js.map +1 -0
  89. package/dist/esm/features/index.js +3 -1
  90. package/dist/esm/features/index.js.map +1 -1
  91. package/dist/esm/features/types.d.ts +4 -1
  92. package/dist/esm/features/types.js.map +1 -1
  93. package/dist/esm/index.d.ts +1 -1
  94. package/dist/esm/index.js.map +1 -1
  95. package/dist/esm/output.d.ts +5 -0
  96. package/dist/esm/output.js +40 -8
  97. package/dist/esm/output.js.map +1 -1
  98. package/dist/esm/scan.d.ts +1 -1
  99. package/dist/esm/scan.js +17 -10
  100. package/dist/esm/scan.js.map +1 -1
  101. package/dist/esm/verbs.d.ts +8 -2
  102. package/dist/esm/verbs.js +92 -18
  103. package/dist/esm/verbs.js.map +1 -1
  104. package/package.json +2 -1
  105. package/schema.json +35 -1
  106. package/skills/sense/EXAMPLES.md +16 -0
  107. package/skills/sense/SKILL.md +60 -20
  108. package/skills/sense-setup/SKILL.md +91 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { parseArgs } from 'node:util';\nimport { COMMANDS } from './commands/index.ts';\nimport type { Ctx } from './commands/types.ts';\nimport { loadConfig, SUPPORTED_CONFIG_VERSION } from './config.ts';\n\n// Parsing and dispatch only. Commands live in src/commands/, one file each, lazy-loaded --\n// nothing tree- or dependency-heavy may be imported at the top of this file.\n\n// Works from dist/cjs and dist/esm alike: walk up past the dist type-marker package.json.\nfunction packageVersion(): string {\n const load = createRequire(import.meta.url);\n for (const rel of ['../package.json', '../../package.json', '../../../package.json']) {\n try {\n const pkg = load(rel) as { name?: string; version?: string };\n if (pkg.name === 'sensemaking' && pkg.version) return pkg.version;\n } catch {}\n }\n return 'unknown';\n}\n\nfunction usage(name: string): string {\n return (\n `usage: ${name} <name> [params...] [--format table|json] [--config path]\\n` +\n ` ${name} query \"<sql>\" [params...]\\n` +\n ` ${name} find \"<terms>\" [--where \"<sql>\"] [--k n]\\n` +\n ` ${name} map\\n` +\n ` ${name} peek <path>\\n` +\n ` ${name} --list\\n` +\n ` ${name} init\\n` +\n ` ${name} watch [--force]\\n` +\n ` ${name} status\\n` +\n ` ${name} rebuild\\n` +\n ` ${name} --version`\n );\n}\n\n// Thrown errors -> exit 1 with the message verbatim; usage errors exit 2 directly.\nexport default async function cli(argv: string[], name: string): Promise<void> {\n let values: Record<string, string | boolean | undefined>;\n let positionals: string[];\n try {\n ({ values, positionals } = parseArgs({\n args: argv,\n options: {\n format: { type: 'string', default: 'table' },\n config: { type: 'string' },\n where: { type: 'string' },\n k: { type: 'string' },\n list: { type: 'boolean', default: false },\n force: { type: 'boolean', default: false },\n version: { type: 'boolean', default: false, short: 'v' },\n help: { type: 'boolean', default: false, short: 'h' },\n },\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage(name));\n process.exit(2);\n }\n\n if (values.version) {\n console.log(`v${packageVersion()}`);\n return;\n }\n if (values.help) {\n console.log(usage(name));\n return;\n }\n\n const ctx: Ctx = {\n name,\n rest: positionals.slice(1),\n format: values.format === 'json' ? 'json' : 'table',\n values: values as Ctx['values'],\n resolveConfig() {\n const cfg = loadConfig(values.config as string | undefined);\n if (cfg.migratedFrom !== undefined) {\n console.warn(`${name}: migrated ${cfg.configPath} from config version ${cfg.migratedFrom} to ${SUPPORTED_CONFIG_VERSION}`);\n }\n return cfg;\n },\n usageError(message) {\n console.error(message);\n process.exit(2);\n },\n };\n\n try {\n if (values.list) {\n for (const queryName of Object.keys(ctx.resolveConfig().queries).sort()) console.log(queryName);\n return;\n }\n\n const [first, ...params] = positionals;\n if (!first) {\n console.error(usage(name));\n process.exit(2);\n }\n\n const load = COMMANDS[first];\n if (load) await (await load()).default(ctx);\n else (await import('./commands/named.ts')).default(ctx, first, params);\n } catch (err) {\n console.error((err as Error).message);\n process.exit(1);\n }\n}\n"],"names":["createRequire","parseArgs","COMMANDS","loadConfig","SUPPORTED_CONFIG_VERSION","packageVersion","load","url","rel","pkg","name","version","usage","cli","argv","values","positionals","args","options","format","type","default","config","where","k","list","force","short","help","allowPositionals","err","console","error","message","process","exit","log","ctx","rest","slice","resolveConfig","cfg","migratedFrom","undefined","warn","configPath","usageError","queryName","Object","keys","queries","sort","first","params"],"mappings":"AAAA,SAASA,aAAa,QAAQ,cAAc;AAC5C,SAASC,SAAS,QAAQ,YAAY;AACtC,SAASC,QAAQ,QAAQ,sBAAsB;AAE/C,SAASC,UAAU,EAAEC,wBAAwB,QAAQ,cAAc;AAEnE,2FAA2F;AAC3F,6EAA6E;AAE7E,0FAA0F;AAC1F,SAASC;IACP,MAAMC,OAAON,cAAc,YAAYO,GAAG;IAC1C,KAAK,MAAMC,OAAO;QAAC;QAAmB;QAAsB;KAAwB,CAAE;QACpF,IAAI;YACF,MAAMC,MAAMH,KAAKE;YACjB,IAAIC,IAAIC,IAAI,KAAK,iBAAiBD,IAAIE,OAAO,EAAE,OAAOF,IAAIE,OAAO;QACnE,EAAE,OAAM,CAAC;IACX;IACA,OAAO;AACT;AAEA,SAASC,MAAMF,IAAY;IACzB,OACE,CAAC,OAAO,EAAEA,KAAK,2DAA2D,CAAC,GAC3E,CAAC,OAAO,EAAEA,KAAK,4BAA4B,CAAC,GAC5C,CAAC,OAAO,EAAEA,KAAK,2CAA2C,CAAC,GAC3D,CAAC,OAAO,EAAEA,KAAK,MAAM,CAAC,GACtB,CAAC,OAAO,EAAEA,KAAK,cAAc,CAAC,GAC9B,CAAC,OAAO,EAAEA,KAAK,SAAS,CAAC,GACzB,CAAC,OAAO,EAAEA,KAAK,OAAO,CAAC,GACvB,CAAC,OAAO,EAAEA,KAAK,kBAAkB,CAAC,GAClC,CAAC,OAAO,EAAEA,KAAK,SAAS,CAAC,GACzB,CAAC,OAAO,EAAEA,KAAK,UAAU,CAAC,GAC1B,CAAC,OAAO,EAAEA,KAAK,UAAU,CAAC;AAE9B;AAEA,mFAAmF;AACnF,eAAe,eAAeG,IAAIC,IAAc,EAAEJ,IAAY;IAC5D,IAAIK;IACJ,IAAIC;IACJ,IAAI;QACD,CAAA,EAAED,MAAM,EAAEC,WAAW,EAAE,GAAGf,UAAU;YACnCgB,MAAMH;YACNI,SAAS;gBACPC,QAAQ;oBAAEC,MAAM;oBAAUC,SAAS;gBAAQ;gBAC3CC,QAAQ;oBAAEF,MAAM;gBAAS;gBACzBG,OAAO;oBAAEH,MAAM;gBAAS;gBACxBI,GAAG;oBAAEJ,MAAM;gBAAS;gBACpBK,MAAM;oBAAEL,MAAM;oBAAWC,SAAS;gBAAM;gBACxCK,OAAO;oBAAEN,MAAM;oBAAWC,SAAS;gBAAM;gBACzCV,SAAS;oBAAES,MAAM;oBAAWC,SAAS;oBAAOM,OAAO;gBAAI;gBACvDC,MAAM;oBAAER,MAAM;oBAAWC,SAAS;oBAAOM,OAAO;gBAAI;YACtD;YACAE,kBAAkB;QACpB,EAAC;IACH,EAAE,OAAOC,KAAK;QACZC,QAAQC,KAAK,CAAC,AAACF,IAAcG,OAAO;QACpCF,QAAQC,KAAK,CAACpB,MAAMF;QACpBwB,QAAQC,IAAI,CAAC;IACf;IAEA,IAAIpB,OAAOJ,OAAO,EAAE;QAClBoB,QAAQK,GAAG,CAAC,CAAC,CAAC,EAAE/B,kBAAkB;QAClC;IACF;IACA,IAAIU,OAAOa,IAAI,EAAE;QACfG,QAAQK,GAAG,CAACxB,MAAMF;QAClB;IACF;IAEA,MAAM2B,MAAW;QACf3B;QACA4B,MAAMtB,YAAYuB,KAAK,CAAC;QACxBpB,QAAQJ,OAAOI,MAAM,KAAK,SAAS,SAAS;QAC5CJ,QAAQA;QACRyB;YACE,MAAMC,MAAMtC,WAAWY,OAAOO,MAAM;YACpC,IAAImB,IAAIC,YAAY,KAAKC,WAAW;gBAClCZ,QAAQa,IAAI,CAAC,GAAGlC,KAAK,WAAW,EAAE+B,IAAII,UAAU,CAAC,qBAAqB,EAAEJ,IAAIC,YAAY,CAAC,IAAI,EAAEtC,0BAA0B;YAC3H;YACA,OAAOqC;QACT;QACAK,YAAWb,OAAO;YAChBF,QAAQC,KAAK,CAACC;YACdC,QAAQC,IAAI,CAAC;QACf;IACF;IAEA,IAAI;QACF,IAAIpB,OAAOU,IAAI,EAAE;YACf,KAAK,MAAMsB,aAAaC,OAAOC,IAAI,CAACZ,IAAIG,aAAa,GAAGU,OAAO,EAAEC,IAAI,GAAIpB,QAAQK,GAAG,CAACW;YACrF;QACF;QAEA,MAAM,CAACK,OAAO,GAAGC,OAAO,GAAGrC;QAC3B,IAAI,CAACoC,OAAO;YACVrB,QAAQC,KAAK,CAACpB,MAAMF;YACpBwB,QAAQC,IAAI,CAAC;QACf;QAEA,MAAM7B,OAAOJ,QAAQ,CAACkD,MAAM;QAC5B,IAAI9C,MAAM,MAAM,AAAC,CAAA,MAAMA,MAAK,EAAGe,OAAO,CAACgB;aAClC,AAAC,CAAA,MAAM,MAAM,CAAC,sBAAqB,EAAGhB,OAAO,CAACgB,KAAKe,OAAOC;IACjE,EAAE,OAAOvB,KAAK;QACZC,QAAQC,KAAK,CAAC,AAACF,IAAcG,OAAO;QACpCC,QAAQC,IAAI,CAAC;IACf;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { parseArgs } from 'node:util';\nimport { COMMANDS } from './commands/index.ts';\nimport type { Ctx } from './commands/types.ts';\nimport { loadConfig, SUPPORTED_CONFIG_VERSION } from './config.ts';\n\n// Parsing and dispatch only. Commands live in src/commands/, one file each, lazy-loaded --\n// nothing tree- or dependency-heavy may be imported at the top of this file.\n\n// Works from dist/cjs and dist/esm alike: walk up past the dist type-marker package.json.\nfunction packageVersion(): string {\n const load = createRequire(import.meta.url);\n for (const rel of ['../package.json', '../../package.json', '../../../package.json']) {\n try {\n const pkg = load(rel) as { name?: string; version?: string };\n if (pkg.name === 'sensemaking' && pkg.version) return pkg.version;\n } catch {}\n }\n return 'unknown';\n}\n\nfunction usage(name: string): string {\n return (\n `usage: ${name} <name> [params...] [--format table|json] [--config path]\\n` +\n ` ${name} query \"<sql>\" [params...]\\n` +\n ` ${name} find \"<terms>\" [--where \"<sql>\"] [--k n] [--semantic]\\n` +\n ` ${name} map\\n` +\n ` ${name} peek <path>\\n` +\n ` ${name} --list\\n` +\n ` ${name} init\\n` +\n ` ${name} watch [--force]\\n` +\n ` ${name} status\\n` +\n ` ${name} rebuild\\n` +\n ` ${name} --version`\n );\n}\n\n// Thrown errors -> exit 1 with the message verbatim; usage errors exit 2 directly.\nexport default async function cli(argv: string[], name: string): Promise<void> {\n let values: Record<string, string | boolean | undefined>;\n let positionals: string[];\n try {\n ({ values, positionals } = parseArgs({\n args: argv,\n options: {\n format: { type: 'string', default: 'table' },\n config: { type: 'string' },\n where: { type: 'string' },\n k: { type: 'string' },\n semantic: { type: 'boolean', default: false },\n list: { type: 'boolean', default: false },\n force: { type: 'boolean', default: false },\n version: { type: 'boolean', default: false, short: 'v' },\n help: { type: 'boolean', default: false, short: 'h' },\n },\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage(name));\n process.exit(2);\n }\n\n if (values.version) {\n console.log(`v${packageVersion()}`);\n return;\n }\n if (values.help) {\n console.log(usage(name));\n return;\n }\n\n const ctx: Ctx = {\n name,\n rest: positionals.slice(1),\n format: values.format === 'json' ? 'json' : 'table',\n values: values as Ctx['values'],\n resolveConfig() {\n const cfg = loadConfig(values.config as string | undefined);\n if (cfg.migratedFrom !== undefined) {\n console.warn(`${name}: migrated ${cfg.configPath} from config version ${cfg.migratedFrom} to ${SUPPORTED_CONFIG_VERSION}`);\n }\n if (cfg.unknownKeys !== undefined) {\n console.warn(`${name}: ${cfg.configPath} sets ${cfg.unknownKeys.join(', ')}, which this build does not read (no effect); see schema.json for the keys it does`);\n }\n return cfg;\n },\n usageError(message) {\n console.error(message);\n process.exit(2);\n },\n };\n\n try {\n if (values.list) {\n for (const queryName of Object.keys(ctx.resolveConfig().queries).sort()) console.log(queryName);\n return;\n }\n\n const [first, ...params] = positionals;\n if (!first) {\n console.error(usage(name));\n process.exit(2);\n }\n\n const load = COMMANDS[first];\n if (load) await (await load()).default(ctx);\n else (await import('./commands/named.ts')).default(ctx, first, params);\n } catch (err) {\n console.error((err as Error).message);\n process.exit(1);\n }\n}\n"],"names":["createRequire","parseArgs","COMMANDS","loadConfig","SUPPORTED_CONFIG_VERSION","packageVersion","load","url","rel","pkg","name","version","usage","cli","argv","values","positionals","args","options","format","type","default","config","where","k","semantic","list","force","short","help","allowPositionals","err","console","error","message","process","exit","log","ctx","rest","slice","resolveConfig","cfg","migratedFrom","undefined","warn","configPath","unknownKeys","join","usageError","queryName","Object","keys","queries","sort","first","params"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from './types.js';
2
+ declare const check: Command;
3
+ export default check;
@@ -0,0 +1,56 @@
1
+ import { open } from '../db.js';
2
+ import { printRows } from '../output.js';
3
+ import { printWarnings } from './shared.js';
4
+ // A saved query that returns zero rows looks identical to a true empty result, so a broken
5
+ // one can sit unnoticed -- one field report had `WHERE flag = 'true'` against a numeric
6
+ // column reading as "nothing tagged yet" for hours. Preparing each query catches syntax and
7
+ // unknown-column errors without executing it; queries that take no parameters are also run
8
+ // for a row count. Parameterised queries are validated but not counted: inventing arguments
9
+ // would report a count for a query nobody ran.
10
+ const check = (ctx)=>{
11
+ var _cfg_queries;
12
+ const cfg = ctx.resolveConfig();
13
+ const { db, warnings } = open(cfg);
14
+ printWarnings(warnings);
15
+ const rows = [];
16
+ let failed = 0;
17
+ for (const [name, sql] of Object.entries((_cfg_queries = cfg.queries) !== null && _cfg_queries !== void 0 ? _cfg_queries : {})){
18
+ var _sql_match;
19
+ const params = ((_sql_match = sql.match(/\?/g)) !== null && _sql_match !== void 0 ? _sql_match : []).length;
20
+ try {
21
+ const statement = db.prepare(sql);
22
+ if (params > 0) {
23
+ rows.push({
24
+ query: name,
25
+ params,
26
+ rows: '—',
27
+ status: 'ok (not run: needs parameters)'
28
+ });
29
+ continue;
30
+ }
31
+ const count = statement.all().length;
32
+ rows.push({
33
+ query: name,
34
+ params,
35
+ rows: count,
36
+ status: count === 0 ? 'ok, but returns 0 rows' : 'ok'
37
+ });
38
+ } catch (err) {
39
+ failed++;
40
+ rows.push({
41
+ query: name,
42
+ params,
43
+ rows: '—',
44
+ status: `FAILED: ${err.message}`
45
+ });
46
+ }
47
+ }
48
+ db.close();
49
+ if (rows.length === 0) {
50
+ console.log('no saved queries in config');
51
+ return;
52
+ }
53
+ printRows(rows, ctx.format);
54
+ if (failed > 0) process.exit(1);
55
+ };
56
+ export default check;
@@ -0,0 +1 @@
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 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 rows.push({ query: name, params, rows: count, status: count === 0 ? 'ok, but returns 0 rows' : 'ok' });\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","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;QAAhB,MAAMI,SAAS,EAACJ,aAAAA,IAAIK,KAAK,CAAC,oBAAVL,wBAAAA,aAAoB,EAAE,EAAEM,MAAM;QAC9C,IAAI;YACF,MAAMC,YAAYZ,GAAGa,OAAO,CAACR;YAC7B,IAAII,SAAS,GAAG;gBACdP,KAAKY,IAAI,CAAC;oBAAEC,OAAOX;oBAAMK;oBAAQP,MAAM;oBAAKc,QAAQ;gBAAiC;gBACrF;YACF;YACA,MAAMC,QAAQ,AAACL,UAAUM,GAAG,GAAiBP,MAAM;YACnDT,KAAKY,IAAI,CAAC;gBAAEC,OAAOX;gBAAMK;gBAAQP,MAAMe;gBAAOD,QAAQC,UAAU,IAAI,2BAA2B;YAAK;QACtG,EAAE,OAAOE,KAAK;YACZhB;YACAD,KAAKY,IAAI,CAAC;gBAAEC,OAAOX;gBAAMK;gBAAQP,MAAM;gBAAKc,QAAQ,CAAC,QAAQ,EAAE,AAACG,IAAcC,OAAO,EAAE;YAAC;QAC1F;IACF;IAEApB,GAAGqB,KAAK;IACR,IAAInB,KAAKS,MAAM,KAAK,GAAG;QACrBW,QAAQC,GAAG,CAAC;QACZ;IACF;IACA7B,UAAUQ,MAAML,IAAI2B,MAAM;IAC1B,IAAIrB,SAAS,GAAGsB,QAAQC,IAAI,CAAC;AAC/B;AACA,eAAe9B,MAAM"}
@@ -1,14 +1,15 @@
1
1
  import { printRows } from '../output.js';
2
2
  import { find } from '../verbs.js';
3
3
  import { withDb } from './shared.js';
4
- const findCmd = (ctx)=>{
4
+ const findCmd = async (ctx)=>{
5
5
  const [terms] = ctx.rest;
6
- if (!terms) ctx.usageError(`usage: ${ctx.name} find "<terms>" [--where "<sql>"] [--k n]`);
6
+ if (!terms) ctx.usageError(`usage: ${ctx.name} find "<terms>" [--where "<sql>"] [--k n] [--semantic]`);
7
7
  const k = ctx.values.k === undefined ? undefined : Number.parseInt(ctx.values.k, 10);
8
8
  if (ctx.values.k !== undefined && !Number.isInteger(k)) ctx.usageError(`--k expects an integer, got "${ctx.values.k}"`);
9
- withDb(ctx, (db, cfg)=>printRows(find(db, cfg, terms, {
9
+ await withDb(ctx, async (db, cfg)=>printRows(await find(db, cfg, terms, {
10
10
  k,
11
- where: ctx.values.where
11
+ where: ctx.values.where,
12
+ semantic: ctx.values.semantic
12
13
  }), ctx.format));
13
14
  };
14
15
  export default findCmd;
@@ -1 +1 @@
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 = (ctx) => {\n const [terms] = ctx.rest;\n if (!terms) ctx.usageError(`usage: ${ctx.name} find \"<terms>\" [--where \"<sql>\"] [--k n]`);\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 withDb(ctx, (db, cfg) => printRows(find(db, cfg, terms, { k, where: ctx.values.where }), 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","format"],"mappings":"AAAA,SAASA,SAAS,QAAQ,eAAe;AACzC,SAASC,IAAI,QAAQ,cAAc;AACnC,SAASC,MAAM,QAAQ,cAAc;AAGrC,MAAMC,UAAmB,CAACC;IACxB,MAAM,CAACC,MAAM,GAAGD,IAAIE,IAAI;IACxB,IAAI,CAACD,OAAOD,IAAIG,UAAU,CAAC,CAAC,OAAO,EAAEH,IAAII,IAAI,CAAC,yCAAyC,CAAC;IACxF,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;IACtHP,OAAOE,KAAK,CAACW,IAAIC,MAAQhB,UAAUC,KAAKc,IAAIC,KAAKX,OAAO;YAAEI;YAAGQ,OAAOb,IAAIM,MAAM,CAACO,KAAK;QAAC,IAAIb,IAAIc,MAAM;AACrG;AACA,eAAef,QAAQ"}
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"}
@@ -5,6 +5,7 @@ export const COMMANDS = {
5
5
  init: ()=>import('./init.js'),
6
6
  watch: ()=>import('./watch.js'),
7
7
  status: ()=>import('./status.js'),
8
+ check: ()=>import('./check.js'),
8
9
  rebuild: ()=>import('./rebuild.js'),
9
10
  query: ()=>import('./query.js'),
10
11
  find: ()=>import('./find.js'),
@@ -1 +1 @@
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 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","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,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
+ {"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,10 +1,8 @@
1
1
  import { renderMap } from '../output.js';
2
2
  import { mapTree } from '../verbs.js';
3
3
  import { withDb } from './shared.js';
4
- const map = (ctx)=>{
5
- withDb(ctx, (db, cfg)=>{
4
+ const map = (ctx)=>withDb(ctx, (db, cfg)=>{
6
5
  const result = mapTree(db, cfg);
7
6
  console.log(ctx.format === 'json' ? JSON.stringify(result, null, 2) : renderMap(result));
8
7
  });
9
- };
10
8
  export default map;
@@ -1 +1 @@
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 });\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;IACpBF,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;AACA,eAAeJ,IAAI"}
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"}
@@ -4,7 +4,7 @@ import { withDb } from './shared.js';
4
4
  const peekCmd = (ctx)=>{
5
5
  const [pathArg] = ctx.rest;
6
6
  if (!pathArg) ctx.usageError(`usage: ${ctx.name} peek <path>`);
7
- withDb(ctx, (db, cfg)=>{
7
+ return withDb(ctx, (db, cfg)=>{
8
8
  const result = peek(db, cfg, pathArg);
9
9
  console.log(ctx.format === 'json' ? JSON.stringify(result, null, 2) : renderPeek(result));
10
10
  });
@@ -1 +1 @@
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 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;IAC7DN,OAAOE,KAAK,CAACK,IAAIC;QACf,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
+ {"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"}
@@ -2,5 +2,5 @@ import type { ResolvedConfig } from '../config.js';
2
2
  import type { OpenResult } from '../db.js';
3
3
  import type { Ctx } from './types.js';
4
4
  export declare function printWarnings(warnings: string[]): void;
5
- export declare function withDb(ctx: Ctx, fn: (db: OpenResult['db'], cfg: ResolvedConfig) => void): void;
5
+ export declare function withDb(ctx: Ctx, fn: (db: OpenResult['db'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void>;
6
6
  export declare function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: 'table' | 'json', label: string): void;
@@ -4,12 +4,12 @@ import { printRows } from '../output.js';
4
4
  export function printWarnings(warnings) {
5
5
  for (const w of warnings)console.warn(w);
6
6
  }
7
- export function withDb(ctx, fn) {
7
+ export async function withDb(ctx, fn) {
8
8
  const cfg = ctx.resolveConfig();
9
9
  const { db, warnings } = open(cfg);
10
10
  printWarnings(warnings);
11
11
  try {
12
- fn(db, cfg);
12
+ await fn(db, cfg);
13
13
  } finally{
14
14
  db.close();
15
15
  }
@@ -1 +1 @@
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 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 function withDb(ctx: Ctx, fn: (db: OpenResult['db'], cfg: ResolvedConfig) => void): void {\n const cfg = ctx.resolveConfig();\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n try {\n 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 printRows(db.prepare(sql).all(...params) as Row[], format);\n db.close();\n}\n"],"names":["open","printRows","printWarnings","warnings","w","console","warn","withDb","ctx","fn","cfg","resolveConfig","db","close","runSql","sql","params","format","label","placeholderCount","match","length","error","process","exit","prepare","all"],"mappings":"AAEA,SAASA,IAAI,QAAQ,WAAW;AAEhC,SAASC,SAAS,QAAQ,eAAe;AAGzC,qEAAqE;AAErE,OAAO,SAASC,cAAcC,QAAkB;IAC9C,KAAK,MAAMC,KAAKD,SAAUE,QAAQC,IAAI,CAACF;AACzC;AAEA,OAAO,SAASG,OAAOC,GAAQ,EAAEC,EAAuD;IACtF,MAAMC,MAAMF,IAAIG,aAAa;IAC7B,MAAM,EAAEC,EAAE,EAAET,QAAQ,EAAE,GAAGH,KAAKU;IAC9BR,cAAcC;IACd,IAAI;QACFM,GAAGG,IAAIF;IACT,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,GAAGH,KAAKU;IAC9BR,cAAcC;IACdF,UAAUW,GAAGa,OAAO,CAACV,KAAKW,GAAG,IAAIV,SAAkBC;IACnDL,GAAGC,KAAK;AACV"}
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 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 printRows(db.prepare(sql).all(...params) as Row[], format);\n db.close();\n}\n"],"names":["open","printRows","printWarnings","warnings","w","console","warn","withDb","ctx","fn","cfg","resolveConfig","db","close","runSql","sql","params","format","label","placeholderCount","match","length","error","process","exit","prepare","all"],"mappings":"AAEA,SAASA,IAAI,QAAQ,WAAW;AAEhC,SAASC,SAAS,QAAQ,eAAe;AAGzC,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,GAAGH,KAAKU;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,GAAGH,KAAKU;IAC9BR,cAAcC;IACdF,UAAUW,GAAGa,OAAO,CAACV,KAAKW,GAAG,IAAIV,SAAkBC;IACnDL,GAAGC,KAAK;AACV"}
@@ -1,13 +1,51 @@
1
+ import { embedConfig, featureStates } from '../config.js';
1
2
  import { docCount, getMeta, open } from '../db.js';
2
3
  import { printWarnings } from './shared.js';
4
+ // Vectors are computed on the first semantic query, not at reconcile, so a tree can be
5
+ // embed-enabled with nothing embedded yet -- reported here because a fast `rebuild` on an
6
+ // embed tree otherwise reads as "the feature isn't on".
7
+ function vectorState(db) {
8
+ try {
9
+ const row = db.prepare('SELECT COUNT(vector) AS embedded, COUNT(*) - COUNT(vector) AS pending FROM embeddings').get();
10
+ return row;
11
+ } catch {
12
+ return null;
13
+ }
14
+ }
3
15
  const status = (ctx)=>{
4
- const { db, dbPath, warnings } = open(ctx.resolveConfig());
16
+ var _ref;
17
+ var _cfg_defaults_find, _cfg_defaults;
18
+ const cfg = ctx.resolveConfig();
19
+ const { db, dbPath, warnings } = open(cfg);
5
20
  printWarnings(warnings);
6
- console.log(`db: ${dbPath}`);
7
- console.log(`docs: ${docCount(db)}`);
21
+ const features = featureStates(cfg);
22
+ const e = embedConfig(cfg);
23
+ const vectors = e ? vectorState(db) : null;
8
24
  const heartbeat = getMeta(db, 'watch_heartbeat');
9
- if (heartbeat) console.log(`watcher: last heartbeat ${Math.round((Date.now() - Date.parse(heartbeat)) / 1000)}s ago`);
10
- else console.log('watcher: no watcher');
25
+ const result = {
26
+ db: dbPath,
27
+ docs: docCount(db),
28
+ features: features.on,
29
+ featuresOff: features.off,
30
+ embed: e ? {
31
+ type: e.type,
32
+ model: e.model,
33
+ ...vectors !== null && vectors !== void 0 ? vectors : {}
34
+ } : null,
35
+ findDefaultWhere: (_ref = (_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) !== null && _ref !== void 0 ? _ref : null,
36
+ watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null
37
+ };
38
+ if (ctx.format === 'json') {
39
+ console.log(JSON.stringify(result, null, 2));
40
+ } else {
41
+ console.log(`db: ${result.db}`);
42
+ console.log(`docs: ${result.docs}`);
43
+ const off = features.off.length > 0 ? ` · off: ${features.off.map((name)=>`${name} (features.${name})`).join(', ')}` : '';
44
+ console.log(`features: ${features.on.join(', ')}${off}`);
45
+ if (e) console.log(`embed: ${e.type} ${e.model}${vectors ? ` (vectors: ${vectors.embedded} embedded, ${vectors.pending} pending — embedded on first --semantic query)` : ''}`);
46
+ if (result.findDefaultWhere) console.log(`find default scope: ${result.findDefaultWhere} (--where replaces it)`);
47
+ console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: no watcher' : `watcher: last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);
48
+ }
11
49
  db.close();
12
50
  };
13
51
  export default status;
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/status.ts"],"sourcesContent":["import { docCount, getMeta, open } from '../db.ts';\nimport { printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst status: Command = (ctx) => {\n const { db, dbPath, warnings } = open(ctx.resolveConfig());\n printWarnings(warnings);\n console.log(`db: ${dbPath}`);\n console.log(`docs: ${docCount(db)}`);\n const heartbeat = getMeta(db, 'watch_heartbeat');\n if (heartbeat) console.log(`watcher: last heartbeat ${Math.round((Date.now() - Date.parse(heartbeat)) / 1000)}s ago`);\n else console.log('watcher: no watcher');\n db.close();\n};\nexport default status;\n"],"names":["docCount","getMeta","open","printWarnings","status","ctx","db","dbPath","warnings","resolveConfig","console","log","heartbeat","Math","round","Date","now","parse","close"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,OAAO,EAAEC,IAAI,QAAQ,WAAW;AACnD,SAASC,aAAa,QAAQ,cAAc;AAG5C,MAAMC,SAAkB,CAACC;IACvB,MAAM,EAAEC,EAAE,EAAEC,MAAM,EAAEC,QAAQ,EAAE,GAAGN,KAAKG,IAAII,aAAa;IACvDN,cAAcK;IACdE,QAAQC,GAAG,CAAC,CAAC,IAAI,EAAEJ,QAAQ;IAC3BG,QAAQC,GAAG,CAAC,CAAC,MAAM,EAAEX,SAASM,KAAK;IACnC,MAAMM,YAAYX,QAAQK,IAAI;IAC9B,IAAIM,WAAWF,QAAQC,GAAG,CAAC,CAAC,wBAAwB,EAAEE,KAAKC,KAAK,CAAC,AAACC,CAAAA,KAAKC,GAAG,KAAKD,KAAKE,KAAK,CAACL,UAAS,IAAK,MAAM,KAAK,CAAC;SAC/GF,QAAQC,GAAG,CAAC;IACjBL,GAAGY,KAAK;AACV;AACA,eAAed,OAAO"}
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"}
@@ -8,6 +8,7 @@ export interface Ctx {
8
8
  where?: string;
9
9
  k?: string;
10
10
  force: boolean;
11
+ semantic: boolean;
11
12
  };
12
13
  resolveConfig(): ResolvedConfig;
13
14
  usageError(message: string): never;
@@ -1 +1 @@
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 };\n resolveConfig(): ResolvedConfig;\n usageError(message: string): never;\n}\n\nexport type Command = (ctx: Ctx) => Promise<void> | void;\n"],"names":[],"mappings":"AAYA,WAAyD"}
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,24 +1,53 @@
1
1
  export declare const CONFIG_FILENAME = "sense.config.json";
2
2
  export declare const STATE_DIR = ".sense";
3
3
  export declare const SUPPORTED_CONFIG_VERSION = 2;
4
- export declare const FEATURE_NAMES: readonly ["links", "sections", "rank"];
4
+ declare const FEATURE_NAMES: readonly ["links", "sections", "rank", "embed"];
5
5
  export type FeatureName = (typeof FEATURE_NAMES)[number];
6
+ export interface EmbedConfig {
7
+ model?: string;
8
+ type?: 'static' | 'api';
9
+ url?: string;
10
+ key?: string;
11
+ }
12
+ export declare const DEFAULT_EMBED_MODEL = "minishlab/potion-retrieval-32M";
6
13
  export interface Config {
7
14
  $schema?: string;
8
15
  version?: number;
9
16
  scan: {
10
17
  include: string[];
11
18
  };
12
- features?: Partial<Record<FeatureName, boolean>>;
19
+ features?: {
20
+ links?: boolean;
21
+ sections?: boolean;
22
+ rank?: boolean;
23
+ embed?: boolean | EmbedConfig;
24
+ };
25
+ defaults?: {
26
+ find?: {
27
+ where?: string;
28
+ };
29
+ };
13
30
  queries: Record<string, string>;
14
31
  }
15
32
  export interface ResolvedConfig extends Config {
16
33
  baseDir: string;
17
34
  configPath: string | null;
35
+ unknownKeys?: string[];
18
36
  migratedFrom?: number;
19
37
  }
20
38
  export declare function featureEnabled(cfg: Config, name: FeatureName): boolean;
21
39
  export declare function enabledFeatures(cfg: Config): FeatureName[];
40
+ export declare function featureStates(cfg: Config): {
41
+ on: FeatureName[];
42
+ off: FeatureName[];
43
+ };
44
+ export declare function embedConfig(cfg: Config): {
45
+ model: string;
46
+ type: 'static' | 'api';
47
+ url?: string;
48
+ key?: string;
49
+ } | null;
50
+ export declare function featureSignature(cfg: Config): string;
22
51
  export declare function migrateConfig(cfg: Config): {
23
52
  cfg: Config;
24
53
  from: number;
@@ -26,3 +55,4 @@ export declare function migrateConfig(cfg: Config): {
26
55
  export declare function initConfig(dir: string): string;
27
56
  export declare function findConfigPath(startDir: string): string | null;
28
57
  export declare function loadConfig(explicitPath?: string): ResolvedConfig;
58
+ export {};
@@ -6,28 +6,69 @@ export const STATE_DIR = '.sense';
6
6
  // Highest sense.config.json `version` this build understands. Older versions auto-migrate on load.
7
7
  export const SUPPORTED_CONFIG_VERSION = 2;
8
8
  // Each feature owns its tables, parse-time extraction, and reconcile step; verbs degrade when one is off.
9
- export const FEATURE_NAMES = [
9
+ // links/sections/rank are opt-out (absent = on); embed is opt-in (absent = off) -- most trees don't need vectors.
10
+ const FEATURE_NAMES = [
11
+ 'links',
12
+ 'sections',
13
+ 'rank',
14
+ 'embed'
15
+ ];
16
+ const OPT_OUT_NAMES = [
10
17
  'links',
11
18
  'sections',
12
19
  'rank'
13
20
  ];
14
- // Absent block or key means enabled -- features are opt-out. `rank` additionally requires `links`.
21
+ export const DEFAULT_EMBED_MODEL = 'minishlab/potion-retrieval-32M';
22
+ // Opt-out features: absent block or key means enabled. `rank` additionally requires `links`.
23
+ // `embed` is the opposite: enabled only when the config says so.
15
24
  export function featureEnabled(cfg, name) {
16
- var _cfg_features;
17
- const enabled = ((_cfg_features = cfg.features) === null || _cfg_features === void 0 ? void 0 : _cfg_features[name]) !== false;
25
+ var _cfg_features, _cfg_features1;
26
+ if (name === 'embed') return Boolean((_cfg_features = cfg.features) === null || _cfg_features === void 0 ? void 0 : _cfg_features.embed);
27
+ const enabled = ((_cfg_features1 = cfg.features) === null || _cfg_features1 === void 0 ? void 0 : _cfg_features1[name]) !== false;
18
28
  if (name === 'rank') return enabled && featureEnabled(cfg, 'links');
19
29
  return enabled;
20
30
  }
21
31
  export function enabledFeatures(cfg) {
22
32
  return FEATURE_NAMES.filter((name)=>featureEnabled(cfg, name));
23
33
  }
34
+ // Every feature with its current state; verbs surface this so "off" and "empty" stay
35
+ // distinguishable in output.
36
+ export function featureStates(cfg) {
37
+ return {
38
+ on: FEATURE_NAMES.filter((name)=>featureEnabled(cfg, name)),
39
+ off: FEATURE_NAMES.filter((name)=>!featureEnabled(cfg, name))
40
+ };
41
+ }
42
+ // Resolved embed settings, or null when the feature is off.
43
+ export function embedConfig(cfg) {
44
+ var _o_model, _o_type;
45
+ var _cfg_features;
46
+ const e = (_cfg_features = cfg.features) === null || _cfg_features === void 0 ? void 0 : _cfg_features.embed;
47
+ if (!e) return null;
48
+ const o = e === true ? {} : e;
49
+ return {
50
+ model: (_o_model = o.model) !== null && _o_model !== void 0 ? _o_model : DEFAULT_EMBED_MODEL,
51
+ type: (_o_type = o.type) !== null && _o_type !== void 0 ? _o_type : 'static',
52
+ url: o.url,
53
+ key: o.key
54
+ };
55
+ }
56
+ // Cache-key string: embed carries its type + model so a model change rebuilds like a toggle.
57
+ export function featureSignature(cfg) {
58
+ return enabledFeatures(cfg).map((name)=>{
59
+ if (name !== 'embed') return name;
60
+ const e = embedConfig(cfg);
61
+ return `embed:${e === null || e === void 0 ? void 0 : e.type}:${e === null || e === void 0 ? void 0 : e.model}`;
62
+ }).join(',');
63
+ }
24
64
  // Pure per-version steps; loadConfig chains them from the file's version up to SUPPORTED_CONFIG_VERSION.
25
65
  const MIGRATIONS = {
26
- // v1 -> v2: features block introduced, everything enabled (matches the old implicit behavior of `links` etc. not existing).
66
+ // v1 -> v2: features block introduced, opt-out features enabled (matches the old implicit
67
+ // behavior of `links` etc. not existing). embed stays absent -- opt-in.
27
68
  1: (cfg)=>({
28
69
  ...cfg,
29
70
  version: 2,
30
- features: Object.fromEntries(FEATURE_NAMES.map((name)=>[
71
+ features: Object.fromEntries(OPT_OUT_NAMES.map((name)=>[
31
72
  name,
32
73
  true
33
74
  ]))
@@ -56,7 +97,7 @@ function starterConfig() {
56
97
  '**/*.md'
57
98
  ]
58
99
  },
59
- features: Object.fromEntries(FEATURE_NAMES.map((name)=>[
100
+ features: Object.fromEntries(OPT_OUT_NAMES.map((name)=>[
60
101
  name,
61
102
  true
62
103
  ])),
@@ -85,7 +126,36 @@ export function findConfigPath(startDir) {
85
126
  // Shape check for hand-edited files: a typo'd config fails with a named error, not a
86
127
  // TypeError from whatever code touched the missing field first. `queries` is optional
87
128
  // on disk (absent = none); `scan.include` has no usable default.
129
+ // Keys each block actually reads. A key outside these sets is accepted and ignored, which
130
+ // looks identical to working -- one field report set `scan.exclude`, saw no change in doc
131
+ // count and no warning, and reasonably concluded the filter had applied. Reported as a
132
+ // warning rather than an error so a config carrying an unknown key still runs.
133
+ const KNOWN_KEYS = new Set([
134
+ '$schema',
135
+ 'version',
136
+ 'scan',
137
+ 'features',
138
+ 'defaults',
139
+ 'queries'
140
+ ]);
141
+ const KNOWN_SCAN_KEYS = new Set([
142
+ 'include'
143
+ ]);
144
+ function unknownConfigKeys(cfg) {
145
+ const unknown = Object.keys(cfg).filter((k)=>!KNOWN_KEYS.has(k)).map((k)=>k);
146
+ const scan = cfg.scan;
147
+ if (scan && typeof scan === 'object' && !Array.isArray(scan)) {
148
+ unknown.push(...Object.keys(scan).filter((k)=>!KNOWN_SCAN_KEYS.has(k)).map((k)=>`scan.${k}`));
149
+ }
150
+ const features = cfg.features;
151
+ if (features && typeof features === 'object' && !Array.isArray(features)) {
152
+ unknown.push(...Object.keys(features).filter((k)=>!FEATURE_NAMES.includes(k)).map((k)=>`features.${k}`));
153
+ }
154
+ return unknown;
155
+ }
88
156
  function validateConfig(parsed, configPath) {
157
+ var _cfg_features;
158
+ var _defaults_find;
89
159
  if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
90
160
  throw new SenseError('CONFIG_INVALID', `${configPath}: config must be a JSON object`);
91
161
  }
@@ -98,9 +168,26 @@ function validateConfig(parsed, configPath) {
98
168
  if (typeof cfg.queries !== 'object' || cfg.queries === null || Array.isArray(cfg.queries) || !Object.values(cfg.queries).every((q)=>typeof q === 'string')) {
99
169
  throw new SenseError('CONFIG_INVALID', `${configPath}: queries must be an object of name -> SQL string`);
100
170
  }
101
- if (cfg.features !== undefined && (typeof cfg.features !== 'object' || cfg.features === null || Array.isArray(cfg.features) || !Object.values(cfg.features).every((v)=>typeof v === 'boolean'))) {
171
+ const defaults = cfg.defaults;
172
+ if (defaults !== undefined && (typeof defaults !== 'object' || defaults === null || Array.isArray(defaults) || defaults.find !== undefined && typeof ((_defaults_find = defaults.find) === null || _defaults_find === void 0 ? void 0 : _defaults_find.where) !== 'string')) {
173
+ throw new SenseError('CONFIG_INVALID', `${configPath}: defaults.find.where must be a SQL condition string`);
174
+ }
175
+ if (cfg.features !== undefined && (typeof cfg.features !== 'object' || cfg.features === null || Array.isArray(cfg.features))) {
102
176
  throw new SenseError('CONFIG_INVALID', `${configPath}: features must be an object of name -> boolean`);
103
177
  }
178
+ for (const [name, value] of Object.entries((_cfg_features = cfg.features) !== null && _cfg_features !== void 0 ? _cfg_features : {})){
179
+ if (typeof value === 'boolean') continue;
180
+ // embed alone takes an object form: { model?, type?: static|api, url?, key? }.
181
+ const embed = value;
182
+ const shapeOk = name === 'embed' && typeof value === 'object' && value !== null && !Array.isArray(value) && [
183
+ 'model',
184
+ 'url',
185
+ 'key'
186
+ ].every((f)=>embed[f] === undefined || typeof embed[f] === 'string') && (embed.type === undefined || embed.type === 'static' || embed.type === 'api');
187
+ if (!shapeOk) {
188
+ throw new SenseError('CONFIG_INVALID', `${configPath}: features.${name} must be a boolean${name === 'embed' ? ' or { model?, type?: "static"|"api", url?, key? }' : ''}`);
189
+ }
190
+ }
104
191
  return cfg;
105
192
  }
106
193
  export function loadConfig(explicitPath) {
@@ -131,10 +218,12 @@ export function loadConfig(explicitPath) {
131
218
  migratedFrom = result.from;
132
219
  writeFileSync(configPath, `${JSON.stringify(cfg, null, 2)}\n`);
133
220
  }
221
+ const unknownKeys = unknownConfigKeys(cfg);
134
222
  return {
135
223
  ...cfg,
136
224
  baseDir: dirname(configPath),
137
225
  configPath,
138
- migratedFrom
226
+ migratedFrom,
227
+ unknownKeys: unknownKeys.length > 0 ? unknownKeys : undefined
139
228
  };
140
229
  }