sensemaking 0.9.1 → 0.9.3

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 (79) hide show
  1. package/README.md +7 -2
  2. package/bin/cli.js +5 -1
  3. package/dist/cjs/cli/check.js +36 -4
  4. package/dist/cjs/cli/check.js.map +1 -1
  5. package/dist/cjs/cli/exit.d.cts +5 -0
  6. package/dist/cjs/cli/exit.d.ts +5 -0
  7. package/dist/cjs/cli/exit.js +147 -0
  8. package/dist/cjs/cli/exit.js.map +1 -0
  9. package/dist/cjs/cli/index.d.cts +11 -0
  10. package/dist/cjs/cli/index.d.ts +11 -0
  11. package/dist/cjs/cli/index.js +22 -3
  12. package/dist/cjs/cli/index.js.map +1 -1
  13. package/dist/cjs/cli/init.js +3 -0
  14. package/dist/cjs/cli/init.js.map +1 -1
  15. package/dist/cjs/cli/map.js +33 -2
  16. package/dist/cjs/cli/map.js.map +1 -1
  17. package/dist/cjs/cli/named.d.cts +1 -1
  18. package/dist/cjs/cli/named.d.ts +1 -1
  19. package/dist/cjs/cli/named.js +48 -17
  20. package/dist/cjs/cli/named.js.map +1 -1
  21. package/dist/cjs/cli/peek.js +36 -4
  22. package/dist/cjs/cli/peek.js.map +1 -1
  23. package/dist/cjs/cli/query.js +35 -3
  24. package/dist/cjs/cli/query.js.map +1 -1
  25. package/dist/cjs/cli/rebuild.js +31 -1
  26. package/dist/cjs/cli/rebuild.js.map +1 -1
  27. package/dist/cjs/cli/search.js +42 -10
  28. package/dist/cjs/cli/search.js.map +1 -1
  29. package/dist/cjs/cli/shared.d.cts +18 -2
  30. package/dist/cjs/cli/shared.d.ts +18 -2
  31. package/dist/cjs/cli/shared.js +238 -11
  32. package/dist/cjs/cli/shared.js.map +1 -1
  33. package/dist/cjs/cli/status.js +5 -2
  34. package/dist/cjs/cli/status.js.map +1 -1
  35. package/dist/cjs/cli/types.d.cts +2 -12
  36. package/dist/cjs/cli/types.d.ts +2 -12
  37. package/dist/cjs/cli/watch.js +38 -2
  38. package/dist/cjs/cli/watch.js.map +1 -1
  39. package/dist/cjs/cli.js +147 -150
  40. package/dist/cjs/cli.js.map +1 -1
  41. package/dist/cjs/db.js +5 -0
  42. package/dist/cjs/db.js.map +1 -1
  43. package/dist/esm/cli/check.js +11 -4
  44. package/dist/esm/cli/check.js.map +1 -1
  45. package/dist/esm/cli/exit.d.ts +5 -0
  46. package/dist/esm/cli/exit.js +15 -0
  47. package/dist/esm/cli/exit.js.map +1 -0
  48. package/dist/esm/cli/index.d.ts +11 -0
  49. package/dist/esm/cli/index.js +14 -0
  50. package/dist/esm/cli/index.js.map +1 -1
  51. package/dist/esm/cli/init.js +3 -0
  52. package/dist/esm/cli/init.js.map +1 -1
  53. package/dist/esm/cli/map.js +11 -3
  54. package/dist/esm/cli/map.js.map +1 -1
  55. package/dist/esm/cli/named.d.ts +1 -1
  56. package/dist/esm/cli/named.js +25 -18
  57. package/dist/esm/cli/named.js.map +1 -1
  58. package/dist/esm/cli/peek.js +12 -5
  59. package/dist/esm/cli/peek.js.map +1 -1
  60. package/dist/esm/cli/query.js +11 -4
  61. package/dist/esm/cli/query.js.map +1 -1
  62. package/dist/esm/cli/rebuild.js +6 -2
  63. package/dist/esm/cli/rebuild.js.map +1 -1
  64. package/dist/esm/cli/search.js +18 -10
  65. package/dist/esm/cli/search.js.map +1 -1
  66. package/dist/esm/cli/shared.d.ts +18 -2
  67. package/dist/esm/cli/shared.js +100 -11
  68. package/dist/esm/cli/shared.js.map +1 -1
  69. package/dist/esm/cli/status.js +9 -3
  70. package/dist/esm/cli/status.js.map +1 -1
  71. package/dist/esm/cli/types.d.ts +2 -12
  72. package/dist/esm/cli/types.js.map +1 -1
  73. package/dist/esm/cli/watch.js +11 -3
  74. package/dist/esm/cli/watch.js.map +1 -1
  75. package/dist/esm/cli.js +83 -102
  76. package/dist/esm/cli.js.map +1 -1
  77. package/dist/esm/db.js +5 -0
  78. package/dist/esm/db.js.map +1 -1
  79. package/package.json +3 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/shared.ts"],"sourcesContent":["import type { ResolvedConfig } from '../config.ts';\nimport type { OpenResult } from '../db.ts';\nimport { open } from '../db.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } from '../output.ts';\nimport { searchError } from '../search-error.ts';\nimport type { Ctx } from './types.ts';\n\n// --k must be a positive integer: SQLite reads a bound LIMIT of -1 as \"unlimited\" and 0 as\n// \"nothing\", and parseInt would silently truncate \"5.9\" -- all three are caller mistakes\n// worth a usage error, matching the config-level SavedSearch validation.\nexport function parseK(ctx: Ctx): number | undefined {\n if (ctx.values.k === undefined) return undefined;\n const k = Number(ctx.values.k);\n if (!Number.isInteger(k) || k <= 0) ctx.usageError(`--k expects a positive integer, got \"${ctx.values.k}\"`);\n return k;\n}\n\n// Shared open-query-close envelope for commands that touch the tree.\n\nexport function printWarnings(warnings: string[]): void {\n for (const w of warnings) console.warn(w);\n}\n\nexport async function withDb(ctx: Ctx, fn: (db: OpenResult['db'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void> {\n const cfg = ctx.resolveConfig();\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n try {\n await fn(db, cfg);\n } finally {\n db.close();\n }\n}\n\n// An unbound `?` silently binds NULL, so mismatched param counts fail loudly instead.\nexport function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: 'table' | 'json', label: string): void {\n const placeholderCount = (sql.match(/\\?/g) ?? []).length;\n if (params.length !== placeholderCount) {\n console.error(`${label} expects ${placeholderCount} parameter(s), got ${params.length}`);\n process.exit(2);\n }\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n let rows: Row[];\n try {\n rows = db.prepare(sql).all(...params) as Row[];\n } catch (err) {\n db.close();\n // A saved query or ad-hoc SQL can carry `content MATCH ?` too, so the same FTS5\n // punctuation trap applies -- the bound parameters are the search terms there. SQL\n // without MATCH gets its error verbatim; search advice on a plain typo would mislead.\n if (/\\bMATCH\\b/i.test(sql)) throw searchError(err as Error, params.join(' '));\n throw err;\n }\n printRows(rows, format);\n db.close();\n}\n"],"names":["open","printRows","searchError","parseK","ctx","values","k","undefined","Number","isInteger","usageError","printWarnings","warnings","w","console","warn","withDb","fn","cfg","resolveConfig","db","close","runSql","sql","params","format","label","placeholderCount","match","length","error","process","exit","rows","prepare","all","err","test","join"],"mappings":"AAEA,SAASA,IAAI,QAAQ,WAAW;AAEhC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,WAAW,QAAQ,qBAAqB;AAGjD,2FAA2F;AAC3F,yFAAyF;AACzF,yEAAyE;AACzE,OAAO,SAASC,OAAOC,GAAQ;IAC7B,IAAIA,IAAIC,MAAM,CAACC,CAAC,KAAKC,WAAW,OAAOA;IACvC,MAAMD,IAAIE,OAAOJ,IAAIC,MAAM,CAACC,CAAC;IAC7B,IAAI,CAACE,OAAOC,SAAS,CAACH,MAAMA,KAAK,GAAGF,IAAIM,UAAU,CAAC,CAAC,qCAAqC,EAAEN,IAAIC,MAAM,CAACC,CAAC,CAAC,CAAC,CAAC;IAC1G,OAAOA;AACT;AAEA,qEAAqE;AAErE,OAAO,SAASK,cAAcC,QAAkB;IAC9C,KAAK,MAAMC,KAAKD,SAAUE,QAAQC,IAAI,CAACF;AACzC;AAEA,OAAO,eAAeG,OAAOZ,GAAQ,EAAEa,EAAuE;IAC5G,MAAMC,MAAMd,IAAIe,aAAa;IAC7B,MAAM,EAAEC,EAAE,EAAER,QAAQ,EAAE,GAAGZ,KAAKkB;IAC9BP,cAAcC;IACd,IAAI;QACF,MAAMK,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;QACtCb,QAAQgB,KAAK,CAAC,GAAGJ,MAAM,SAAS,EAAEC,iBAAiB,mBAAmB,EAAEH,OAAOK,MAAM,EAAE;QACvFE,QAAQC,IAAI,CAAC;IACf;IACA,MAAM,EAAEZ,EAAE,EAAER,QAAQ,EAAE,GAAGZ,KAAKkB;IAC9BP,cAAcC;IACd,IAAIqB;IACJ,IAAI;QACFA,OAAOb,GAAGc,OAAO,CAACX,KAAKY,GAAG,IAAIX;IAChC,EAAE,OAAOY,KAAK;QACZhB,GAAGC,KAAK;QACR,gFAAgF;QAChF,mFAAmF;QACnF,sFAAsF;QACtF,IAAI,aAAagB,IAAI,CAACd,MAAM,MAAMrB,YAAYkC,KAAcZ,OAAOc,IAAI,CAAC;QACxE,MAAMF;IACR;IACAnC,UAAUgC,MAAMR;IAChBL,GAAGC,KAAK;AACV"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/shared.ts"],"sourcesContent":["import getopts from 'getopts-compat';\nimport type { ResolvedConfig } from '../config.ts';\nimport type { OpenResult } from '../db.ts';\nimport { open } from '../db.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } from '../output.ts';\nimport { searchError } from '../search-error.ts';\nimport { ExitError, usageError } from './exit.ts';\nimport type { Ctx } from './types.ts';\n\n// Flag descriptors, spreadable so one flag name keeps one meaning across every command's\n// table. parse() converts them to the getopts call the rest of the CLIs here make directly.\nexport interface Flag {\n type: 'string' | 'boolean';\n default?: string | boolean;\n multiple?: boolean;\n short?: string;\n}\nexport type Flags = Record<string, Flag>;\n\nexport const FORMAT: Flags = { format: { type: 'string', default: 'table' } };\nexport const CONFIG: Flags = { config: { type: 'string' } };\nexport const SEARCH_FLAGS: Flags = {\n where: { type: 'string' },\n k: { type: 'string' },\n preset: { type: 'string' },\n include: { type: 'string', multiple: true },\n lexical: { type: 'boolean', default: false },\n};\n\nexport type Values = Record<string, string | boolean | string[] | undefined>;\n\nexport function formatOf(values: Values): 'table' | 'json' {\n return values.format === 'json' ? 'json' : 'table';\n}\n\n// Per-command parse: strict (a foreign flag exits 2), and every table gets --help for free.\nexport function parse(argv: string[], usage: string, flags: Flags = {}): { values: Values; positionals: string[] } {\n const table: Flags = { ...flags, help: { type: 'boolean', default: false, short: 'h' } };\n const string: string[] = [];\n const boolean: string[] = [];\n const alias: Record<string, string> = {};\n const defaults: Record<string, string | boolean> = {};\n for (const [name, flag] of Object.entries(table)) {\n (flag.type === 'boolean' ? boolean : string).push(name);\n if (flag.default !== undefined) defaults[name] = flag.default;\n if (flag.short !== undefined) alias[name] = flag.short;\n }\n\n // getopts is lenient about undeclared flags -- they land in the result and are silently\n // ignored, which is the bug 0.9.2 fixed. Record the first and fail below; returning false\n // also keeps it out of the result. `--k -1` arrives here as unknown option \"1\", because\n // getopts reads a leading dash as a new option rather than as --k's value; the message is\n // blunter than the old one but it is still a usage error rather than a silent default.\n let unknown: string | undefined;\n const parsed = getopts(argv, {\n string,\n boolean,\n alias,\n default: defaults,\n unknown: (name: string): boolean => {\n if (unknown === undefined) unknown = name;\n return false;\n },\n });\n if (unknown !== undefined) usageError(`unknown option: ${unknown}`, usage);\n if (parsed.help) {\n console.log(usage);\n throw new ExitError(0);\n }\n\n // Two getopts shapes the callers must not see: an unset string flag reads as \"\" rather\n // than undefined, and a flag passed once reads as a string rather than a one-element\n // array. Both matter -- `?? saved.field` means \"flag absent\", and --include is a list.\n const values: Values = {};\n for (const [name, flag] of Object.entries(table)) {\n const raw = parsed[name];\n if (flag.type === 'boolean') values[name] = raw as boolean;\n else if (flag.multiple) values[name] = raw === '' ? undefined : Array.isArray(raw) ? (raw as string[]) : [raw as string];\n else values[name] = raw === '' ? undefined : (raw as string);\n }\n return { values, positionals: parsed._ };\n}\n\n// --k must be a positive integer: SQLite reads a bound LIMIT of -1 as \"unlimited\" and 0 as\n// \"nothing\", and parseInt would silently truncate \"5.9\" -- all three are caller mistakes\n// worth a usage error, matching the config-level SavedSearch validation.\nexport function parseK(k: string | undefined, usageErrorFn: (message: string) => never): number | undefined {\n if (k === undefined) return undefined;\n const parsed = Number(k);\n if (!Number.isInteger(parsed) || parsed <= 0) usageErrorFn(`--k expects a positive integer, got \"${k}\"`);\n return parsed;\n}\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, configPath: string | undefined, fn: (db: OpenResult['db'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void> {\n const cfg = ctx.resolveConfig(configPath);\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) usageError(`${label} expects ${placeholderCount} parameter(s), got ${params.length}`);\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n let rows: Row[];\n try {\n rows = db.prepare(sql).all(...params) as Row[];\n } catch (err) {\n db.close();\n // A saved query or ad-hoc SQL can carry `content MATCH ?` too, so the same FTS5\n // punctuation trap applies -- the bound parameters are the search terms there. SQL\n // without MATCH gets its error verbatim; search advice on a plain typo would mislead.\n if (/\\bMATCH\\b/i.test(sql)) throw searchError(err as Error, params.join(' '));\n throw err;\n }\n printRows(rows, format);\n db.close();\n}\n"],"names":["getopts","open","printRows","searchError","ExitError","usageError","FORMAT","format","type","default","CONFIG","config","SEARCH_FLAGS","where","k","preset","include","multiple","lexical","formatOf","values","parse","argv","usage","flags","table","help","short","string","boolean","alias","defaults","name","flag","Object","entries","push","undefined","unknown","parsed","console","log","raw","Array","isArray","positionals","_","parseK","usageErrorFn","Number","isInteger","printWarnings","warnings","w","warn","withDb","ctx","configPath","fn","cfg","resolveConfig","db","close","runSql","sql","params","label","placeholderCount","match","length","rows","prepare","all","err","test","join"],"mappings":"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"}
@@ -2,7 +2,8 @@ import { presetCoverage } from '../commands.js';
2
2
  import { embedConfig, featureStates } from '../config.js';
3
3
  import { docCount, getMeta, open } from '../db.js';
4
4
  import { featuresLine, presetsLines } from '../output.js';
5
- import { printWarnings } from './shared.js';
5
+ import { USAGE } from './index.js';
6
+ import { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.js';
6
7
  // Vectors are computed on the first semantic query, not at reconcile, so a tree can have a
7
8
  // semantic-on preset with nothing embedded yet -- reported here because a fast `rebuild` on
8
9
  // such a tree otherwise reads as "the feature isn't on".
@@ -15,7 +16,12 @@ function vectorState(db) {
15
16
  }
16
17
  }
17
18
  const status = (ctx)=>{
18
- const cfg = ctx.resolveConfig();
19
+ const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.status}`, {
20
+ ...FORMAT,
21
+ ...CONFIG
22
+ });
23
+ const format = formatOf(values);
24
+ const cfg = ctx.resolveConfig(values.config);
19
25
  const { db, dbPath, warnings } = open(cfg);
20
26
  printWarnings(warnings);
21
27
  const features = featureStates(cfg);
@@ -41,7 +47,7 @@ const status = (ctx)=>{
41
47
  watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null,
42
48
  busyTimeoutMs
43
49
  };
44
- if (ctx.format === 'json') {
50
+ if (format === 'json') {
45
51
  console.log(JSON.stringify(result, null, 2));
46
52
  } else {
47
53
  console.log(`db: ${result.db}`);
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/status.ts"],"sourcesContent":["import { presetCoverage } from '../commands.ts';\nimport { embedConfig, featureStates } from '../config.ts';\nimport { docCount, getMeta, open } from '../db.ts';\nimport { featuresLine, presetsLines } from '../output.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 have a\n// semantic-on preset with nothing embedded yet -- reported here because a fast `rebuild` on\n// such a 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 presets = presetCoverage(db, cfg);\n const heartbeat = getMeta(db, '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.\n const busyTimeoutMs = (db.prepare('PRAGMA busy_timeout').get() as { timeout: number }).timeout;\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 presets,\n watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null,\n busyTimeoutMs,\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 console.log(featuresLine(features));\n if (e) console.log(`embed: ${e.type} ${e.model}${vectors ? ` (vectors: ${vectors.embedded} embedded, ${vectors.pending} pending — embedded on the first semantic search)` : ''}`);\n for (const line of presetsLines(presets)) console.log(line);\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: no watcher' : `watcher: last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n console.log(`busy_timeout: ${result.busyTimeoutMs}ms (derived: 3x the largest reconcile this cache has recorded, floored at 30000ms)`);\n }\n db.close();\n};\nexport default status;\n"],"names":["presetCoverage","embedConfig","featureStates","docCount","getMeta","open","featuresLine","presetsLines","printWarnings","vectorState","db","row","prepare","get","status","ctx","cfg","resolveConfig","dbPath","warnings","features","e","vectors","presets","heartbeat","busyTimeoutMs","timeout","result","docs","on","featuresOff","off","embed","type","model","watcherHeartbeatSecondsAgo","Math","round","Date","now","parse","format","console","log","JSON","stringify","embedded","pending","line","close"],"mappings":"AAAA,SAASA,cAAc,QAAQ,iBAAiB;AAChD,SAASC,WAAW,EAAEC,aAAa,QAAQ,eAAe;AAC1D,SAASC,QAAQ,EAAEC,OAAO,EAAEC,IAAI,QAAQ,WAAW;AACnD,SAASC,YAAY,EAAEC,YAAY,QAAQ,eAAe;AAC1D,SAASC,aAAa,QAAQ,cAAc;AAG5C,2FAA2F;AAC3F,4FAA4F;AAC5F,yDAAyD;AACzD,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;IACvB,MAAMC,MAAMD,IAAIE,aAAa;IAC7B,MAAM,EAAEP,EAAE,EAAEQ,MAAM,EAAEC,QAAQ,EAAE,GAAGd,KAAKW;IACtCR,cAAcW;IAEd,MAAMC,WAAWlB,cAAcc;IAC/B,MAAMK,IAAIpB,YAAYe;IACtB,MAAMM,UAAUD,IAAIZ,YAAYC,MAAM;IACtC,MAAMa,UAAUvB,eAAeU,IAAIM;IACnC,MAAMQ,YAAYpB,QAAQM,IAAI;IAC9B,qFAAqF;IACrF,+EAA+E;IAC/E,oEAAoE;IACpE,MAAMe,gBAAgB,AAACf,GAAGE,OAAO,CAAC,uBAAuBC,GAAG,GAA2Ba,OAAO;IAC9F,MAAMC,SAAS;QACbjB,IAAIQ;QACJU,MAAMzB,SAASO;QACfU,UAAUA,SAASS,EAAE;QACrBC,aAAaV,SAASW,GAAG;QACzBC,OAAOX,IAAI;YAAEY,MAAMZ,EAAEY,IAAI;YAAEC,OAAOb,EAAEa,KAAK;eAAMZ,oBAAAA,qBAAAA,UAAW,CAAC,CAAhB;QAAmB,IAAI;QAClEC;QACAY,4BAA4BX,YAAYY,KAAKC,KAAK,CAAC,AAACC,CAAAA,KAAKC,GAAG,KAAKD,KAAKE,KAAK,CAAChB,UAAS,IAAK,QAAQ;QAClGC;IACF;IAEA,IAAIV,IAAI0B,MAAM,KAAK,QAAQ;QACzBC,QAAQC,GAAG,CAACC,KAAKC,SAAS,CAAClB,QAAQ,MAAM;IAC3C,OAAO;QACLe,QAAQC,GAAG,CAAC,CAAC,IAAI,EAAEhB,OAAOjB,EAAE,EAAE;QAC9BgC,QAAQC,GAAG,CAAC,CAAC,MAAM,EAAEhB,OAAOC,IAAI,EAAE;QAClCc,QAAQC,GAAG,CAACrC,aAAac;QACzB,IAAIC,GAAGqB,QAAQC,GAAG,CAAC,CAAC,OAAO,EAAEtB,EAAEY,IAAI,CAAC,CAAC,EAAEZ,EAAEa,KAAK,GAAGZ,UAAU,CAAC,WAAW,EAAEA,QAAQwB,QAAQ,CAAC,WAAW,EAAExB,QAAQyB,OAAO,CAAC,iDAAiD,CAAC,GAAG,IAAI;QAChL,KAAK,MAAMC,QAAQzC,aAAagB,SAAUmB,QAAQC,GAAG,CAACK;QACtDN,QAAQC,GAAG,CAAChB,OAAOQ,0BAA0B,KAAK,OAAO,wBAAwB,CAAC,wBAAwB,EAAER,OAAOQ,0BAA0B,CAAC,KAAK,CAAC;QACpJO,QAAQC,GAAG,CAAC,CAAC,cAAc,EAAEhB,OAAOF,aAAa,CAAC,kFAAkF,CAAC;IACvI;IACAf,GAAGuC,KAAK;AACV;AACA,eAAenC,OAAO"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/status.ts"],"sourcesContent":["import { presetCoverage } from '../commands.ts';\nimport { embedConfig, featureStates } from '../config.ts';\nimport { docCount, getMeta, open } from '../db.ts';\nimport { featuresLine, presetsLines } from '../output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, 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 have a\n// semantic-on preset with nothing embedded yet -- reported here because a fast `rebuild` on\n// such a 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 { 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 { 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 presets = presetCoverage(db, cfg);\n const heartbeat = getMeta(db, '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.\n const busyTimeoutMs = (db.prepare('PRAGMA busy_timeout').get() as { timeout: number }).timeout;\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 presets,\n watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null,\n busyTimeoutMs,\n };\n\n if (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 console.log(featuresLine(features));\n if (e) console.log(`embed: ${e.type} ${e.model}${vectors ? ` (vectors: ${vectors.embedded} embedded, ${vectors.pending} pending — embedded on the first semantic search)` : ''}`);\n for (const line of presetsLines(presets)) console.log(line);\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: no watcher' : `watcher: last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n console.log(`busy_timeout: ${result.busyTimeoutMs}ms (derived: 3x the largest reconcile this cache has recorded, floored at 30000ms)`);\n }\n db.close();\n};\nexport default status;\n"],"names":["presetCoverage","embedConfig","featureStates","docCount","getMeta","open","featuresLine","presetsLines","USAGE","CONFIG","FORMAT","formatOf","parse","printWarnings","vectorState","db","row","prepare","get","status","ctx","values","argv","name","format","cfg","resolveConfig","config","dbPath","warnings","features","e","vectors","presets","heartbeat","busyTimeoutMs","timeout","result","docs","on","featuresOff","off","embed","type","model","watcherHeartbeatSecondsAgo","Math","round","Date","now","console","log","JSON","stringify","embedded","pending","line","close"],"mappings":"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"}
@@ -1,18 +1,8 @@
1
1
  import type { ResolvedConfig } from '../config.js';
2
2
  export interface Ctx {
3
3
  name: string;
4
- rest: string[];
5
- format: 'table' | 'json';
6
- values: {
7
- config?: string;
8
- where?: string;
9
- k?: string;
10
- preset?: string;
11
- include?: string[];
12
- force: boolean;
13
- lexical: boolean;
14
- };
15
- resolveConfig(): ResolvedConfig;
4
+ argv: string[];
5
+ resolveConfig(configPath?: string): ResolvedConfig;
16
6
  usageError(message: string): never;
17
7
  }
18
8
  export type Command = (ctx: Ctx) => Promise<void> | void;
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/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; preset?: string; include?: string[]; force: boolean; lexical: 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/cli/types.ts"],"sourcesContent":["import type { ResolvedConfig } from '../config.ts';\n\n// Handed to every command; each command parses its own argv via shared.ts's `parse`.\nexport interface Ctx {\n name: string;\n argv: string[]; // argv after the command word\n resolveConfig(configPath?: string): ResolvedConfig;\n usageError(message: string): never;\n}\n\nexport type Command = (ctx: Ctx) => Promise<void> | void;\n"],"names":[],"mappings":"AAUA,WAAyD"}
@@ -1,8 +1,16 @@
1
1
  import { runWatch } from '../watch.js';
2
- import { printWarnings } from './shared.js';
2
+ import { USAGE } from './index.js';
3
+ import { CONFIG, parse, printWarnings } from './shared.js';
3
4
  const watch = async (ctx)=>{
4
- await runWatch(ctx.resolveConfig(), {
5
- force: ctx.values.force,
5
+ const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.watch}`, {
6
+ force: {
7
+ type: 'boolean',
8
+ default: false
9
+ },
10
+ ...CONFIG
11
+ });
12
+ await runWatch(ctx.resolveConfig(values.config), {
13
+ force: values.force,
6
14
  onEvent: (event)=>{
7
15
  if (event.type === 'started') {
8
16
  console.log(`${ctx.name} watch: watching ${event.baseDir}`);
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/watch.ts"],"sourcesContent":["import type { WatchEvent } from '../watch.ts';\nimport { runWatch } from '../watch.ts';\nimport { printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst watch: Command = async (ctx) => {\n await runWatch(ctx.resolveConfig(), {\n force: ctx.values.force,\n onEvent: (event: WatchEvent) => {\n if (event.type === 'started') {\n console.log(`${ctx.name} watch: watching ${event.baseDir}`);\n console.log(`${ctx.name} watch: db ${event.dbPath}`);\n } else if (event.type === 'reconciled') {\n printWarnings(event.warnings);\n if (event.parsed > 0) console.log(`${ctx.name} watch: reconciled, ${event.parsed} file(s) reparsed (${event.total} total)`);\n } else {\n console.error(`${ctx.name} watch: reconcile error: ${event.message}`);\n }\n },\n });\n};\nexport default watch;\n"],"names":["runWatch","printWarnings","watch","ctx","resolveConfig","force","values","onEvent","event","type","console","log","name","baseDir","dbPath","warnings","parsed","total","error","message"],"mappings":"AACA,SAASA,QAAQ,QAAQ,cAAc;AACvC,SAASC,aAAa,QAAQ,cAAc;AAG5C,MAAMC,QAAiB,OAAOC;IAC5B,MAAMH,SAASG,IAAIC,aAAa,IAAI;QAClCC,OAAOF,IAAIG,MAAM,CAACD,KAAK;QACvBE,SAAS,CAACC;YACR,IAAIA,MAAMC,IAAI,KAAK,WAAW;gBAC5BC,QAAQC,GAAG,CAAC,GAAGR,IAAIS,IAAI,CAAC,iBAAiB,EAAEJ,MAAMK,OAAO,EAAE;gBAC1DH,QAAQC,GAAG,CAAC,GAAGR,IAAIS,IAAI,CAAC,WAAW,EAAEJ,MAAMM,MAAM,EAAE;YACrD,OAAO,IAAIN,MAAMC,IAAI,KAAK,cAAc;gBACtCR,cAAcO,MAAMO,QAAQ;gBAC5B,IAAIP,MAAMQ,MAAM,GAAG,GAAGN,QAAQC,GAAG,CAAC,GAAGR,IAAIS,IAAI,CAAC,oBAAoB,EAAEJ,MAAMQ,MAAM,CAAC,mBAAmB,EAAER,MAAMS,KAAK,CAAC,OAAO,CAAC;YAC5H,OAAO;gBACLP,QAAQQ,KAAK,CAAC,GAAGf,IAAIS,IAAI,CAAC,yBAAyB,EAAEJ,MAAMW,OAAO,EAAE;YACtE;QACF;IACF;AACF;AACA,eAAejB,MAAM"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/watch.ts"],"sourcesContent":["import type { WatchEvent } from '../watch.ts';\nimport { runWatch } from '../watch.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst watch: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.watch}`, { force: { type: 'boolean', default: false }, ...CONFIG });\n await runWatch(ctx.resolveConfig(values.config as string | undefined), {\n force: values.force as boolean,\n onEvent: (event: WatchEvent) => {\n if (event.type === 'started') {\n console.log(`${ctx.name} watch: watching ${event.baseDir}`);\n console.log(`${ctx.name} watch: db ${event.dbPath}`);\n } else if (event.type === 'reconciled') {\n printWarnings(event.warnings);\n if (event.parsed > 0) console.log(`${ctx.name} watch: reconciled, ${event.parsed} file(s) reparsed (${event.total} total)`);\n } else {\n console.error(`${ctx.name} watch: reconcile error: ${event.message}`);\n }\n },\n });\n};\nexport default watch;\n"],"names":["runWatch","USAGE","CONFIG","parse","printWarnings","watch","ctx","values","argv","name","force","type","default","resolveConfig","config","onEvent","event","console","log","baseDir","dbPath","warnings","parsed","total","error","message"],"mappings":"AACA,SAASA,QAAQ,QAAQ,cAAc;AACvC,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,KAAK,EAAEC,aAAa,QAAQ,cAAc;AAG3D,MAAMC,QAAiB,OAAOC;IAC5B,MAAM,EAAEC,MAAM,EAAE,GAAGJ,MAAMG,IAAIE,IAAI,EAAE,CAAC,OAAO,EAAEF,IAAIG,IAAI,CAAC,CAAC,EAAER,MAAMI,KAAK,EAAE,EAAE;QAAEK,OAAO;YAAEC,MAAM;YAAWC,SAAS;QAAM;QAAG,GAAGV,MAAM;IAAC;IAChI,MAAMF,SAASM,IAAIO,aAAa,CAACN,OAAOO,MAAM,GAAyB;QACrEJ,OAAOH,OAAOG,KAAK;QACnBK,SAAS,CAACC;YACR,IAAIA,MAAML,IAAI,KAAK,WAAW;gBAC5BM,QAAQC,GAAG,CAAC,GAAGZ,IAAIG,IAAI,CAAC,iBAAiB,EAAEO,MAAMG,OAAO,EAAE;gBAC1DF,QAAQC,GAAG,CAAC,GAAGZ,IAAIG,IAAI,CAAC,WAAW,EAAEO,MAAMI,MAAM,EAAE;YACrD,OAAO,IAAIJ,MAAML,IAAI,KAAK,cAAc;gBACtCP,cAAcY,MAAMK,QAAQ;gBAC5B,IAAIL,MAAMM,MAAM,GAAG,GAAGL,QAAQC,GAAG,CAAC,GAAGZ,IAAIG,IAAI,CAAC,oBAAoB,EAAEO,MAAMM,MAAM,CAAC,mBAAmB,EAAEN,MAAMO,KAAK,CAAC,OAAO,CAAC;YAC5H,OAAO;gBACLN,QAAQO,KAAK,CAAC,GAAGlB,IAAIG,IAAI,CAAC,yBAAyB,EAAEO,MAAMS,OAAO,EAAE;YACtE;QACF;IACF;AACF;AACA,eAAepB,MAAM"}
package/dist/esm/cli.js CHANGED
@@ -1,9 +1,13 @@
1
1
  import { createRequire } from 'node:module';
2
- import { parseArgs } from 'node:util';
3
- import { COMMANDS } from './cli/index.js';
2
+ import exit from 'exit-compat';
3
+ import getopts from 'getopts-compat';
4
+ import { ExitError, usageError } from './cli/exit.js';
5
+ import { COMMANDS, USAGE } from './cli/index.js';
4
6
  import { loadConfig, SUPPORTED_CONFIG_VERSION } from './config.js';
5
7
  // Parsing and dispatch only. Commands live in src/cli/, one file each, lazy-loaded --
6
- // nothing tree- or dependency-heavy may be imported at the top of this file.
8
+ // nothing tree- or dependency-heavy may be imported at the top of this file. Flags parse
9
+ // per command (each command's own parse() call); this file only handles the bare top-level
10
+ // flags (--version/--help/--list/--config) and dispatch, and owns the single exit.
7
11
  // Works from dist/cjs and dist/esm alike: walk up past the dist type-marker package.json.
8
12
  function packageVersion() {
9
13
  const load = createRequire(import.meta.url);
@@ -20,120 +24,97 @@ function packageVersion() {
20
24
  return 'unknown';
21
25
  }
22
26
  function usage(name) {
23
- return `usage: ${name} <name> [params...] [--format table|json] [--config path]\n` + ` ${name} query "<sql>" [params...]\n` + ` ${name} search "<terms>" [--preset name] [--include glob ...] [--where "<sql>"] [--k n] [--lexical]\n` + ` ${name} map\n` + ` ${name} peek <path>\n` + ` ${name} --list\n` + ` ${name} init\n` + ` ${name} watch [--force]\n` + ` ${name} status\n` + ` ${name} check\n` + ` ${name} rebuild\n` + ` ${name} --version`;
27
+ const lines = Object.values(USAGE).map((u)=>` ${name} ${u}`);
28
+ return [
29
+ `usage: ${name} <name> [params...] [--format table|json] [--config path]`,
30
+ ...lines,
31
+ ` ${name} --list`,
32
+ ` ${name} --version`
33
+ ].join('\n');
24
34
  }
25
- // Thrown errors -> exit 1 with the message verbatim; usage errors exit 2 directly.
26
- export default async function cli(argv, name) {
27
- let values;
28
- let positionals;
29
- try {
30
- ({ values, positionals } = parseArgs({
31
- args: argv,
32
- options: {
33
- format: {
34
- type: 'string',
35
- default: 'table'
36
- },
37
- config: {
38
- type: 'string'
39
- },
40
- where: {
41
- type: 'string'
42
- },
43
- k: {
44
- type: 'string'
45
- },
46
- preset: {
47
- type: 'string'
48
- },
49
- include: {
50
- type: 'string',
51
- multiple: true
52
- },
53
- lexical: {
54
- type: 'boolean',
55
- default: false
56
- },
57
- list: {
58
- type: 'boolean',
59
- default: false
60
- },
61
- force: {
62
- type: 'boolean',
63
- default: false
64
- },
65
- version: {
66
- type: 'boolean',
67
- default: false,
68
- short: 'v'
69
- },
70
- help: {
71
- type: 'boolean',
72
- default: false,
73
- short: 'h'
74
- }
75
- },
76
- allowPositionals: true
77
- }));
78
- } catch (err) {
79
- console.error(err.message);
80
- console.error(usage(name));
81
- process.exit(2);
35
+ function resolveConfigFor(name, configPath) {
36
+ const cfg = loadConfig(configPath);
37
+ if (cfg.migratedFrom !== undefined) {
38
+ console.warn(`${name}: migrated ${cfg.configPath} from config version ${cfg.migratedFrom} to ${SUPPORTED_CONFIG_VERSION}`);
39
+ }
40
+ if (cfg.unknownKeys !== undefined) {
41
+ 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`);
82
42
  }
83
- if (values.version) {
84
- console.log(`v${packageVersion()}`);
43
+ return cfg;
44
+ }
45
+ // The top level knows four flags and nothing else; everything past the command word is the
46
+ // command's to parse. Reached only when there is no command word, or the first token is a flag.
47
+ function topLevel(argv, name) {
48
+ let unknown;
49
+ const opts = getopts(argv, {
50
+ string: [
51
+ 'config'
52
+ ],
53
+ boolean: [
54
+ 'version',
55
+ 'help',
56
+ 'list'
57
+ ],
58
+ alias: {
59
+ version: 'v',
60
+ help: 'h'
61
+ },
62
+ default: {
63
+ version: false,
64
+ help: false,
65
+ list: false
66
+ },
67
+ unknown: (flag)=>{
68
+ if (unknown === undefined) unknown = flag;
69
+ return false;
70
+ }
71
+ });
72
+ if (unknown !== undefined) usageError(`unknown option: ${unknown}`, usage(name));
73
+ if (opts.version) {
74
+ console.log(packageVersion());
85
75
  return;
86
76
  }
87
- if (values.help) {
77
+ if (opts.help) {
88
78
  console.log(usage(name));
89
79
  return;
90
80
  }
91
- const ctx = {
92
- name,
93
- rest: positionals.slice(1),
94
- format: values.format === 'json' ? 'json' : 'table',
95
- values: values,
96
- resolveConfig () {
97
- const cfg = loadConfig(values.config);
98
- if (cfg.migratedFrom !== undefined) {
99
- console.warn(`${name}: migrated ${cfg.configPath} from config version ${cfg.migratedFrom} to ${SUPPORTED_CONFIG_VERSION}`);
100
- }
101
- if (cfg.unknownKeys !== undefined) {
102
- 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`);
103
- }
104
- return cfg;
105
- },
106
- usageError (message) {
107
- console.error(message);
108
- process.exit(2);
81
+ if (opts.list) {
82
+ const queries = resolveConfigFor(name, opts.config === '' ? undefined : opts.config).queries;
83
+ for (const queryName of Object.keys(queries).sort()){
84
+ const entry = queries[queryName];
85
+ const isSavedSearch = typeof entry === 'object' && entry !== null && 'search' in entry;
86
+ console.log(isSavedSearch ? `${queryName} (search)` : queryName);
109
87
  }
110
- };
88
+ return;
89
+ }
90
+ console.error(usage(name));
91
+ throw new ExitError(2);
92
+ }
93
+ // ExitError carries a chosen code; anything else is an error -> exit 1 with its message.
94
+ export default async function cli(argv, name) {
111
95
  try {
112
- if (values.list) {
113
- const queries = ctx.resolveConfig().queries;
114
- for (const queryName of Object.keys(queries).sort()){
115
- const entry = queries[queryName];
116
- const isSavedSearch = typeof entry === 'object' && entry !== null && 'search' in entry;
117
- console.log(isSavedSearch ? `${queryName} (search)` : queryName);
118
- }
96
+ const first = argv[0];
97
+ if (!first || first.startsWith('-')) {
98
+ topLevel(argv, name);
119
99
  return;
120
100
  }
121
- const [first, ...params] = positionals;
122
- if (!first) {
123
- console.error(usage(name));
124
- process.exit(2);
125
- }
126
101
  // find -> search (breaking rename): one release of a pointer instead of "unknown query".
127
- if (first === 'find') {
128
- console.error(`${name}: find is now search`);
129
- console.error(usage(name));
130
- process.exit(2);
131
- }
102
+ if (first === 'find') usageError(`${name}: find is now search`, usage(name));
103
+ const ctx = {
104
+ name,
105
+ argv: argv.slice(1),
106
+ resolveConfig: (configPath)=>resolveConfigFor(name, configPath),
107
+ usageError: (message)=>usageError(message)
108
+ };
132
109
  const load = COMMANDS[first];
133
110
  if (load) await (await load()).default(ctx);
134
- else await (await import('./cli/named.js')).default(ctx, first, params);
111
+ else await (await import('./cli/named.js')).default(ctx, first);
135
112
  } catch (err) {
113
+ if (err instanceof ExitError) {
114
+ exit(err.code);
115
+ return;
116
+ }
136
117
  console.error(err.message);
137
- process.exit(1);
118
+ exit(1);
138
119
  }
139
120
  }
@@ -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 './cli/index.ts';\nimport type { Ctx } from './cli/types.ts';\nimport { loadConfig, SUPPORTED_CONFIG_VERSION } from './config.ts';\n\n// Parsing and dispatch only. Commands live in src/cli/, 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} search \"<terms>\" [--preset name] [--include glob ...] [--where \"<sql>\"] [--k n] [--lexical]\\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} check\\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 | string[] | 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 preset: { type: 'string' },\n include: { type: 'string', multiple: true },\n lexical: { 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 const queries = ctx.resolveConfig().queries;\n for (const queryName of Object.keys(queries).sort()) {\n const entry = queries[queryName];\n const isSavedSearch = typeof entry === 'object' && entry !== null && 'search' in entry;\n console.log(isSavedSearch ? `${queryName} (search)` : queryName);\n }\n return;\n }\n\n const [first, ...params] = positionals;\n if (!first) {\n console.error(usage(name));\n process.exit(2);\n }\n\n // find -> search (breaking rename): one release of a pointer instead of \"unknown query\".\n if (first === 'find') {\n console.error(`${name}: find is now search`);\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 (await import('./cli/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","preset","include","multiple","lexical","list","force","short","help","allowPositionals","err","console","error","message","process","exit","log","ctx","rest","slice","resolveConfig","cfg","migratedFrom","undefined","warn","configPath","unknownKeys","join","usageError","queries","queryName","Object","keys","sort","entry","isSavedSearch","first","params"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport exit from 'exit-compat';\nimport getopts from 'getopts-compat';\nimport { ExitError, usageError } from './cli/exit.ts';\nimport { COMMANDS, USAGE } from './cli/index.ts';\nimport type { Ctx } from './cli/types.ts';\nimport { loadConfig, SUPPORTED_CONFIG_VERSION } from './config.ts';\n\n// Parsing and dispatch only. Commands live in src/cli/, one file each, lazy-loaded --\n// nothing tree- or dependency-heavy may be imported at the top of this file. Flags parse\n// per command (each command's own parse() call); this file only handles the bare top-level\n// flags (--version/--help/--list/--config) and dispatch, and owns the single exit.\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 const lines = Object.values(USAGE).map((u) => ` ${name} ${u}`);\n return [`usage: ${name} <name> [params...] [--format table|json] [--config path]`, ...lines, ` ${name} --list`, ` ${name} --version`].join('\\n');\n}\n\nfunction resolveConfigFor(name: string, configPath: string | undefined) {\n const cfg = loadConfig(configPath);\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\n// The top level knows four flags and nothing else; everything past the command word is the\n// command's to parse. Reached only when there is no command word, or the first token is a flag.\nfunction topLevel(argv: string[], name: string): void {\n let unknown: string | undefined;\n const opts = getopts(argv, {\n string: ['config'],\n boolean: ['version', 'help', 'list'],\n alias: { version: 'v', help: 'h' },\n default: { version: false, help: false, list: false },\n unknown: (flag: string): boolean => {\n if (unknown === undefined) unknown = flag;\n return false;\n },\n });\n if (unknown !== undefined) usageError(`unknown option: ${unknown}`, usage(name));\n\n if (opts.version) {\n console.log(packageVersion());\n return;\n }\n if (opts.help) {\n console.log(usage(name));\n return;\n }\n if (opts.list) {\n const queries = resolveConfigFor(name, opts.config === '' ? undefined : (opts.config as string)).queries;\n for (const queryName of Object.keys(queries).sort()) {\n const entry = queries[queryName];\n const isSavedSearch = typeof entry === 'object' && entry !== null && 'search' in entry;\n console.log(isSavedSearch ? `${queryName} (search)` : queryName);\n }\n return;\n }\n console.error(usage(name));\n throw new ExitError(2);\n}\n\n// ExitError carries a chosen code; anything else is an error -> exit 1 with its message.\nexport default async function cli(argv: string[], name: string): Promise<void> {\n try {\n const first = argv[0];\n if (!first || first.startsWith('-')) {\n topLevel(argv, name);\n return;\n }\n\n // find -> search (breaking rename): one release of a pointer instead of \"unknown query\".\n if (first === 'find') usageError(`${name}: find is now search`, usage(name));\n\n const ctx: Ctx = {\n name,\n argv: argv.slice(1),\n resolveConfig: (configPath) => resolveConfigFor(name, configPath),\n usageError: (message) => usageError(message),\n };\n\n const load = COMMANDS[first];\n if (load) await (await load()).default(ctx);\n else await (await import('./cli/named.ts')).default(ctx, first);\n } catch (err) {\n if (err instanceof ExitError) {\n exit(err.code);\n return;\n }\n console.error((err as Error).message);\n exit(1);\n }\n}\n"],"names":["createRequire","exit","getopts","ExitError","usageError","COMMANDS","USAGE","loadConfig","SUPPORTED_CONFIG_VERSION","packageVersion","load","url","rel","pkg","name","version","usage","lines","Object","values","map","u","join","resolveConfigFor","configPath","cfg","migratedFrom","undefined","console","warn","unknownKeys","topLevel","argv","unknown","opts","string","boolean","alias","help","default","list","flag","log","queries","config","queryName","keys","sort","entry","isSavedSearch","error","cli","first","startsWith","ctx","slice","resolveConfig","message","err","code"],"mappings":"AAAA,SAASA,aAAa,QAAQ,cAAc;AAC5C,OAAOC,UAAU,cAAc;AAC/B,OAAOC,aAAa,iBAAiB;AACrC,SAASC,SAAS,EAAEC,UAAU,QAAQ,gBAAgB;AACtD,SAASC,QAAQ,EAAEC,KAAK,QAAQ,iBAAiB;AAEjD,SAASC,UAAU,EAAEC,wBAAwB,QAAQ,cAAc;AAEnE,sFAAsF;AACtF,yFAAyF;AACzF,2FAA2F;AAC3F,mFAAmF;AAEnF,0FAA0F;AAC1F,SAASC;IACP,MAAMC,OAAOV,cAAc,YAAYW,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,MAAMG,QAAQC,OAAOC,MAAM,CAACb,OAAOc,GAAG,CAAC,CAACC,IAAM,CAAC,OAAO,EAAEP,KAAK,CAAC,EAAEO,GAAG;IACnE,OAAO;QAAC,CAAC,OAAO,EAAEP,KAAK,yDAAyD,CAAC;WAAKG;QAAO,CAAC,OAAO,EAAEH,KAAK,OAAO,CAAC;QAAE,CAAC,OAAO,EAAEA,KAAK,UAAU,CAAC;KAAC,CAACQ,IAAI,CAAC;AACzJ;AAEA,SAASC,iBAAiBT,IAAY,EAAEU,UAA8B;IACpE,MAAMC,MAAMlB,WAAWiB;IACvB,IAAIC,IAAIC,YAAY,KAAKC,WAAW;QAClCC,QAAQC,IAAI,CAAC,GAAGf,KAAK,WAAW,EAAEW,IAAID,UAAU,CAAC,qBAAqB,EAAEC,IAAIC,YAAY,CAAC,IAAI,EAAElB,0BAA0B;IAC3H;IACA,IAAIiB,IAAIK,WAAW,KAAKH,WAAW;QACjCC,QAAQC,IAAI,CAAC,GAAGf,KAAK,EAAE,EAAEW,IAAID,UAAU,CAAC,MAAM,EAAEC,IAAIK,WAAW,CAACR,IAAI,CAAC,MAAM,kFAAkF,CAAC;IAChK;IACA,OAAOG;AACT;AAEA,2FAA2F;AAC3F,gGAAgG;AAChG,SAASM,SAASC,IAAc,EAAElB,IAAY;IAC5C,IAAImB;IACJ,MAAMC,OAAOhC,QAAQ8B,MAAM;QACzBG,QAAQ;YAAC;SAAS;QAClBC,SAAS;YAAC;YAAW;YAAQ;SAAO;QACpCC,OAAO;YAAEtB,SAAS;YAAKuB,MAAM;QAAI;QACjCC,SAAS;YAAExB,SAAS;YAAOuB,MAAM;YAAOE,MAAM;QAAM;QACpDP,SAAS,CAACQ;YACR,IAAIR,YAAYN,WAAWM,UAAUQ;YACrC,OAAO;QACT;IACF;IACA,IAAIR,YAAYN,WAAWvB,WAAW,CAAC,gBAAgB,EAAE6B,SAAS,EAAEjB,MAAMF;IAE1E,IAAIoB,KAAKnB,OAAO,EAAE;QAChBa,QAAQc,GAAG,CAACjC;QACZ;IACF;IACA,IAAIyB,KAAKI,IAAI,EAAE;QACbV,QAAQc,GAAG,CAAC1B,MAAMF;QAClB;IACF;IACA,IAAIoB,KAAKM,IAAI,EAAE;QACb,MAAMG,UAAUpB,iBAAiBT,MAAMoB,KAAKU,MAAM,KAAK,KAAKjB,YAAaO,KAAKU,MAAM,EAAaD,OAAO;QACxG,KAAK,MAAME,aAAa3B,OAAO4B,IAAI,CAACH,SAASI,IAAI,GAAI;YACnD,MAAMC,QAAQL,OAAO,CAACE,UAAU;YAChC,MAAMI,gBAAgB,OAAOD,UAAU,YAAYA,UAAU,QAAQ,YAAYA;YACjFpB,QAAQc,GAAG,CAACO,gBAAgB,GAAGJ,UAAU,UAAU,CAAC,GAAGA;QACzD;QACA;IACF;IACAjB,QAAQsB,KAAK,CAAClC,MAAMF;IACpB,MAAM,IAAIX,UAAU;AACtB;AAEA,yFAAyF;AACzF,eAAe,eAAegD,IAAInB,IAAc,EAAElB,IAAY;IAC5D,IAAI;QACF,MAAMsC,QAAQpB,IAAI,CAAC,EAAE;QACrB,IAAI,CAACoB,SAASA,MAAMC,UAAU,CAAC,MAAM;YACnCtB,SAASC,MAAMlB;YACf;QACF;QAEA,yFAAyF;QACzF,IAAIsC,UAAU,QAAQhD,WAAW,GAAGU,KAAK,oBAAoB,CAAC,EAAEE,MAAMF;QAEtE,MAAMwC,MAAW;YACfxC;YACAkB,MAAMA,KAAKuB,KAAK,CAAC;YACjBC,eAAe,CAAChC,aAAeD,iBAAiBT,MAAMU;YACtDpB,YAAY,CAACqD,UAAYrD,WAAWqD;QACtC;QAEA,MAAM/C,OAAOL,QAAQ,CAAC+C,MAAM;QAC5B,IAAI1C,MAAM,MAAM,AAAC,CAAA,MAAMA,MAAK,EAAG6B,OAAO,CAACe;aAClC,MAAM,AAAC,CAAA,MAAM,MAAM,CAAC,iBAAgB,EAAGf,OAAO,CAACe,KAAKF;IAC3D,EAAE,OAAOM,KAAK;QACZ,IAAIA,eAAevD,WAAW;YAC5BF,KAAKyD,IAAIC,IAAI;YACb;QACF;QACA/B,QAAQsB,KAAK,CAAC,AAACQ,IAAcD,OAAO;QACpCxD,KAAK;IACP;AACF"}
package/dist/esm/db.js CHANGED
@@ -1,3 +1,8 @@
1
+ // The package's Node floor (>=22.16) is set here and nowhere else: node:sqlite arrived in
2
+ // 22.5, but FTS5 -- which search.ts's whole lexical half is built on -- and
3
+ // StatementSync.columns() both landed in 22.16. 22.15 fails with "no such module: fts5".
4
+ // Nothing outside this file, features/, and commands.ts needs anything past Node 12, so
5
+ // raise the floor only for a sqlite capability, and lower it for nothing.
1
6
  import { mkdirSync, rmSync } from 'node:fs';
2
7
  import { join } from 'node:path';
3
8
  import { DatabaseSync } from 'node:sqlite';