sensemaking 0.18.0 → 0.18.2

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 (53) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/cli/status.js +20 -14
  3. package/dist/cjs/cli/status.js.map +1 -1
  4. package/dist/cjs/config/types.js.map +1 -1
  5. package/dist/cjs/output/column-hint.js +8 -7
  6. package/dist/cjs/output/column-hint.js.map +1 -1
  7. package/dist/cjs/scan/reparse.d.cts +6 -1
  8. package/dist/cjs/scan/reparse.d.ts +6 -1
  9. package/dist/cjs/scan/reparse.js +375 -48
  10. package/dist/cjs/scan/reparse.js.map +1 -1
  11. package/dist/cjs/scan/worker-error.d.cts +9 -0
  12. package/dist/cjs/scan/worker-error.d.ts +9 -0
  13. package/dist/cjs/scan/worker-error.js +44 -0
  14. package/dist/cjs/scan/worker-error.js.map +1 -0
  15. package/dist/cjs/store/duckdb/reconcile.js +8 -3
  16. package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
  17. package/dist/cjs/store/index.d.cts +1 -0
  18. package/dist/cjs/store/index.d.ts +1 -0
  19. package/dist/cjs/store/index.js +15 -2
  20. package/dist/cjs/store/index.js.map +1 -1
  21. package/dist/cjs/store/sqlite/reconcile.js +13 -8
  22. package/dist/cjs/store/sqlite/reconcile.js.map +1 -1
  23. package/dist/cjs/watch.js +77 -58
  24. package/dist/cjs/watch.js.map +1 -1
  25. package/dist/cjs/workers/parse.d.cts +18 -0
  26. package/dist/cjs/workers/parse.d.ts +18 -0
  27. package/dist/cjs/workers/parse.js +43 -0
  28. package/dist/cjs/workers/parse.js.map +1 -0
  29. package/dist/esm/cli/status.js +6 -3
  30. package/dist/esm/cli/status.js.map +1 -1
  31. package/dist/esm/config/types.js.map +1 -1
  32. package/dist/esm/output/column-hint.js +8 -7
  33. package/dist/esm/output/column-hint.js.map +1 -1
  34. package/dist/esm/scan/reparse.d.ts +6 -1
  35. package/dist/esm/scan/reparse.js +108 -8
  36. package/dist/esm/scan/reparse.js.map +1 -1
  37. package/dist/esm/scan/worker-error.d.ts +9 -0
  38. package/dist/esm/scan/worker-error.js +19 -0
  39. package/dist/esm/scan/worker-error.js.map +1 -0
  40. package/dist/esm/store/duckdb/reconcile.js +1 -1
  41. package/dist/esm/store/duckdb/reconcile.js.map +1 -1
  42. package/dist/esm/store/index.d.ts +1 -0
  43. package/dist/esm/store/index.js +14 -2
  44. package/dist/esm/store/index.js.map +1 -1
  45. package/dist/esm/store/sqlite/reconcile.js +1 -1
  46. package/dist/esm/store/sqlite/reconcile.js.map +1 -1
  47. package/dist/esm/watch.js +30 -17
  48. package/dist/esm/watch.js.map +1 -1
  49. package/dist/esm/workers/parse.d.ts +18 -0
  50. package/dist/esm/workers/parse.js +25 -0
  51. package/dist/esm/workers/parse.js.map +1 -0
  52. package/package.json +3 -1
  53. package/skills/sense-setup/SKILL.md +1 -1
package/README.md CHANGED
@@ -166,7 +166,7 @@ Three skills: `sense` for querying a tree (what each command is for, FTS5 syntax
166
166
  - **RAG / vector stores:** similarity can't express `WHERE status = 'active'`. Here vectors are one signal inside `search`: same database file, filters compose, every row labels its evidence (`via`), and a preset turns vectors off per layer of the tree. No second store, no daemon, no native builds on the default store.
167
167
  - **Document-OS apps (Anytype, Logseq, SilverBullet, Capacities):** full applications with their own UI and storage. `sense` is headless: your files stay files, there's no app to run.
168
168
 
169
- Dependencies: [yaml](https://github.com/eemeli/yaml), [@huggingface/tokenizers](https://github.com/huggingface/tokenizers.js), [franc-min](https://github.com/wooorm/franc), [mdast-util-from-markdown](https://github.com/syntax-tree/mdast-util-from-markdown), and the five GFM extensions it needs (not the full gfm/tagfilter bundle): [micromark-extension-gfm-autolink-literal](https://github.com/micromark/micromark-extension-gfm-autolink-literal), [micromark-extension-gfm-footnote](https://github.com/micromark/micromark-extension-gfm-footnote), [micromark-extension-gfm-strikethrough](https://github.com/micromark/micromark-extension-gfm-strikethrough), [micromark-extension-gfm-table](https://github.com/micromark/micromark-extension-gfm-table), [micromark-extension-gfm-task-list-item](https://github.com/micromark/micromark-extension-gfm-task-list-item), and their mdast counterparts [mdast-util-gfm-autolink-literal](https://github.com/syntax-tree/mdast-util-gfm-autolink-literal), [mdast-util-gfm-footnote](https://github.com/syntax-tree/mdast-util-gfm-footnote), [mdast-util-gfm-strikethrough](https://github.com/syntax-tree/mdast-util-gfm-strikethrough), [mdast-util-gfm-table](https://github.com/syntax-tree/mdast-util-gfm-table), [mdast-util-gfm-task-list-item](https://github.com/syntax-tree/mdast-util-gfm-task-list-item) (all pure JS), Node's built-in SQLite, and [install-module-linked](https://github.com/kmalakoff/install-module-linked), which installs the optional `duckdb` store's `@duckdb/node-api` native binding on first use instead of shipping it to every install. No native builds by default.
169
+ Dependencies: [yaml](https://github.com/eemeli/yaml), [@huggingface/tokenizers](https://github.com/huggingface/tokenizers.js), [franc-min](https://github.com/wooorm/franc), [tinypool](https://github.com/tinylibs/tinypool) (worker pool for parallel parsing on large trees), [mdast-util-from-markdown](https://github.com/syntax-tree/mdast-util-from-markdown), and the five GFM extensions it needs (not the full gfm/tagfilter bundle): [micromark-extension-gfm-autolink-literal](https://github.com/micromark/micromark-extension-gfm-autolink-literal), [micromark-extension-gfm-footnote](https://github.com/micromark/micromark-extension-gfm-footnote), [micromark-extension-gfm-strikethrough](https://github.com/micromark/micromark-extension-gfm-strikethrough), [micromark-extension-gfm-table](https://github.com/micromark/micromark-extension-gfm-table), [micromark-extension-gfm-task-list-item](https://github.com/micromark/micromark-extension-gfm-task-list-item), and their mdast counterparts [mdast-util-gfm-autolink-literal](https://github.com/syntax-tree/mdast-util-gfm-autolink-literal), [mdast-util-gfm-footnote](https://github.com/syntax-tree/mdast-util-gfm-footnote), [mdast-util-gfm-strikethrough](https://github.com/syntax-tree/mdast-util-gfm-strikethrough), [mdast-util-gfm-table](https://github.com/syntax-tree/mdast-util-gfm-table), [mdast-util-gfm-task-list-item](https://github.com/syntax-tree/mdast-util-gfm-task-list-item) (all pure JS), Node's built-in SQLite, and [install-module-linked](https://github.com/kmalakoff/install-module-linked), which installs the optional `duckdb` store's `@duckdb/node-api` native binding on first use instead of shipping it to every install. No native builds by default.
170
170
 
171
171
  ## License
172
172
 
@@ -327,7 +327,7 @@ function embedReachable(e) {
327
327
  }
328
328
  var status = function status(ctx) {
329
329
  return _async_to_generator(function() {
330
- var _ref, _process_env_e_key, _cfg_migratedFrom, _cfg_unknownKeys, _cfg_queries, values, format, cfg, _ref1, store, dbPath, warnings, features, e, hasModel, reachable, _tmp, vectors, _tmp1, presets, staticLanguages, declaredLanguages, detectedLanguages, heartbeat, busyTimeoutMs, _tmp2, keyEnv, result, _tmp3, migrated, shown, total, breakdown, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, line, pid;
330
+ var _ref, _process_env_e_key, _cfg_migratedFrom, _cfg_unknownKeys, _cfg_queries, values, format, cfg, _ref1, store, dbPath, warnings, features, e, hasModel, reachable, _tmp, vectors, _tmp1, presets, staticLanguages, declaredLanguages, detectedLanguages, heartbeat, cacheSchema, busyTimeoutMs, _tmp2, keyEnv, result, _tmp3, migrated, shown, total, breakdown, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, line, pid;
331
331
  return _ts_generator(this, function(_state) {
332
332
  switch(_state.label){
333
333
  case 0:
@@ -402,29 +402,35 @@ var status = function status(ctx) {
402
402
  ];
403
403
  case 10:
404
404
  heartbeat = _state.sent();
405
+ return [
406
+ 4,
407
+ (0, _indexts1.getMeta)(store, 'schema_version')
408
+ ];
409
+ case 11:
410
+ cacheSchema = _state.sent();
405
411
  if (!(store.name === 'sqlite')) return [
406
412
  3,
407
- 13
413
+ 14
408
414
  ];
409
415
  return [
410
416
  4,
411
417
  store.prepare('PRAGMA busy_timeout')
412
418
  ];
413
- case 11:
419
+ case 12:
414
420
  return [
415
421
  4,
416
422
  _state.sent().get()
417
423
  ];
418
- case 12:
424
+ case 13:
419
425
  _tmp2 = _state.sent().timeout;
420
426
  return [
421
427
  3,
422
- 14
428
+ 15
423
429
  ];
424
- case 13:
425
- _tmp2 = null;
426
- _state.label = 14;
427
430
  case 14:
431
+ _tmp2 = null;
432
+ _state.label = 15;
433
+ case 15:
428
434
  busyTimeoutMs = _tmp2;
429
435
  // The env var holds the token; only its name and whether it is set are ever reported.
430
436
  keyEnv = (e === null || e === void 0 ? void 0 : e.key) ? {
@@ -439,19 +445,19 @@ var status = function status(ctx) {
439
445
  tree: cfg.baseDir,
440
446
  cache: (0, _nodepath.dirname)(dbPath),
441
447
  db: dbPath,
442
- cacheSchema: _indexts1.SCHEMA_VERSION
448
+ cacheSchema: cacheSchema
443
449
  };
444
450
  return [
445
451
  4,
446
452
  (0, _indexts1.docCount)(store)
447
453
  ];
448
- case 15:
454
+ case 16:
449
455
  _tmp3.docs = _state.sent();
450
456
  return [
451
457
  4,
452
458
  parseErrorCount(store)
453
459
  ];
454
- case 16:
460
+ case 17:
455
461
  _tmp3.unparseableFrontmatter = _state.sent(), _tmp3.features = features.on, _tmp3.featuresOff = features.off, _tmp3.embed = e ? _object_spread({
456
462
  provider: e.provider,
457
463
  model: e.model,
@@ -467,7 +473,7 @@ var status = function status(ctx) {
467
473
  4,
468
474
  (0, _indexts1.getMeta)(store, 'watch_pid')
469
475
  ];
470
- case 17:
476
+ case 18:
471
477
  result = (_tmp3.watcherPid = _state.sent(), _tmp3.watcherHeartbeatSecondsAgo = heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null, _tmp3.busyTimeoutMs = busyTimeoutMs, _tmp3);
472
478
  if (format === 'json') {
473
479
  console.log((0, _outputts.stringifyJson)(result, 2));
@@ -477,7 +483,7 @@ var status = function status(ctx) {
477
483
  // A load-time stderr warning has scrolled away by the time anyone looks here.
478
484
  if (cfg.unknownKeys) console.log(" unknown keys, ignored: ".concat(cfg.unknownKeys.join(', ')));
479
485
  console.log("tree: ".concat(result.tree));
480
- console.log("cache: ".concat(result.cache, " (schema ").concat(_indexts1.SCHEMA_VERSION, "; delete this directory to reset)"));
486
+ console.log("cache: ".concat(result.cache, " (schema ").concat(result.cacheSchema, "; delete this directory to reset)"));
481
487
  console.log("docs: ".concat(result.docs).concat(result.unparseableFrontmatter > 0 ? " (".concat(result.unparseableFrontmatter, " with unparseable frontmatter: WHERE _parse_error IS NOT NULL)") : ''));
482
488
  console.log('');
483
489
  console.log((0, _outputts.featuresLine)(features));
@@ -541,7 +547,7 @@ var status = function status(ctx) {
541
547
  4,
542
548
  store.close()
543
549
  ];
544
- case 18:
550
+ case 19:
545
551
  _state.sent();
546
552
  return [
547
553
  2
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/status.ts"],"sourcesContent":["import { dirname } from 'node:path';\nimport { presetCoverage } from '../commands/status.ts';\nimport { embedConfig, featureStates, SUPPORTED_CONFIG_VERSION } from '../config/index.ts';\nimport { languageDistribution } from '../embed/distribution.ts';\nimport { probeReachable } from '../embed/http.ts';\nimport { isDownloadable, MODEL_FILENAMES, modelDir, modelPresent, readLanguages } from '../embed/store.ts';\nimport { featuresLine, presetsLines, stringifyJson } from '../output/output.ts';\nimport { docCount, getMeta, openStore, SCHEMA_VERSION } from '../store/index.ts';\nimport type { Store } from '../store/types.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// status names what you cannot read off the config file: locations sense chose, values it\n// derived, state it stored. Config content is not echoed -- the config line says which file to\n// read, and duplicating its globs here would create two places that disagree after an edit.\n// The exception is the embed block's url and key, whose effect is remote and otherwise invisible.\n\n// Vectors are computed on the first semantic query, not at reconcile, so a tree can have a\n// semantic-on preset with nothing embedded yet -- reported here because a fast reconcile on\n// such a tree otherwise reads as \"the feature isn't on\".\nasync function vectorState(store: Store): Promise<{ embedded: number; pending: number } | null> {\n try {\n const stmt = await store.prepare('SELECT COUNT(vector) AS embedded, COUNT(*) - COUNT(vector) AS pending FROM embeddings');\n return (await stmt.get()) as { embedded: number; pending: number };\n } catch {\n return null;\n }\n}\n\nasync function parseErrorCount(store: Store): Promise<number> {\n const stmt = await store.prepare(`SELECT COUNT(*) AS n FROM frontmatter WHERE \"_parse_error\" IS NOT NULL`);\n return ((await stmt.get()) as { n: number }).n;\n}\n\n// A URL can carry credentials in its userinfo (https://user:pass@host/v1). status output gets\n// pasted into issues and transcripts, so it is always safe to paste.\nexport function redactUrl(url: string): string {\n try {\n const parsed = new URL(url);\n if (!parsed.username && !parsed.password) return url;\n parsed.username = '';\n parsed.password = '';\n return `${parsed.toString().replace(/\\/$/, '')} (credentials redacted)`;\n } catch {\n return url;\n }\n}\n\n// A stopped Ollama/LM Studio/Cohere endpoint prints identically to a running one otherwise; any\n// HTTP response counts as reachable (probeReachable), so this only distinguishes up from down.\nasync function embedReachable(e: { provider: string; url?: string }): Promise<boolean | null> {\n if (e.provider === 'static' || (e.provider === 'openai' && !e.url)) return null;\n const base = (e.url ?? 'https://api.cohere.com').replace(/\\/+$/, '');\n return probeReachable(e.provider === 'openai' ? `${base}/models` : base);\n}\n\nconst status: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.status}`, { ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const cfg = ctx.resolveConfig(values.config as string | undefined);\n const { store, dbPath, warnings } = await openStore(cfg);\n printWarnings(warnings);\n\n const features = featureStates(cfg);\n const e = embedConfig(cfg);\n const hasModel = e ? modelPresent(cfg) : false;\n const reachable = e ? await embedReachable(e) : null;\n const vectors = e ? await vectorState(store) : null;\n const presets = await presetCoverage(store, cfg);\n const staticLanguages = e && e.provider === 'static' ? readLanguages(e.model) : undefined;\n const declaredLanguages = staticLanguages && staticLanguages.length > 0 ? staticLanguages : null;\n const detectedLanguages = (await languageDistribution(store)) ?? null;\n const heartbeat = await getMeta(store, 'watch_heartbeat');\n // Derived at open() (F): 3x the largest reconcile this cache has ever held its write\n // transaction for, floored at 30s -- read back from the connection rather than\n // recomputed here, so this always reports what open() actually set. The pragma is\n // sqlite-engine-specific; other stores have no such setting and report null.\n const busyTimeoutMs = store.name === 'sqlite' ? ((await (await store.prepare('PRAGMA busy_timeout')).get()) as { timeout: number }).timeout : null;\n // The env var holds the token; only its name and whether it is set are ever reported.\n const keyEnv = e?.key ? { name: e.key, set: (process.env[e.key] ?? '') !== '' } : null;\n const result = {\n config: cfg.configPath,\n configVersion: SUPPORTED_CONFIG_VERSION,\n migratedFrom: cfg.migratedFrom ?? null,\n unknownConfigKeys: cfg.unknownKeys ?? null,\n tree: cfg.baseDir,\n cache: dirname(dbPath),\n db: dbPath,\n cacheSchema: SCHEMA_VERSION,\n docs: await docCount(store),\n unparseableFrontmatter: await parseErrorCount(store),\n features: features.on,\n featuresOff: features.off,\n embed: e ? { provider: e.provider, model: e.model, dir: e.provider === 'static' ? modelDir(e.model) : null, url: e.url ? redactUrl(e.url) : null, reachable, keyEnv, downloaded: hasModel, languages: declaredLanguages, detectedLanguages, ...(vectors ?? {}) } : null,\n presets,\n queries: Object.keys(cfg.queries ?? {}).length,\n watcherPid: await getMeta(store, 'watch_pid'),\n watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null,\n busyTimeoutMs,\n };\n\n if (format === 'json') {\n console.log(stringifyJson(result, 2));\n } else {\n const migrated = cfg.migratedFrom !== undefined ? `, migrated from v${cfg.migratedFrom} on this run` : '';\n console.log(`config: ${result.config} (v${SUPPORTED_CONFIG_VERSION}${migrated})`);\n // A load-time stderr warning has scrolled away by the time anyone looks here.\n if (cfg.unknownKeys) console.log(` unknown keys, ignored: ${cfg.unknownKeys.join(', ')}`);\n console.log(`tree: ${result.tree}`);\n console.log(`cache: ${result.cache} (schema ${SCHEMA_VERSION}; delete this directory to reset)`);\n console.log(`docs: ${result.docs}${result.unparseableFrontmatter > 0 ? ` (${result.unparseableFrontmatter} with unparseable frontmatter: WHERE _parse_error IS NOT NULL)` : ''}`);\n console.log('');\n console.log(featuresLine(features));\n // One authoritative block, off states included: an absent model reads as a degraded search,\n // not as an empty corpus.\n if (!e) console.log('embed: off (no preset asks for vectors)');\n else {\n console.log(`embed: ${e.provider} ${e.model}`);\n if (e.provider === 'static') console.log(` model: ${modelDir(e.model)} (${hasModel ? 'present' : `missing, ${isDownloadable(e.model) ? `fetches automatically at first search, or run \\`${ctx.name} download\\` to prefetch` : `no ${MODEL_FILENAMES} in that directory`}`})`);\n if (declaredLanguages) console.log(` languages: ${declaredLanguages.join(', ')} (declared by the model card)`);\n // Cohere defaults to api.cohere.com with no url in the config; show it anyway so the\n // reachability probe below has something to name.\n if (e.url || reachable !== null) {\n const shown = e.url ? redactUrl(e.url) : 'https://api.cohere.com (default)';\n console.log(` url: ${shown}${reachable === null ? '' : reachable ? ' (reachable)' : ' (unreachable)'}`);\n }\n if (keyEnv) console.log(` key: env ${keyEnv.name} (${keyEnv.set ? 'set' : 'NOT SET'})`);\n if (!hasModel) console.log(' vectors: off until the model is present; search runs on words and links');\n else if (vectors) console.log(` vectors: ${vectors.embedded} embedded, ${vectors.pending} pending (embedded on the first semantic search)`);\n if (detectedLanguages) {\n const total = Object.values(detectedLanguages).reduce((a, b) => a + b, 0);\n const breakdown = Object.entries(detectedLanguages)\n .sort((a, b) => b[1] - a[1])\n .map(([code, n]) => `${code} ${Math.round((n / total) * 100)}%`)\n .join(', ');\n console.log(` detected: ${breakdown} (${total} chunks classified)`);\n }\n }\n console.log('');\n for (const line of presetsLines(presets)) console.log(line);\n console.log('');\n console.log(`queries: ${result.queries} saved (${ctx.name} --list)`);\n const pid = result.watcherPid ? `pid ${result.watcherPid}, ` : '';\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: none' : `watcher: ${pid}last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n if (result.busyTimeoutMs !== null) console.log(`sqlite: busy_timeout ${result.busyTimeoutMs}ms (derived: 3x the largest reconcile this cache has recorded, floored at 30000ms)`);\n }\n await store.close();\n};\nexport default status;\n"],"names":["redactUrl","vectorState","store","stmt","prepare","get","parseErrorCount","n","url","parsed","URL","username","password","toString","replace","embedReachable","e","base","provider","probeReachable","status","ctx","process","cfg","values","format","dbPath","warnings","features","hasModel","reachable","vectors","presets","staticLanguages","declaredLanguages","detectedLanguages","heartbeat","busyTimeoutMs","keyEnv","result","migrated","shown","total","breakdown","line","pid","parse","argv","USAGE","name","FORMAT","CONFIG","formatOf","resolveConfig","config","openStore","printWarnings","featureStates","embedConfig","modelPresent","presetCoverage","readLanguages","model","undefined","length","languageDistribution","getMeta","timeout","key","set","env","configPath","configVersion","SUPPORTED_CONFIG_VERSION","migratedFrom","unknownConfigKeys","unknownKeys","tree","baseDir","cache","dirname","db","cacheSchema","SCHEMA_VERSION","docCount","docs","unparseableFrontmatter","on","featuresOff","off","embed","dir","modelDir","downloaded","languages","queries","Object","keys","watcherPid","watcherHeartbeatSecondsAgo","Math","round","Date","now","console","log","stringifyJson","join","featuresLine","isDownloadable","MODEL_FILENAMES","embedded","pending","reduce","a","b","entries","sort","map","code","presetsLines","close"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/status.ts"],"sourcesContent":["import { dirname } from 'node:path';\nimport { presetCoverage } from '../commands/status.ts';\nimport { embedConfig, featureStates, SUPPORTED_CONFIG_VERSION } from '../config/index.ts';\nimport { languageDistribution } from '../embed/distribution.ts';\nimport { probeReachable } from '../embed/http.ts';\nimport { isDownloadable, MODEL_FILENAMES, modelDir, modelPresent, readLanguages } from '../embed/store.ts';\nimport { featuresLine, presetsLines, stringifyJson } from '../output/output.ts';\nimport { docCount, getMeta, openStore } from '../store/index.ts';\nimport type { Store } from '../store/types.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// status names what you cannot read off the config file: locations sense chose, values it\n// derived, state it stored. Config content is not echoed -- the config line says which file to\n// read, and duplicating its globs here would create two places that disagree after an edit.\n// The exception is the embed block's url and key, whose effect is remote and otherwise invisible.\n\n// Vectors are computed on the first semantic query, not at reconcile, so a tree can have a\n// semantic-on preset with nothing embedded yet -- reported here because a fast reconcile on\n// such a tree otherwise reads as \"the feature isn't on\".\nasync function vectorState(store: Store): Promise<{ embedded: number; pending: number } | null> {\n try {\n const stmt = await store.prepare('SELECT COUNT(vector) AS embedded, COUNT(*) - COUNT(vector) AS pending FROM embeddings');\n return (await stmt.get()) as { embedded: number; pending: number };\n } catch {\n return null;\n }\n}\n\nasync function parseErrorCount(store: Store): Promise<number> {\n const stmt = await store.prepare(`SELECT COUNT(*) AS n FROM frontmatter WHERE \"_parse_error\" IS NOT NULL`);\n return ((await stmt.get()) as { n: number }).n;\n}\n\n// A URL can carry credentials in its userinfo (https://user:pass@host/v1). status output gets\n// pasted into issues and transcripts, so it is always safe to paste.\nexport function redactUrl(url: string): string {\n try {\n const parsed = new URL(url);\n if (!parsed.username && !parsed.password) return url;\n parsed.username = '';\n parsed.password = '';\n return `${parsed.toString().replace(/\\/$/, '')} (credentials redacted)`;\n } catch {\n return url;\n }\n}\n\n// A stopped Ollama/LM Studio/Cohere endpoint prints identically to a running one otherwise; any\n// HTTP response counts as reachable (probeReachable), so this only distinguishes up from down.\nasync function embedReachable(e: { provider: string; url?: string }): Promise<boolean | null> {\n if (e.provider === 'static' || (e.provider === 'openai' && !e.url)) return null;\n const base = (e.url ?? 'https://api.cohere.com').replace(/\\/+$/, '');\n return probeReachable(e.provider === 'openai' ? `${base}/models` : base);\n}\n\nconst status: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.status}`, { ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const cfg = ctx.resolveConfig(values.config as string | undefined);\n const { store, dbPath, warnings } = await openStore(cfg);\n printWarnings(warnings);\n\n const features = featureStates(cfg);\n const e = embedConfig(cfg);\n const hasModel = e ? modelPresent(cfg) : false;\n const reachable = e ? await embedReachable(e) : null;\n const vectors = e ? await vectorState(store) : null;\n const presets = await presetCoverage(store, cfg);\n const staticLanguages = e && e.provider === 'static' ? readLanguages(e.model) : undefined;\n const declaredLanguages = staticLanguages && staticLanguages.length > 0 ? staticLanguages : null;\n const detectedLanguages = (await languageDistribution(store)) ?? null;\n const heartbeat = await getMeta(store, 'watch_heartbeat');\n // Written by the store's open() on every open, so it is this cache's true version on either\n // store (sqlite 18, duckdb 2); a version mismatch already triggered a rebuild before this read.\n const cacheSchema = await getMeta(store, 'schema_version');\n // Derived at open() (F): 3x the largest reconcile this cache has ever held its write\n // transaction for, floored at 30s -- read back from the connection rather than\n // recomputed here, so this always reports what open() actually set. The pragma is\n // sqlite-engine-specific; other stores have no such setting and report null.\n const busyTimeoutMs = store.name === 'sqlite' ? ((await (await store.prepare('PRAGMA busy_timeout')).get()) as { timeout: number }).timeout : null;\n // The env var holds the token; only its name and whether it is set are ever reported.\n const keyEnv = e?.key ? { name: e.key, set: (process.env[e.key] ?? '') !== '' } : null;\n const result = {\n config: cfg.configPath,\n configVersion: SUPPORTED_CONFIG_VERSION,\n migratedFrom: cfg.migratedFrom ?? null,\n unknownConfigKeys: cfg.unknownKeys ?? null,\n tree: cfg.baseDir,\n cache: dirname(dbPath),\n db: dbPath,\n cacheSchema,\n docs: await docCount(store),\n unparseableFrontmatter: await parseErrorCount(store),\n features: features.on,\n featuresOff: features.off,\n embed: e ? { provider: e.provider, model: e.model, dir: e.provider === 'static' ? modelDir(e.model) : null, url: e.url ? redactUrl(e.url) : null, reachable, keyEnv, downloaded: hasModel, languages: declaredLanguages, detectedLanguages, ...(vectors ?? {}) } : null,\n presets,\n queries: Object.keys(cfg.queries ?? {}).length,\n watcherPid: await getMeta(store, 'watch_pid'),\n watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null,\n busyTimeoutMs,\n };\n\n if (format === 'json') {\n console.log(stringifyJson(result, 2));\n } else {\n const migrated = cfg.migratedFrom !== undefined ? `, migrated from v${cfg.migratedFrom} on this run` : '';\n console.log(`config: ${result.config} (v${SUPPORTED_CONFIG_VERSION}${migrated})`);\n // A load-time stderr warning has scrolled away by the time anyone looks here.\n if (cfg.unknownKeys) console.log(` unknown keys, ignored: ${cfg.unknownKeys.join(', ')}`);\n console.log(`tree: ${result.tree}`);\n console.log(`cache: ${result.cache} (schema ${result.cacheSchema}; delete this directory to reset)`);\n console.log(`docs: ${result.docs}${result.unparseableFrontmatter > 0 ? ` (${result.unparseableFrontmatter} with unparseable frontmatter: WHERE _parse_error IS NOT NULL)` : ''}`);\n console.log('');\n console.log(featuresLine(features));\n // One authoritative block, off states included: an absent model reads as a degraded search,\n // not as an empty corpus.\n if (!e) console.log('embed: off (no preset asks for vectors)');\n else {\n console.log(`embed: ${e.provider} ${e.model}`);\n if (e.provider === 'static') console.log(` model: ${modelDir(e.model)} (${hasModel ? 'present' : `missing, ${isDownloadable(e.model) ? `fetches automatically at first search, or run \\`${ctx.name} download\\` to prefetch` : `no ${MODEL_FILENAMES} in that directory`}`})`);\n if (declaredLanguages) console.log(` languages: ${declaredLanguages.join(', ')} (declared by the model card)`);\n // Cohere defaults to api.cohere.com with no url in the config; show it anyway so the\n // reachability probe below has something to name.\n if (e.url || reachable !== null) {\n const shown = e.url ? redactUrl(e.url) : 'https://api.cohere.com (default)';\n console.log(` url: ${shown}${reachable === null ? '' : reachable ? ' (reachable)' : ' (unreachable)'}`);\n }\n if (keyEnv) console.log(` key: env ${keyEnv.name} (${keyEnv.set ? 'set' : 'NOT SET'})`);\n if (!hasModel) console.log(' vectors: off until the model is present; search runs on words and links');\n else if (vectors) console.log(` vectors: ${vectors.embedded} embedded, ${vectors.pending} pending (embedded on the first semantic search)`);\n if (detectedLanguages) {\n const total = Object.values(detectedLanguages).reduce((a, b) => a + b, 0);\n const breakdown = Object.entries(detectedLanguages)\n .sort((a, b) => b[1] - a[1])\n .map(([code, n]) => `${code} ${Math.round((n / total) * 100)}%`)\n .join(', ');\n console.log(` detected: ${breakdown} (${total} chunks classified)`);\n }\n }\n console.log('');\n for (const line of presetsLines(presets)) console.log(line);\n console.log('');\n console.log(`queries: ${result.queries} saved (${ctx.name} --list)`);\n const pid = result.watcherPid ? `pid ${result.watcherPid}, ` : '';\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: none' : `watcher: ${pid}last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n if (result.busyTimeoutMs !== null) console.log(`sqlite: busy_timeout ${result.busyTimeoutMs}ms (derived: 3x the largest reconcile this cache has recorded, floored at 30000ms)`);\n }\n await store.close();\n};\nexport default status;\n"],"names":["redactUrl","vectorState","store","stmt","prepare","get","parseErrorCount","n","url","parsed","URL","username","password","toString","replace","embedReachable","e","base","provider","probeReachable","status","ctx","process","cfg","values","format","dbPath","warnings","features","hasModel","reachable","vectors","presets","staticLanguages","declaredLanguages","detectedLanguages","heartbeat","cacheSchema","busyTimeoutMs","keyEnv","result","migrated","shown","total","breakdown","line","pid","parse","argv","USAGE","name","FORMAT","CONFIG","formatOf","resolveConfig","config","openStore","printWarnings","featureStates","embedConfig","modelPresent","presetCoverage","readLanguages","model","undefined","length","languageDistribution","getMeta","timeout","key","set","env","configPath","configVersion","SUPPORTED_CONFIG_VERSION","migratedFrom","unknownConfigKeys","unknownKeys","tree","baseDir","cache","dirname","db","docCount","docs","unparseableFrontmatter","on","featuresOff","off","embed","dir","modelDir","downloaded","languages","queries","Object","keys","watcherPid","watcherHeartbeatSecondsAgo","Math","round","Date","now","console","log","stringifyJson","join","featuresLine","isDownloadable","MODEL_FILENAMES","embedded","pending","reduce","a","b","entries","sort","map","code","presetsLines","close"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/config/types.ts"],"sourcesContent":["import type { SignalWeights } from './signals.ts';\n\nexport const CONFIG_FILENAME = 'sense.config.json';\nexport const STATE_DIR = '.sense';\n\n// Highest sense.config.json `version` this build understands. Older versions auto-migrate on load.\nexport const SUPPORTED_CONFIG_VERSION = 5;\n\n// Each feature owns its tables, parse-time extraction, and reconcile step; commands degrade when one is off.\n// links/sections/tags/rank are opt-out toggles in the top-level `features` block; embed is not a\n// member of that block -- it is on exactly when an `embed` block names a model.\nexport const FEATURE_NAMES = ['links', 'sections', 'tags', 'rank', 'embed'] as const;\nexport type FeatureName = (typeof FEATURE_NAMES)[number];\n\n// `embed` names the model and gives the tree vectors at all; a preset's `signals` says which\n// engines that scope's searches use.\nexport interface EmbedConfig {\n model?: string;\n provider?: 'static' | 'openai' | 'cohere';\n url?: string; // openai provider: OpenAI-compatible base URL, e.g. http://localhost:11434/v1\n key?: string; // openai/cohere provider: name of the env var holding the bearer token, if any\n languages?: string[]; // owner-declared model languages; enables the language-fit check where no card exists\n chunkTokens?: number; // chunk size ceiling in estimated tokens for small-context models; default 500\n}\n\nexport const DEFAULT_EMBED_MODEL = 'minishlab/potion-retrieval-32M';\n\n// A named, self-contained file-selection scope. include/exclude are globby patterns resolved\n// relative to the config file. No inheritance between presets -- every field a preset wants\n// it declares itself. Presets may overlap freely; they are views, not partitions.\nexport interface Preset {\n include: string[];\n exclude?: string[];\n k?: number; // result count for `search` scoped to this preset; default 10\n // Exhaustive when present: every signal this preset's searches compose, each mapped to\n // its RRF weight (a finite number > 0; presence is enablement). Absent means every signal\n // whose prerequisite holds, each at weight 1 -- words always, links when the feature is on,\n // vectors when the tree names a model. A layer searched for exact wording (ingested sources,\n // archives, generated output) declares {\"words\":1,\"links\":1} and costs no embedding at all.\n signals?: SignalWeights;\n where?: string; // standing SQL condition against frontmatter alias `f`\n}\n\n// A saved `search` invocation: `sense <name>` runs like\n// `sense search <search> [--preset] [--include] [--exclude] [--where] [--k]`.\nexport interface SavedSearch {\n search: string;\n preset?: string;\n include?: string[];\n exclude?: string[];\n where?: string;\n k?: number;\n}\n\n// An entry names the verb it runs, one to one with the commands: { sql } runs like\n// `sense sql`, { search } like `sense search`.\nexport type SavedQuery = { sql: string } | SavedSearch;\n\nexport interface Config {\n // Editor-only pointer to schema.json; never read by sense.\n $schema?: string;\n version?: number;\n // File selection, index-time, and per-preset search defaults. A file is indexed iff any\n // preset's include/exclude covers it (union). `default` is used when a command names no preset.\n presets: Record<string, Preset>;\n // Global feature defaults; absent block or key means enabled. embed is not a member here --\n // see the `embed` block.\n features?: { links?: boolean; sections?: boolean; tags?: boolean; rank?: boolean };\n // Names the embedding model. Present means every indexed file gets vectors; absent means none do.\n embed?: EmbedConfig;\n // Settings for the `content` FTS5 table. `tokenize` decides which languages the tree can be\n // word-searched in at all; changing it rebuilds the index.\n content?: { tokenize?: string };\n // Backing store engine for this tree; defaults to \"sqlite\" (zero-dependency). \"duckdb\" is an\n // optional dependency and, in this build, implements only the portable surface (frontmatter,\n // links, sections, tags, rank, raw sql) -- a config needing lexical or vector search under it fails at open.\n store?: 'sqlite' | 'duckdb';\n queries: Record<string, SavedQuery>;\n}\n\nexport interface ResolvedConfig extends Config {\n baseDir: string;\n configPath: string | null;\n // Keys the file declares that this build does not read; cli reports them.\n unknownKeys?: string[];\n // Set when loadConfig auto-migrated the file on disk; cli reports it.\n migratedFrom?: number;\n}\n\nexport interface SearchOverrides {\n preset?: string;\n k?: number;\n where?: string;\n include?: string[];\n exclude?: string[];\n noExclude?: boolean; // drop the preset's exclude for this command; --exclude still applies\n}\n\nexport interface EffectiveSearch {\n presetName: string;\n k: number;\n where?: string;\n include: string[];\n exclude?: string[];\n signals: SignalWeights; // this preset's effective signal weights\n}\n"],"names":["CONFIG_FILENAME","DEFAULT_EMBED_MODEL","FEATURE_NAMES","STATE_DIR","SUPPORTED_CONFIG_VERSION"],"mappings":";;;;;;;;;;;QAEaA;eAAAA;;QAuBAC;eAAAA;;QAdAC;eAAAA;;QARAC;eAAAA;;QAGAC;eAAAA;;;AAJN,IAAMJ,kBAAkB;AACxB,IAAMG,YAAY;AAGlB,IAAMC,2BAA2B;AAKjC,IAAMF,gBAAgB;IAAC;IAAS;IAAY;IAAQ;IAAQ;CAAQ;AAcpE,IAAMD,sBAAsB"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/config/types.ts"],"sourcesContent":["import type { SignalWeights } from './signals.ts';\n\nexport const CONFIG_FILENAME = 'sense.config.json';\nexport const STATE_DIR = '.sense';\n\n// Highest sense.config.json `version` this build understands. Older versions auto-migrate on load.\nexport const SUPPORTED_CONFIG_VERSION = 5;\n\n// Each feature owns its tables, parse-time extraction, and reconcile step; commands degrade when one is off.\n// links/sections/tags/rank are opt-out toggles in the top-level `features` block; embed is not a\n// member of that block -- it is on exactly when an `embed` block names a model.\nexport const FEATURE_NAMES = ['links', 'sections', 'tags', 'rank', 'embed'] as const;\nexport type FeatureName = (typeof FEATURE_NAMES)[number];\n\n// `embed` names the model and gives the tree vectors at all; a preset's `signals` says which\n// engines that scope's searches use.\nexport interface EmbedConfig {\n model?: string;\n provider?: 'static' | 'openai' | 'cohere';\n url?: string; // openai provider: OpenAI-compatible base URL, e.g. http://localhost:11434/v1\n key?: string; // openai/cohere provider: name of the env var holding the bearer token, if any\n languages?: string[]; // owner-declared model languages; enables the language-fit check where no card exists\n chunkTokens?: number; // chunk size ceiling in estimated tokens for small-context models; default 500\n}\n\nexport const DEFAULT_EMBED_MODEL = 'minishlab/potion-retrieval-32M';\n\n// A named, self-contained file-selection scope. include/exclude are globby patterns resolved\n// relative to the config file. No inheritance between presets -- every field a preset wants\n// it declares itself. Presets may overlap freely; they are views, not partitions.\nexport interface Preset {\n include: string[];\n exclude?: string[];\n k?: number; // result count for `search` scoped to this preset; default 10\n // Exhaustive when present: every signal this preset's searches compose, each mapped to\n // its RRF weight (a finite number > 0; presence is enablement). Absent means every signal\n // whose prerequisite holds, each at weight 1 -- words always, links when the feature is on,\n // vectors when the tree names a model. A layer searched for exact wording (ingested sources,\n // archives, generated output) declares {\"words\":1,\"links\":1} and costs no embedding at all.\n signals?: SignalWeights;\n where?: string; // standing SQL condition against frontmatter alias `f`\n}\n\n// A saved `search` invocation: `sense <name>` runs like\n// `sense search <search> [--preset] [--include] [--exclude] [--where] [--k]`.\nexport interface SavedSearch {\n search: string;\n preset?: string;\n include?: string[];\n exclude?: string[];\n where?: string;\n k?: number;\n}\n\n// An entry names the verb it runs, one to one with the commands: { sql } runs like\n// `sense sql`, { search } like `sense search`.\nexport type SavedQuery = { sql: string } | SavedSearch;\n\nexport interface Config {\n // Editor-only pointer to schema.json; never read by sense.\n $schema?: string;\n version?: number;\n // File selection, index-time, and per-preset search defaults. A file is indexed iff any\n // preset's include/exclude covers it (union). `default` is used when a command names no preset.\n presets: Record<string, Preset>;\n // Global feature defaults; absent block or key means enabled. embed is not a member here --\n // see the `embed` block.\n features?: { links?: boolean; sections?: boolean; tags?: boolean; rank?: boolean };\n // Names the embedding model. Present means every indexed file gets vectors; absent means none do.\n embed?: EmbedConfig;\n // Settings for the `content` FTS5 table. `tokenize` decides which languages the tree can be\n // word-searched in at all; changing it rebuilds the index.\n content?: { tokenize?: string };\n // Backing store engine for this tree: \"sqlite\" (default, zero-dependency) or \"duckdb\"\n // (an optional dependency, installed on first use). Both implement the same commands.\n store?: 'sqlite' | 'duckdb';\n queries: Record<string, SavedQuery>;\n}\n\nexport interface ResolvedConfig extends Config {\n baseDir: string;\n configPath: string | null;\n // Keys the file declares that this build does not read; cli reports them.\n unknownKeys?: string[];\n // Set when loadConfig auto-migrated the file on disk; cli reports it.\n migratedFrom?: number;\n}\n\nexport interface SearchOverrides {\n preset?: string;\n k?: number;\n where?: string;\n include?: string[];\n exclude?: string[];\n noExclude?: boolean; // drop the preset's exclude for this command; --exclude still applies\n}\n\nexport interface EffectiveSearch {\n presetName: string;\n k: number;\n where?: string;\n include: string[];\n exclude?: string[];\n signals: SignalWeights; // this preset's effective signal weights\n}\n"],"names":["CONFIG_FILENAME","DEFAULT_EMBED_MODEL","FEATURE_NAMES","STATE_DIR","SUPPORTED_CONFIG_VERSION"],"mappings":";;;;;;;;;;;QAEaA;eAAAA;;QAuBAC;eAAAA;;QAdAC;eAAAA;;QARAC;eAAAA;;QAGAC;eAAAA;;;AAJN,IAAMJ,kBAAkB;AACxB,IAAMG,YAAY;AAGlB,IAAMC,2BAA2B;AAKjC,IAAMF,gBAAgB;IAAC;IAAS;IAAY;IAAQ;IAAQ;CAAQ;AAcpE,IAAMD,sBAAsB"}
@@ -35,17 +35,18 @@ function _unsupported_iterable_to_array(o, minLen) {
35
35
  if (n === "Map" || n === "Set") return Array.from(n);
36
36
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
37
37
  }
38
- // A frontmatter key with punctuation (`plugin-id`, `a.b`) is a real column, but naming it
39
- // unquoted in SQL parses as an expression: `plugin-id` is `plugin - id`, and SQLite's error
40
- // names a fragment (`plugin`) the user never wrote. This maps that fragment back to the
41
- // columns it could have come from, so the error names the actual fix instead.
38
+ // A frontmatter key with punctuation (`plugin-id`, `a.b`) is a real column, but unquoted in SQL
39
+ // it parses as an expression: `plugin - id`, or table `a` column `b`. SQLite names a fragment
40
+ // (`no such column: plugin`), DuckDB names the fragment or the table (`Referenced column/table
41
+ // "..." not found`); this maps either back to the real column so the error names the fix.
42
42
  function startsWithBoundary(name, prefix) {
43
43
  return name.length > prefix.length && name.startsWith(prefix) && /\W/.test(name[prefix.length]);
44
44
  }
45
45
  function columnHint(columns, err) {
46
- var match = /no such column: (\S+)/.exec(err.message);
46
+ var _ref, _match_;
47
+ var match = /no such column: (\S+)|Referenced column "([^"]+)" not found in FROM clause|Referenced table "([^"]+)" not found/.exec(err.message);
47
48
  if (!match) return err;
48
- var token = match[1];
49
+ var token = (_ref = (_match_ = match[1]) !== null && _match_ !== void 0 ? _match_ : match[2]) !== null && _ref !== void 0 ? _ref : match[3];
49
50
  // `f.plugin` -> `plugin`; left as-is when there's no leading alias segment, which also
50
51
  // covers a column literally named `a.b` -- the full-token check below matches that case
51
52
  // directly, so stripping here never needs to special-case it.
@@ -98,6 +99,6 @@ function columnHint(columns, err) {
98
99
  var quoted = _to_consumable_array(candidates).map(function(name) {
99
100
  return '"'.concat(name.split('"').join('""'), '"');
100
101
  }).join(', ');
101
- return new Error("".concat(err.message, " -- ").concat(quoted, " needs double quotes in SQL: unquoted, SQLite parses the punctuation as an operator instead of column syntax."));
102
+ return new Error("".concat(err.message, " -- ").concat(quoted, " needs double quotes in SQL: unquoted, the engine parses the punctuation as an operator or a qualifier, not part of a column name."));
102
103
  }
103
104
  /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/output/column-hint.ts"],"sourcesContent":["// A frontmatter key with punctuation (`plugin-id`, `a.b`) is a real column, but naming it\n// unquoted in SQL parses as an expression: `plugin-id` is `plugin - id`, and SQLite's error\n// names a fragment (`plugin`) the user never wrote. This maps that fragment back to the\n// columns it could have come from, so the error names the actual fix instead.\n\nfunction startsWithBoundary(name: string, prefix: string): boolean {\n return name.length > prefix.length && name.startsWith(prefix) && /\\W/.test(name[prefix.length]);\n}\n\n// columns: the tree's frontmatter columns (store.docs.columns()), read by the caller so this\n// stays a pure function rather than a store dependency.\nexport function columnHint(columns: string[], err: Error): Error {\n const match = /no such column: (\\S+)/.exec(err.message);\n if (!match) return err;\n const token = match[1];\n // `f.plugin` -> `plugin`; left as-is when there's no leading alias segment, which also\n // covers a column literally named `a.b` -- the full-token check below matches that case\n // directly, so stripping here never needs to special-case it.\n const aliasStripped = token.replace(/^[A-Za-z_]\\w*\\./, '');\n const forms = new Set([token, aliasStripped]);\n const candidates = new Set<string>();\n for (const name of columns) {\n for (const form of forms) {\n if (name === form || startsWithBoundary(name, form)) candidates.add(name);\n }\n }\n if (candidates.size === 0) return err;\n const quoted = [...candidates].map((name) => `\"${name.split('\"').join('\"\"')}\"`).join(', ');\n return new Error(`${err.message} -- ${quoted} needs double quotes in SQL: unquoted, SQLite parses the punctuation as an operator instead of column syntax.`);\n}\n"],"names":["columnHint","startsWithBoundary","name","prefix","length","startsWith","test","columns","err","match","exec","message","token","aliasStripped","replace","forms","Set","candidates","form","add","size","quoted","map","split","join","Error"],"mappings":";;;;+BAWgBA;;;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAXhB,0FAA0F;AAC1F,4FAA4F;AAC5F,wFAAwF;AACxF,8EAA8E;AAE9E,SAASC,mBAAmBC,IAAY,EAAEC,MAAc;IACtD,OAAOD,KAAKE,MAAM,GAAGD,OAAOC,MAAM,IAAIF,KAAKG,UAAU,CAACF,WAAW,KAAKG,IAAI,CAACJ,IAAI,CAACC,OAAOC,MAAM,CAAC;AAChG;AAIO,SAASJ,WAAWO,OAAiB,EAAEC,GAAU;IACtD,IAAMC,QAAQ,wBAAwBC,IAAI,CAACF,IAAIG,OAAO;IACtD,IAAI,CAACF,OAAO,OAAOD;IACnB,IAAMI,QAAQH,KAAK,CAAC,EAAE;IACtB,uFAAuF;IACvF,wFAAwF;IACxF,8DAA8D;IAC9D,IAAMI,gBAAgBD,MAAME,OAAO,CAAC,mBAAmB;IACvD,IAAMC,QAAQ,IAAIC,IAAI;QAACJ;QAAOC;KAAc;IAC5C,IAAMI,aAAa,IAAID;QAClB,kCAAA,2BAAA;;QAAL,QAAK,YAAcT,4BAAd,SAAA,6BAAA,QAAA,yBAAA,iCAAuB;YAAvB,IAAML,OAAN;gBACE,mCAAA,4BAAA;;gBAAL,QAAK,aAAca,0BAAd,UAAA,8BAAA,SAAA,0BAAA,kCAAqB;oBAArB,IAAMG,OAAN;oBACH,IAAIhB,SAASgB,QAAQjB,mBAAmBC,MAAMgB,OAAOD,WAAWE,GAAG,CAACjB;gBACtE;;gBAFK;gBAAA;;;yBAAA,8BAAA;wBAAA;;;wBAAA;8BAAA;;;;QAGP;;QAJK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAKL,IAAIe,WAAWG,IAAI,KAAK,GAAG,OAAOZ;IAClC,IAAMa,SAAS,AAAC,qBAAGJ,YAAYK,GAAG,CAAC,SAACpB;eAAS,AAAC,IAA8B,OAA3BA,KAAKqB,KAAK,CAAC,KAAKC,IAAI,CAAC,OAAM;OAAIA,IAAI,CAAC;IACrF,OAAO,IAAIC,MAAM,AAAC,GAAoBJ,OAAlBb,IAAIG,OAAO,EAAC,QAAa,OAAPU,QAAO;AAC/C"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/output/column-hint.ts"],"sourcesContent":["// A frontmatter key with punctuation (`plugin-id`, `a.b`) is a real column, but unquoted in SQL\n// it parses as an expression: `plugin - id`, or table `a` column `b`. SQLite names a fragment\n// (`no such column: plugin`), DuckDB names the fragment or the table (`Referenced column/table\n// \"...\" not found`); this maps either back to the real column so the error names the fix.\n\nfunction startsWithBoundary(name: string, prefix: string): boolean {\n return name.length > prefix.length && name.startsWith(prefix) && /\\W/.test(name[prefix.length]);\n}\n\n// columns: the tree's frontmatter columns (store.docs.columns()), read by the caller so this\n// stays a pure function rather than a store dependency.\nexport function columnHint(columns: string[], err: Error): Error {\n const match = /no such column: (\\S+)|Referenced column \"([^\"]+)\" not found in FROM clause|Referenced table \"([^\"]+)\" not found/.exec(err.message);\n if (!match) return err;\n const token = match[1] ?? match[2] ?? match[3];\n // `f.plugin` -> `plugin`; left as-is when there's no leading alias segment, which also\n // covers a column literally named `a.b` -- the full-token check below matches that case\n // directly, so stripping here never needs to special-case it.\n const aliasStripped = token.replace(/^[A-Za-z_]\\w*\\./, '');\n const forms = new Set([token, aliasStripped]);\n const candidates = new Set<string>();\n for (const name of columns) {\n for (const form of forms) {\n if (name === form || startsWithBoundary(name, form)) candidates.add(name);\n }\n }\n if (candidates.size === 0) return err;\n const quoted = [...candidates].map((name) => `\"${name.split('\"').join('\"\"')}\"`).join(', ');\n return new Error(`${err.message} -- ${quoted} needs double quotes in SQL: unquoted, the engine parses the punctuation as an operator or a qualifier, not part of a column name.`);\n}\n"],"names":["columnHint","startsWithBoundary","name","prefix","length","startsWith","test","columns","err","match","exec","message","token","aliasStripped","replace","forms","Set","candidates","form","add","size","quoted","map","split","join","Error"],"mappings":";;;;+BAWgBA;;;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAXhB,gGAAgG;AAChG,8FAA8F;AAC9F,+FAA+F;AAC/F,0FAA0F;AAE1F,SAASC,mBAAmBC,IAAY,EAAEC,MAAc;IACtD,OAAOD,KAAKE,MAAM,GAAGD,OAAOC,MAAM,IAAIF,KAAKG,UAAU,CAACF,WAAW,KAAKG,IAAI,CAACJ,IAAI,CAACC,OAAOC,MAAM,CAAC;AAChG;AAIO,SAASJ,WAAWO,OAAiB,EAAEC,GAAU;QAGxCC,MAAAA;IAFd,IAAMA,QAAQ,kHAAkHC,IAAI,CAACF,IAAIG,OAAO;IAChJ,IAAI,CAACF,OAAO,OAAOD;IACnB,IAAMI,SAAQH,QAAAA,UAAAA,KAAK,CAAC,EAAE,cAARA,qBAAAA,UAAYA,KAAK,CAAC,EAAE,cAApBA,kBAAAA,OAAwBA,KAAK,CAAC,EAAE;IAC9C,uFAAuF;IACvF,wFAAwF;IACxF,8DAA8D;IAC9D,IAAMI,gBAAgBD,MAAME,OAAO,CAAC,mBAAmB;IACvD,IAAMC,QAAQ,IAAIC,IAAI;QAACJ;QAAOC;KAAc;IAC5C,IAAMI,aAAa,IAAID;QAClB,kCAAA,2BAAA;;QAAL,QAAK,YAAcT,4BAAd,SAAA,6BAAA,QAAA,yBAAA,iCAAuB;YAAvB,IAAML,OAAN;gBACE,mCAAA,4BAAA;;gBAAL,QAAK,aAAca,0BAAd,UAAA,8BAAA,SAAA,0BAAA,kCAAqB;oBAArB,IAAMG,OAAN;oBACH,IAAIhB,SAASgB,QAAQjB,mBAAmBC,MAAMgB,OAAOD,WAAWE,GAAG,CAACjB;gBACtE;;gBAFK;gBAAA;;;yBAAA,8BAAA;wBAAA;;;wBAAA;8BAAA;;;;QAGP;;QAJK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAKL,IAAIe,WAAWG,IAAI,KAAK,GAAG,OAAOZ;IAClC,IAAMa,SAAS,AAAC,qBAAGJ,YAAYK,GAAG,CAAC,SAACpB;eAAS,AAAC,IAA8B,OAA3BA,KAAKqB,KAAK,CAAC,KAAKC,IAAI,CAAC,OAAM;OAAIA,IAAI,CAAC;IACrF,OAAO,IAAIC,MAAM,AAAC,GAAoBJ,OAAlBb,IAAIG,OAAO,EAAC,QAAa,OAAPU,QAAO;AAC/C"}
@@ -7,4 +7,9 @@ export interface ReparseResult {
7
7
  warnings: string[];
8
8
  newColumns: string[];
9
9
  }
10
- export declare function reparseFiles(files: FileStat[], features: Feature[], cfg: Config, knownColumns: ReadonlySet<string>, onParsed?: (done: number) => void): ReparseResult;
10
+ export interface ReparseOptions {
11
+ threshold?: number;
12
+ maxWorkers?: number;
13
+ }
14
+ export declare function featuresForFile(features: Feature[], cfg: Config, file: FileStat): Feature[];
15
+ export declare function reparseFiles(files: FileStat[], features: Feature[], cfg: Config, knownColumns: ReadonlySet<string>, onParsed?: (done: number) => void, options?: ReparseOptions): Promise<ReparseResult>;
@@ -7,4 +7,9 @@ export interface ReparseResult {
7
7
  warnings: string[];
8
8
  newColumns: string[];
9
9
  }
10
- export declare function reparseFiles(files: FileStat[], features: Feature[], cfg: Config, knownColumns: ReadonlySet<string>, onParsed?: (done: number) => void): ReparseResult;
10
+ export interface ReparseOptions {
11
+ threshold?: number;
12
+ maxWorkers?: number;
13
+ }
14
+ export declare function featuresForFile(features: Feature[], cfg: Config, file: FileStat): Feature[];
15
+ export declare function reparseFiles(files: FileStat[], features: Feature[], cfg: Config, knownColumns: ReadonlySet<string>, onParsed?: (done: number) => void, options?: ReparseOptions): Promise<ReparseResult>;