sensemaking 0.9.3 → 0.9.4

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.
package/dist/cjs/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, // ExitError carries a chosen code; anything else is an error -> exit 1 with its message.
5
+ Object.defineProperty(exports, // Thrown errors -> exit 1 with the message verbatim; usage errors exit 2 directly.
6
6
  "default", {
7
7
  enumerable: true,
8
8
  get: function() {
@@ -10,9 +10,7 @@ Object.defineProperty(exports, // ExitError carries a chosen code; anything else
10
10
  }
11
11
  });
12
12
  var _nodemodule = require("node:module");
13
- var _exitcompat = /*#__PURE__*/ _interop_require_default(require("exit-compat"));
14
- var _getoptscompat = /*#__PURE__*/ _interop_require_default(require("getopts-compat"));
15
- var _exitts = require("./cli/exit.js");
13
+ var _nodeutil = require("node:util");
16
14
  var _indexts = require("./cli/index.js");
17
15
  var _configts = require("./config.js");
18
16
  function _array_like_to_array(arr, len) {
@@ -52,19 +50,6 @@ function _async_to_generator(fn) {
52
50
  });
53
51
  };
54
52
  }
55
- function _instanceof(left, right) {
56
- "@swc/helpers - instanceof";
57
- if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
58
- return !!right[Symbol.hasInstance](left);
59
- } else {
60
- return left instanceof right;
61
- }
62
- }
63
- function _interop_require_default(obj) {
64
- return obj && obj.__esModule ? obj : {
65
- default: obj
66
- };
67
- }
68
53
  function _getRequireWildcardCache(nodeInterop) {
69
54
  if (typeof WeakMap !== "function") return null;
70
55
  var cacheBabelInterop = new WeakMap();
@@ -229,7 +214,7 @@ function _ts_generator(thisArg, body) {
229
214
  // Parsing and dispatch only. Commands live in src/cli/, one file each, lazy-loaded --
230
215
  // nothing tree- or dependency-heavy may be imported at the top of this file. Flags parse
231
216
  // per command (each command's own parse() call); this file only handles the bare top-level
232
- // flags (--version/--help/--list/--config) and dispatch, and owns the single exit.
217
+ // flags (--version/--help/--list/--config) and dispatch.
233
218
  // Works from dist/cjs and dist/esm alike: walk up past the dist type-marker package.json.
234
219
  function packageVersion() {
235
220
  var load = (0, _nodemodule.createRequire)(require("url").pathToFileURL(__filename).toString());
@@ -267,92 +252,99 @@ function resolveConfigFor(name, configPath) {
267
252
  }
268
253
  return cfg;
269
254
  }
270
- // The top level knows four flags and nothing else; everything past the command word is the
271
- // command's to parse. Reached only when there is no command word, or the first token is a flag.
272
- function topLevel(argv, name) {
273
- var unknown;
274
- var opts = (0, _getoptscompat.default)(argv, {
275
- string: [
276
- 'config'
277
- ],
278
- boolean: [
279
- 'version',
280
- 'help',
281
- 'list'
282
- ],
283
- alias: {
284
- version: 'v',
285
- help: 'h'
286
- },
287
- default: {
288
- version: false,
289
- help: false,
290
- list: false
291
- },
292
- unknown: function unknown1(flag) {
293
- if (unknown === undefined) unknown = flag;
294
- return false;
295
- }
296
- });
297
- if (unknown !== undefined) (0, _exitts.usageError)("unknown option: ".concat(unknown), usage(name));
298
- if (opts.version) {
299
- console.log(packageVersion());
300
- return;
301
- }
302
- if (opts.help) {
303
- console.log(usage(name));
304
- return;
305
- }
306
- if (opts.list) {
307
- var queries = resolveConfigFor(name, opts.config === '' ? undefined : opts.config).queries;
308
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
309
- try {
310
- for(var _iterator = Object.keys(queries).sort()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
311
- var queryName = _step.value;
312
- var entry = queries[queryName];
313
- var isSavedSearch = (typeof entry === "undefined" ? "undefined" : _type_of(entry)) === 'object' && entry !== null && 'search' in entry;
314
- console.log(isSavedSearch ? "".concat(queryName, " (search)") : queryName);
315
- }
316
- } catch (err) {
317
- _didIteratorError = true;
318
- _iteratorError = err;
319
- } finally{
320
- try {
321
- if (!_iteratorNormalCompletion && _iterator.return != null) {
322
- _iterator.return();
323
- }
324
- } finally{
325
- if (_didIteratorError) {
326
- throw _iteratorError;
327
- }
328
- }
329
- }
330
- return;
331
- }
332
- console.error(usage(name));
333
- throw new _exitts.ExitError(2);
334
- }
335
255
  function cli(argv, name) {
336
256
  return _async_to_generator(function() {
337
- var first, ctx, load, err;
257
+ var first, values, queries, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, queryName, entry, isSavedSearch, ctx, load, err;
338
258
  return _ts_generator(this, function(_state) {
339
259
  switch(_state.label){
340
260
  case 0:
341
- _state.trys.push([
342
- 0,
343
- 7,
344
- ,
345
- 8
346
- ]);
347
261
  first = argv[0];
262
+ // No command word, or the first token looks like a flag: the only flags this level knows.
348
263
  if (!first || first.startsWith('-')) {
349
- topLevel(argv, name);
350
- return [
351
- 2
352
- ];
264
+ ;
265
+ try {
266
+ values = (0, _nodeutil.parseArgs)({
267
+ args: argv,
268
+ options: {
269
+ version: {
270
+ type: 'boolean',
271
+ default: false,
272
+ short: 'v'
273
+ },
274
+ help: {
275
+ type: 'boolean',
276
+ default: false,
277
+ short: 'h'
278
+ },
279
+ list: {
280
+ type: 'boolean',
281
+ default: false
282
+ },
283
+ config: {
284
+ type: 'string'
285
+ }
286
+ },
287
+ allowPositionals: true
288
+ }).values;
289
+ } catch (err) {
290
+ console.error(err.message);
291
+ console.error(usage(name));
292
+ process.exit(2);
293
+ }
294
+ try {
295
+ if (values.version) {
296
+ console.log(packageVersion());
297
+ return [
298
+ 2
299
+ ];
300
+ }
301
+ if (values.help) {
302
+ console.log(usage(name));
303
+ return [
304
+ 2
305
+ ];
306
+ }
307
+ if (values.list) {
308
+ queries = resolveConfigFor(name, values.config).queries;
309
+ _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
310
+ try {
311
+ for(_iterator = Object.keys(queries).sort()[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
312
+ queryName = _step.value;
313
+ entry = queries[queryName];
314
+ isSavedSearch = (typeof entry === "undefined" ? "undefined" : _type_of(entry)) === 'object' && entry !== null && 'search' in entry;
315
+ console.log(isSavedSearch ? "".concat(queryName, " (search)") : queryName);
316
+ }
317
+ } catch (err) {
318
+ _didIteratorError = true;
319
+ _iteratorError = err;
320
+ } finally{
321
+ try {
322
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
323
+ _iterator.return();
324
+ }
325
+ } finally{
326
+ if (_didIteratorError) {
327
+ throw _iteratorError;
328
+ }
329
+ }
330
+ }
331
+ return [
332
+ 2
333
+ ];
334
+ }
335
+ } catch (err) {
336
+ console.error(err.message);
337
+ process.exit(1);
338
+ }
339
+ console.error(usage(name));
340
+ process.exit(2);
353
341
  }
354
342
  // find -> search (breaking rename): one release of a pointer instead of "unknown query".
355
- if (first === 'find') (0, _exitts.usageError)("".concat(name, ": find is now search"), usage(name));
343
+ if (first === 'find') {
344
+ console.error("".concat(name, ": find is now search"));
345
+ console.error(usage(name));
346
+ process.exit(2);
347
+ }
356
348
  ctx = {
357
349
  name: name,
358
350
  argv: argv.slice(1),
@@ -360,64 +352,67 @@ function cli(argv, name) {
360
352
  return resolveConfigFor(name, configPath);
361
353
  },
362
354
  usageError: function usageError(message) {
363
- return (0, _exitts.usageError)(message);
355
+ console.error(message);
356
+ process.exit(2);
364
357
  }
365
358
  };
359
+ _state.label = 1;
360
+ case 1:
361
+ _state.trys.push([
362
+ 1,
363
+ 8,
364
+ ,
365
+ 9
366
+ ]);
366
367
  load = _indexts.COMMANDS[first];
367
368
  if (!load) return [
368
369
  3,
369
- 3
370
+ 4
370
371
  ];
371
372
  return [
372
373
  4,
373
374
  load()
374
375
  ];
375
- case 1:
376
+ case 2:
376
377
  return [
377
378
  4,
378
379
  _state.sent().default(ctx)
379
380
  ];
380
- case 2:
381
+ case 3:
381
382
  _state.sent();
382
383
  return [
383
384
  3,
384
- 6
385
+ 7
385
386
  ];
386
- case 3:
387
+ case 4:
387
388
  return [
388
389
  4,
389
390
  Promise.resolve().then(function() {
390
391
  return /*#__PURE__*/ _interop_require_wildcard(require("./cli/named.js"));
391
392
  })
392
393
  ];
393
- case 4:
394
+ case 5:
394
395
  return [
395
396
  4,
396
397
  _state.sent().default(ctx, first)
397
398
  ];
398
- case 5:
399
- _state.sent();
400
- _state.label = 6;
401
399
  case 6:
400
+ _state.sent();
401
+ _state.label = 7;
402
+ case 7:
402
403
  return [
403
404
  3,
404
- 8
405
+ 9
405
406
  ];
406
- case 7:
407
+ case 8:
407
408
  err = _state.sent();
408
- if (_instanceof(err, _exitts.ExitError)) {
409
- (0, _exitcompat.default)(err.code);
410
- return [
411
- 2
412
- ];
413
- }
414
409
  console.error(err.message);
415
- (0, _exitcompat.default)(1);
410
+ process.exit(1);
416
411
  return [
417
412
  3,
418
- 8
413
+ 9
419
414
  ];
420
- case 8:
415
+ case 9:
421
416
  return [
422
417
  2
423
418
  ];
@@ -1 +1 @@
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":["cli","packageVersion","load","createRequire","rel","pkg","name","version","usage","lines","Object","values","USAGE","map","u","join","resolveConfigFor","configPath","cfg","loadConfig","migratedFrom","undefined","console","warn","SUPPORTED_CONFIG_VERSION","unknownKeys","topLevel","argv","unknown","opts","getopts","string","boolean","alias","help","default","list","flag","usageError","log","queries","config","keys","sort","queryName","entry","isSavedSearch","error","ExitError","first","ctx","err","startsWith","slice","resolveConfig","message","COMMANDS","exit","code"],"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 { parseArgs } from 'node:util';\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.\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// 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 const first = argv[0];\n\n // No command word, or the first token looks like a flag: the only flags this level knows.\n if (!first || first.startsWith('-')) {\n let values: Record<string, string | boolean | undefined>;\n try {\n ({ values } = parseArgs({\n args: argv,\n options: {\n version: { type: 'boolean', default: false, short: 'v' },\n help: { type: 'boolean', default: false, short: 'h' },\n list: { type: 'boolean', default: false },\n config: { type: 'string' },\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 try {\n if (values.version) {\n console.log(packageVersion());\n return;\n }\n if (values.help) {\n console.log(usage(name));\n return;\n }\n if (values.list) {\n const queries = resolveConfigFor(name, values.config as string | undefined).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 } catch (err) {\n console.error((err as Error).message);\n process.exit(1);\n }\n\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 ctx: Ctx = {\n name,\n argv: argv.slice(1),\n resolveConfig: (configPath) => resolveConfigFor(name, configPath),\n usageError(message) {\n console.error(message);\n process.exit(2);\n },\n };\n\n try {\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 console.error((err as Error).message);\n process.exit(1);\n }\n}\n"],"names":["cli","packageVersion","load","createRequire","rel","pkg","name","version","usage","lines","Object","values","USAGE","map","u","join","resolveConfigFor","configPath","cfg","loadConfig","migratedFrom","undefined","console","warn","SUPPORTED_CONFIG_VERSION","unknownKeys","argv","first","queries","queryName","entry","isSavedSearch","ctx","err","startsWith","parseArgs","args","options","type","default","short","help","list","config","allowPositionals","error","message","process","exit","log","keys","sort","slice","resolveConfig","usageError","COMMANDS"],"mappings":";;;;+BAuCA,mFAAmF;AACnF;;;eAA8BA;;;0BAxCA;wBACJ;uBACM;wBAEqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAErD,sFAAsF;AACtF,yFAAyF;AACzF,2FAA2F;AAC3F,yDAAyD;AAEzD,0FAA0F;AAC1F,SAASC;IACP,IAAMC,OAAOC,IAAAA,yBAAa,EAAC;IAC3B,gBAAkB,QAAA;QAAC;QAAmB;QAAsB;KAAwB,OAAlE,mBAAoE;YAA3EC,MAAO;QAChB,IAAI;YACF,IAAMC,MAAMH,KAAKE;YACjB,IAAIC,IAAIC,IAAI,KAAK,iBAAiBD,IAAIE,OAAO,EAAE,OAAOF,IAAIE,OAAO;QACnE,EAAE,eAAM,CAAC;IACX;IACA,OAAO;AACT;AAEA,SAASC,MAAMF,IAAY;IACzB,IAAMG,QAAQC,OAAOC,MAAM,CAACC,cAAK,EAAEC,GAAG,CAAC,SAACC;eAAM,AAAC,UAAiBA,OAARR,MAAK,KAAK,OAAFQ;;IAChE,OAAO;QAAE,UAAc,OAALR,MAAK;KAA0H,CAA1I,OAA4E,qBAAGG,QAA/E;QAAuF,UAAc,OAALH,MAAK;QAAW,UAAc,OAALA,MAAK;KAAY,EAACS,IAAI,CAAC;AACzJ;AAEA,SAASC,iBAAiBV,IAAY,EAAEW,UAA8B;IACpE,IAAMC,MAAMC,IAAAA,oBAAU,EAACF;IACvB,IAAIC,IAAIE,YAAY,KAAKC,WAAW;QAClCC,QAAQC,IAAI,CAAC,AAAC,GAAoBL,OAAlBZ,MAAK,eAAmDY,OAAtCA,IAAID,UAAU,EAAC,yBAA8CO,OAAvBN,IAAIE,YAAY,EAAC,QAA+B,OAAzBI,kCAAwB;IACzH;IACA,IAAIN,IAAIO,WAAW,KAAKJ,WAAW;QACjCC,QAAQC,IAAI,CAAC,AAAC,GAAWL,OAATZ,MAAK,MAA2BY,OAAvBA,IAAID,UAAU,EAAC,UAAmC,OAA3BC,IAAIO,WAAW,CAACV,IAAI,CAAC,OAAM;IAC7E;IACA,OAAOG;AACT;AAGe,SAAelB,IAAI0B,IAAc,EAAEpB,IAAY;;YACtDqB,OAIAhB,QA4BMiB,SACD,2BAAA,mBAAA,gBAAA,WAAA,OAAMC,WACHC,OACAC,eAqBRC,KAWE9B,MAGC+B;;;;oBAtEHN,QAAQD,IAAI,CAAC,EAAE;oBAErB,0FAA0F;oBAC1F,IAAI,CAACC,SAASA,MAAMO,UAAU,CAAC,MAAM;;wBAEnC,IAAI;4BACCvB,SAAWwB,IAAAA,mBAAS,EAAC;gCACtBC,MAAMV;gCACNW,SAAS;oCACP9B,SAAS;wCAAE+B,MAAM;wCAAWC,SAAS;wCAAOC,OAAO;oCAAI;oCACvDC,MAAM;wCAAEH,MAAM;wCAAWC,SAAS;wCAAOC,OAAO;oCAAI;oCACpDE,MAAM;wCAAEJ,MAAM;wCAAWC,SAAS;oCAAM;oCACxCI,QAAQ;wCAAEL,MAAM;oCAAS;gCAC3B;gCACAM,kBAAkB;4BACpB,GATGjC;wBAUL,EAAE,OAAOsB,KAAK;4BACZX,QAAQuB,KAAK,CAAC,AAACZ,IAAca,OAAO;4BACpCxB,QAAQuB,KAAK,CAACrC,MAAMF;4BACpByC,QAAQC,IAAI,CAAC;wBACf;wBAEA,IAAI;4BACF,IAAIrC,OAAOJ,OAAO,EAAE;gCAClBe,QAAQ2B,GAAG,CAAChD;gCACZ;;;4BACF;4BACA,IAAIU,OAAO8B,IAAI,EAAE;gCACfnB,QAAQ2B,GAAG,CAACzC,MAAMF;gCAClB;;;4BACF;4BACA,IAAIK,OAAO+B,IAAI,EAAE;gCACTd,UAAUZ,iBAAiBV,MAAMK,OAAOgC,MAAM,EAAwBf,OAAO;gCAC9E,kCAAA,2BAAA;;oCAAL,IAAK,YAAmBlB,OAAOwC,IAAI,CAACtB,SAASuB,IAAI,yBAA5C,6BAAA,QAAA,yBAAA,iCAAgD;wCAA1CtB,YAAN;wCACGC,QAAQF,OAAO,CAACC,UAAU;wCAC1BE,gBAAgB,CAAA,OAAOD,sCAAP,SAAOA,MAAI,MAAM,YAAYA,UAAU,QAAQ,YAAYA;wCACjFR,QAAQ2B,GAAG,CAAClB,gBAAgB,AAAC,GAAY,OAAVF,WAAU,gBAAcA;oCACzD;;oCAJK;oCAAA;;;6CAAA,6BAAA;4CAAA;;;4CAAA;kDAAA;;;;gCAKL;;;4BACF;wBACF,EAAE,OAAOI,KAAK;4BACZX,QAAQuB,KAAK,CAAC,AAACZ,IAAca,OAAO;4BACpCC,QAAQC,IAAI,CAAC;wBACf;wBAEA1B,QAAQuB,KAAK,CAACrC,MAAMF;wBACpByC,QAAQC,IAAI,CAAC;oBACf;oBAEA,yFAAyF;oBACzF,IAAIrB,UAAU,QAAQ;wBACpBL,QAAQuB,KAAK,CAAC,AAAC,GAAO,OAALvC,MAAK;wBACtBgB,QAAQuB,KAAK,CAACrC,MAAMF;wBACpByC,QAAQC,IAAI,CAAC;oBACf;oBAEMhB,MAAW;wBACf1B,MAAAA;wBACAoB,MAAMA,KAAK0B,KAAK,CAAC;wBACjBC,eAAe,SAAfA,cAAgBpC;mCAAeD,iBAAiBV,MAAMW;;wBACtDqC,YAAAA,SAAAA,WAAWR,OAAO;4BAChBxB,QAAQuB,KAAK,CAACC;4BACdC,QAAQC,IAAI,CAAC;wBACf;oBACF;;;;;;;;;oBAGQ9C,OAAOqD,iBAAQ,CAAC5B,MAAM;yBACxBzB,MAAAA;;;;oBAAa;;wBAAMA;;;oBAAb;;wBAAO,cAAcqC,OAAO,CAACP;;;oBAA7B;;;;;;oBACE;;wBAAM;2EAAA,QAAO;;;;oBAApB;;wBAAO,cAAgCO,OAAO,CAACP,KAAKL;;;oBAApD;;;;;;;;oBACEM;oBACPX,QAAQuB,KAAK,CAAC,AAACZ,IAAca,OAAO;oBACpCC,QAAQC,IAAI,CAAC;;;;;;;;;;;IAEjB"}
@@ -1,7 +1,6 @@
1
1
  import { search } from '../commands.js';
2
2
  import { open } from '../db.js';
3
3
  import { printRows } from '../output.js';
4
- import { ExitError } from './exit.js';
5
4
  import { USAGE } from './index.js';
6
5
  import { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.js';
7
6
  // A saved query that returns zero rows looks identical to a true empty result, so a broken
@@ -90,6 +89,6 @@ const check = async (ctx)=>{
90
89
  return;
91
90
  }
92
91
  printRows(rows, format);
93
- if (failed > 0) throw new ExitError(1);
92
+ if (failed > 0) process.exit(1);
94
93
  };
95
94
  export default check;
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/check.ts"],"sourcesContent":["import { search } from '../commands.ts';\nimport { open } from '../db.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } from '../output.ts';\nimport { ExitError } from './exit.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// A saved query that returns zero rows looks identical to a true empty result, so a broken\n// one can sit unnoticed -- one field report had `WHERE flag = 'true'` against a numeric\n// column reading as \"nothing tagged yet\" for hours. Preparing each query catches syntax and\n// unknown-column errors without executing it; queries that take no parameters are also run\n// for a row count. Parameterised queries are validated but not counted: inventing arguments\n// would report a count for a query nobody ran. Saved searches run lexically with k=1 -- that\n// validates the `where` fragment, the FTS5 terms, and the `preset` name (resolveSearch throws\n// on an unknown one, the same breakage class prepare() catches for SQL strings) -- but never\n// semantically (a semantic pass costs model time and, on api trees, network). Whether a\n// result being empty is good or bad is the reader's judgment -- there is no assertion path.\nconst check: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.check}`, { ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const cfg = ctx.resolveConfig(values.config as string | undefined);\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n\n const rows: Row[] = [];\n let failed = 0;\n for (const [name, entry] of Object.entries(cfg.queries ?? {})) {\n if (typeof entry === 'object' && entry !== null && 'search' in entry) {\n try {\n const count = (await search(db, cfg, entry.search, { k: 1, where: entry.where, preset: entry.preset, include: entry.include, semantic: false })).length;\n rows.push({ query: name, params: '—', rows: '—', status: count === 0 ? 'ok, but matches 0 notes (lexical probe)' : 'ok (probe run with k=1)' });\n } catch (err) {\n failed++;\n rows.push({ query: name, params: '—', rows: '—', status: `FAILED: ${(err as Error).message}` });\n }\n continue;\n }\n const sql = typeof entry === 'string' ? entry : entry.sql;\n const params = (sql.match(/\\?/g) ?? []).length;\n try {\n const statement = db.prepare(sql);\n if (params > 0) {\n rows.push({ query: name, params, rows: '—', status: 'ok (not run: needs parameters)' });\n continue;\n }\n const count = (statement.all() as unknown[]).length;\n rows.push({ query: name, params, rows: count, status: count === 0 ? 'ok, but returns 0 rows' : 'ok' });\n } catch (err) {\n failed++;\n rows.push({ query: name, params, rows: '—', status: `FAILED: ${(err as Error).message}` });\n }\n }\n\n db.close();\n if (rows.length === 0) {\n console.log('no saved queries in config');\n return;\n }\n printRows(rows, format);\n if (failed > 0) throw new ExitError(1);\n};\nexport default check;\n"],"names":["search","open","printRows","ExitError","USAGE","CONFIG","FORMAT","formatOf","parse","printWarnings","check","ctx","cfg","values","argv","name","format","resolveConfig","config","db","warnings","rows","failed","entry","Object","entries","queries","sql","count","k","where","preset","include","semantic","length","push","query","params","status","err","message","match","statement","prepare","all","close","console","log"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/check.ts"],"sourcesContent":["import { search } from '../commands.ts';\nimport { open } from '../db.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } 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// A saved query that returns zero rows looks identical to a true empty result, so a broken\n// one can sit unnoticed -- one field report had `WHERE flag = 'true'` against a numeric\n// column reading as \"nothing tagged yet\" for hours. Preparing each query catches syntax and\n// unknown-column errors without executing it; queries that take no parameters are also run\n// for a row count. Parameterised queries are validated but not counted: inventing arguments\n// would report a count for a query nobody ran. Saved searches run lexically with k=1 -- that\n// validates the `where` fragment, the FTS5 terms, and the `preset` name (resolveSearch throws\n// on an unknown one, the same breakage class prepare() catches for SQL strings) -- but never\n// semantically (a semantic pass costs model time and, on api trees, network). Whether a\n// result being empty is good or bad is the reader's judgment -- there is no assertion path.\nconst check: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.check}`, { ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const cfg = ctx.resolveConfig(values.config as string | undefined);\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n\n const rows: Row[] = [];\n let failed = 0;\n for (const [name, entry] of Object.entries(cfg.queries ?? {})) {\n if (typeof entry === 'object' && entry !== null && 'search' in entry) {\n try {\n const count = (await search(db, cfg, entry.search, { k: 1, where: entry.where, preset: entry.preset, include: entry.include, semantic: false })).length;\n rows.push({ query: name, params: '—', rows: '—', status: count === 0 ? 'ok, but matches 0 notes (lexical probe)' : 'ok (probe run with k=1)' });\n } catch (err) {\n failed++;\n rows.push({ query: name, params: '—', rows: '—', status: `FAILED: ${(err as Error).message}` });\n }\n continue;\n }\n const sql = typeof entry === 'string' ? entry : entry.sql;\n const params = (sql.match(/\\?/g) ?? []).length;\n try {\n const statement = db.prepare(sql);\n if (params > 0) {\n rows.push({ query: name, params, rows: '—', status: 'ok (not run: needs parameters)' });\n continue;\n }\n const count = (statement.all() as unknown[]).length;\n rows.push({ query: name, params, rows: count, status: count === 0 ? 'ok, but returns 0 rows' : 'ok' });\n } catch (err) {\n failed++;\n rows.push({ query: name, params, rows: '—', status: `FAILED: ${(err as Error).message}` });\n }\n }\n\n db.close();\n if (rows.length === 0) {\n console.log('no saved queries in config');\n return;\n }\n printRows(rows, format);\n if (failed > 0) process.exit(1);\n};\nexport default check;\n"],"names":["search","open","printRows","USAGE","CONFIG","FORMAT","formatOf","parse","printWarnings","check","ctx","cfg","values","argv","name","format","resolveConfig","config","db","warnings","rows","failed","entry","Object","entries","queries","sql","count","k","where","preset","include","semantic","length","push","query","params","status","err","message","match","statement","prepare","all","close","console","log","process","exit"],"mappings":"AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,IAAI,QAAQ,WAAW;AAEhC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,aAAa,QAAQ,cAAc;AAG7E,2FAA2F;AAC3F,wFAAwF;AACxF,4FAA4F;AAC5F,2FAA2F;AAC3F,4FAA4F;AAC5F,6FAA6F;AAC7F,8FAA8F;AAC9F,6FAA6F;AAC7F,wFAAwF;AACxF,4FAA4F;AAC5F,MAAMC,QAAiB,OAAOC;QASeC;IAR3C,MAAM,EAAEC,MAAM,EAAE,GAAGL,MAAMG,IAAIG,IAAI,EAAE,CAAC,OAAO,EAAEH,IAAII,IAAI,CAAC,CAAC,EAAEX,MAAMM,KAAK,EAAE,EAAE;QAAE,GAAGJ,MAAM;QAAE,GAAGD,MAAM;IAAC;IAC/F,MAAMW,SAAST,SAASM;IACxB,MAAMD,MAAMD,IAAIM,aAAa,CAACJ,OAAOK,MAAM;IAC3C,MAAM,EAAEC,EAAE,EAAEC,QAAQ,EAAE,GAAGlB,KAAKU;IAC9BH,cAAcW;IAEd,MAAMC,OAAc,EAAE;IACtB,IAAIC,SAAS;IACb,KAAK,MAAM,CAACP,MAAMQ,MAAM,IAAIC,OAAOC,OAAO,EAACb,eAAAA,IAAIc,OAAO,cAAXd,0BAAAA,eAAe,CAAC,GAAI;YAY7Ce;QAXhB,IAAI,OAAOJ,UAAU,YAAYA,UAAU,QAAQ,YAAYA,OAAO;YACpE,IAAI;gBACF,MAAMK,QAAQ,AAAC,CAAA,MAAM3B,OAAOkB,IAAIP,KAAKW,MAAMtB,MAAM,EAAE;oBAAE4B,GAAG;oBAAGC,OAAOP,MAAMO,KAAK;oBAAEC,QAAQR,MAAMQ,MAAM;oBAAEC,SAAST,MAAMS,OAAO;oBAAEC,UAAU;gBAAM,EAAC,EAAGC,MAAM;gBACvJb,KAAKc,IAAI,CAAC;oBAAEC,OAAOrB;oBAAMsB,QAAQ;oBAAKhB,MAAM;oBAAKiB,QAAQV,UAAU,IAAI,4CAA4C;gBAA0B;YAC/I,EAAE,OAAOW,KAAK;gBACZjB;gBACAD,KAAKc,IAAI,CAAC;oBAAEC,OAAOrB;oBAAMsB,QAAQ;oBAAKhB,MAAM;oBAAKiB,QAAQ,CAAC,QAAQ,EAAE,AAACC,IAAcC,OAAO,EAAE;gBAAC;YAC/F;YACA;QACF;QACA,MAAMb,MAAM,OAAOJ,UAAU,WAAWA,QAAQA,MAAMI,GAAG;QACzD,MAAMU,SAAS,EAACV,aAAAA,IAAIc,KAAK,CAAC,oBAAVd,wBAAAA,aAAoB,EAAE,EAAEO,MAAM;QAC9C,IAAI;YACF,MAAMQ,YAAYvB,GAAGwB,OAAO,CAAChB;YAC7B,IAAIU,SAAS,GAAG;gBACdhB,KAAKc,IAAI,CAAC;oBAAEC,OAAOrB;oBAAMsB;oBAAQhB,MAAM;oBAAKiB,QAAQ;gBAAiC;gBACrF;YACF;YACA,MAAMV,QAAQ,AAACc,UAAUE,GAAG,GAAiBV,MAAM;YACnDb,KAAKc,IAAI,CAAC;gBAAEC,OAAOrB;gBAAMsB;gBAAQhB,MAAMO;gBAAOU,QAAQV,UAAU,IAAI,2BAA2B;YAAK;QACtG,EAAE,OAAOW,KAAK;YACZjB;YACAD,KAAKc,IAAI,CAAC;gBAAEC,OAAOrB;gBAAMsB;gBAAQhB,MAAM;gBAAKiB,QAAQ,CAAC,QAAQ,EAAE,AAACC,IAAcC,OAAO,EAAE;YAAC;QAC1F;IACF;IAEArB,GAAG0B,KAAK;IACR,IAAIxB,KAAKa,MAAM,KAAK,GAAG;QACrBY,QAAQC,GAAG,CAAC;QACZ;IACF;IACA5C,UAAUkB,MAAML;IAChB,IAAIM,SAAS,GAAG0B,QAAQC,IAAI,CAAC;AAC/B;AACA,eAAevC,MAAM"}
@@ -1,6 +1,5 @@
1
1
  import { search } from '../commands.js';
2
2
  import { printRows } from '../output.js';
3
- import { usageError } from './exit.js';
4
3
  import { CONFIG, FORMAT, formatOf, parse, parseK, runSql, SEARCH_FLAGS, withDb } from './shared.js';
5
4
  // Fallback when the first positional is not a command: a named query from config, either a
6
5
  // SQL string (run as-is) or a saved search (run through the `search` command's own machinery).
@@ -18,7 +17,11 @@ export default async function named(ctx, queryName) {
18
17
  const configPath = values.config;
19
18
  const cfg = ctx.resolveConfig(configPath);
20
19
  const entry = cfg.queries[queryName];
21
- if (entry === undefined) usageError(`unknown query: "${queryName}"`, `valid queries: ${Object.keys(cfg.queries).sort().join(', ')}`);
20
+ if (entry === undefined) {
21
+ console.error(`unknown query: "${queryName}"`);
22
+ console.error(`valid queries: ${Object.keys(cfg.queries).sort().join(', ')}`);
23
+ process.exit(2);
24
+ }
22
25
  if (typeof entry === 'string') {
23
26
  runSql(cfg, entry, params, format, `query "${queryName}"`);
24
27
  return;
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/named.ts"],"sourcesContent":["import { search } from '../commands.ts';\nimport { printRows } from '../output.ts';\nimport { usageError } from './exit.ts';\nimport { CONFIG, FORMAT, formatOf, parse, parseK, runSql, SEARCH_FLAGS, withDb } from './shared.ts';\nimport type { Ctx } from './types.ts';\n\n// Fallback when the first positional is not a command: a named query from config, either a\n// SQL string (run as-is) or a saved search (run through the `search` command's own machinery).\n// Flags cover both shapes -- SEARCH_FLAGS override a saved search's fields the same way they\n// override a preset's.\nexport default async function named(ctx: Ctx, queryName: string): Promise<void> {\n const usage = `usage: ${ctx.name} ${queryName} [params...] [--format table|json] [--config path] [--where \"<sql>\"] [--k n] [--preset name] [--include glob ...] [--lexical]`;\n const { values, positionals: params } = parse(ctx.argv, usage, { ...SEARCH_FLAGS, ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const configPath = values.config as string | undefined;\n\n const cfg = ctx.resolveConfig(configPath);\n const entry = cfg.queries[queryName];\n if (entry === undefined) usageError(`unknown query: \"${queryName}\"`, `valid queries: ${Object.keys(cfg.queries).sort().join(', ')}`);\n\n if (typeof entry === 'string') {\n runSql(cfg, entry, params, format, `query \"${queryName}\"`);\n return;\n }\n if ('sql' in entry) {\n runSql(cfg, entry.sql, params, format, `query \"${queryName}\"`);\n return;\n }\n\n // A saved search's text is fixed in config; there is nowhere for a positional to bind.\n if (params.length > 0) {\n ctx.usageError(`\"${queryName}\" is a saved search and takes no positional parameters; edit its \"search\" in sense.config.json, or use \"${ctx.name} search\" directly`);\n }\n const k = parseK(values.k as string | undefined, ctx.usageError) ?? entry.k;\n const where = (values.where as string | undefined) ?? entry.where;\n const preset = (values.preset as string | undefined) ?? entry.preset;\n const include = (values.include as string[] | undefined) ?? entry.include;\n // --lexical upgrades a saved search's semantic behavior the same way --where/--k\n // override; absent means the saved value (the flag has no default false override).\n const semantic = values.lexical ? false : entry.semantic;\n await withDb(ctx, configPath, async (db, resolvedCfg) => printRows(await search(db, resolvedCfg, entry.search, { k, where, preset, include, semantic }), format));\n}\n"],"names":["search","printRows","usageError","CONFIG","FORMAT","formatOf","parse","parseK","runSql","SEARCH_FLAGS","withDb","named","ctx","queryName","values","usage","name","positionals","params","argv","format","configPath","config","cfg","resolveConfig","entry","queries","undefined","Object","keys","sort","join","sql","length","k","where","preset","include","semantic","lexical","db","resolvedCfg"],"mappings":"AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,UAAU,QAAQ,YAAY;AACvC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,MAAM,EAAEC,MAAM,EAAEC,YAAY,EAAEC,MAAM,QAAQ,cAAc;AAGpG,2FAA2F;AAC3F,+FAA+F;AAC/F,6FAA6F;AAC7F,uBAAuB;AACvB,eAAe,eAAeC,MAAMC,GAAQ,EAAEC,SAAiB;QAuBnDN,SACKO,eACCA,gBACCA;IAzBjB,MAAMC,QAAQ,CAAC,OAAO,EAAEH,IAAII,IAAI,CAAC,CAAC,EAAEH,UAAU,6HAA6H,CAAC;IAC5K,MAAM,EAAEC,MAAM,EAAEG,aAAaC,MAAM,EAAE,GAAGZ,MAAMM,IAAIO,IAAI,EAAEJ,OAAO;QAAE,GAAGN,YAAY;QAAE,GAAGL,MAAM;QAAE,GAAGD,MAAM;IAAC;IACvG,MAAMiB,SAASf,SAASS;IACxB,MAAMO,aAAaP,OAAOQ,MAAM;IAEhC,MAAMC,MAAMX,IAAIY,aAAa,CAACH;IAC9B,MAAMI,QAAQF,IAAIG,OAAO,CAACb,UAAU;IACpC,IAAIY,UAAUE,WAAWzB,WAAW,CAAC,gBAAgB,EAAEW,UAAU,CAAC,CAAC,EAAE,CAAC,eAAe,EAAEe,OAAOC,IAAI,CAACN,IAAIG,OAAO,EAAEI,IAAI,GAAGC,IAAI,CAAC,OAAO;IAEnI,IAAI,OAAON,UAAU,UAAU;QAC7BjB,OAAOe,KAAKE,OAAOP,QAAQE,QAAQ,CAAC,OAAO,EAAEP,UAAU,CAAC,CAAC;QACzD;IACF;IACA,IAAI,SAASY,OAAO;QAClBjB,OAAOe,KAAKE,MAAMO,GAAG,EAAEd,QAAQE,QAAQ,CAAC,OAAO,EAAEP,UAAU,CAAC,CAAC;QAC7D;IACF;IAEA,uFAAuF;IACvF,IAAIK,OAAOe,MAAM,GAAG,GAAG;QACrBrB,IAAIV,UAAU,CAAC,CAAC,CAAC,EAAEW,UAAU,wGAAwG,EAAED,IAAII,IAAI,CAAC,iBAAiB,CAAC;IACpK;IACA,MAAMkB,KAAI3B,UAAAA,OAAOO,OAAOoB,CAAC,EAAwBtB,IAAIV,UAAU,eAArDK,qBAAAA,UAA0DkB,MAAMS,CAAC;IAC3E,MAAMC,SAASrB,gBAAAA,OAAOqB,KAAK,cAAZrB,2BAAAA,gBAAuCW,MAAMU,KAAK;IACjE,MAAMC,UAAUtB,iBAAAA,OAAOsB,MAAM,cAAbtB,4BAAAA,iBAAwCW,MAAMW,MAAM;IACpE,MAAMC,WAAWvB,kBAAAA,OAAOuB,OAAO,cAAdvB,6BAAAA,kBAA2CW,MAAMY,OAAO;IACzE,iFAAiF;IACjF,mFAAmF;IACnF,MAAMC,WAAWxB,OAAOyB,OAAO,GAAG,QAAQd,MAAMa,QAAQ;IACxD,MAAM5B,OAAOE,KAAKS,YAAY,OAAOmB,IAAIC,cAAgBxC,UAAU,MAAMD,OAAOwC,IAAIC,aAAahB,MAAMzB,MAAM,EAAE;YAAEkC;YAAGC;YAAOC;YAAQC;YAASC;QAAS,IAAIlB;AAC3J"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/named.ts"],"sourcesContent":["import { search } from '../commands.ts';\nimport { printRows } from '../output.ts';\nimport { CONFIG, FORMAT, formatOf, parse, parseK, runSql, SEARCH_FLAGS, withDb } from './shared.ts';\nimport type { Ctx } from './types.ts';\n\n// Fallback when the first positional is not a command: a named query from config, either a\n// SQL string (run as-is) or a saved search (run through the `search` command's own machinery).\n// Flags cover both shapes -- SEARCH_FLAGS override a saved search's fields the same way they\n// override a preset's.\nexport default async function named(ctx: Ctx, queryName: string): Promise<void> {\n const usage = `usage: ${ctx.name} ${queryName} [params...] [--format table|json] [--config path] [--where \"<sql>\"] [--k n] [--preset name] [--include glob ...] [--lexical]`;\n const { values, positionals: params } = parse(ctx.argv, usage, { ...SEARCH_FLAGS, ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const configPath = values.config as string | undefined;\n\n const cfg = ctx.resolveConfig(configPath);\n const entry = cfg.queries[queryName];\n if (entry === undefined) {\n console.error(`unknown query: \"${queryName}\"`);\n console.error(`valid queries: ${Object.keys(cfg.queries).sort().join(', ')}`);\n process.exit(2);\n }\n\n if (typeof entry === 'string') {\n runSql(cfg, entry, params, format, `query \"${queryName}\"`);\n return;\n }\n if ('sql' in entry) {\n runSql(cfg, entry.sql, params, format, `query \"${queryName}\"`);\n return;\n }\n\n // A saved search's text is fixed in config; there is nowhere for a positional to bind.\n if (params.length > 0) {\n ctx.usageError(`\"${queryName}\" is a saved search and takes no positional parameters; edit its \"search\" in sense.config.json, or use \"${ctx.name} search\" directly`);\n }\n const k = parseK(values.k as string | undefined, ctx.usageError) ?? entry.k;\n const where = (values.where as string | undefined) ?? entry.where;\n const preset = (values.preset as string | undefined) ?? entry.preset;\n const include = (values.include as string[] | undefined) ?? entry.include;\n // --lexical upgrades a saved search's semantic behavior the same way --where/--k\n // override; absent means the saved value (the flag has no default false override).\n const semantic = values.lexical ? false : entry.semantic;\n await withDb(ctx, configPath, async (db, resolvedCfg) => printRows(await search(db, resolvedCfg, entry.search, { k, where, preset, include, semantic }), format));\n}\n"],"names":["search","printRows","CONFIG","FORMAT","formatOf","parse","parseK","runSql","SEARCH_FLAGS","withDb","named","ctx","queryName","values","usage","name","positionals","params","argv","format","configPath","config","cfg","resolveConfig","entry","queries","undefined","console","error","Object","keys","sort","join","process","exit","sql","length","usageError","k","where","preset","include","semantic","lexical","db","resolvedCfg"],"mappings":"AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,MAAM,EAAEC,MAAM,EAAEC,YAAY,EAAEC,MAAM,QAAQ,cAAc;AAGpG,2FAA2F;AAC3F,+FAA+F;AAC/F,6FAA6F;AAC7F,uBAAuB;AACvB,eAAe,eAAeC,MAAMC,GAAQ,EAAEC,SAAiB;QA2BnDN,SACKO,eACCA,gBACCA;IA7BjB,MAAMC,QAAQ,CAAC,OAAO,EAAEH,IAAII,IAAI,CAAC,CAAC,EAAEH,UAAU,6HAA6H,CAAC;IAC5K,MAAM,EAAEC,MAAM,EAAEG,aAAaC,MAAM,EAAE,GAAGZ,MAAMM,IAAIO,IAAI,EAAEJ,OAAO;QAAE,GAAGN,YAAY;QAAE,GAAGL,MAAM;QAAE,GAAGD,MAAM;IAAC;IACvG,MAAMiB,SAASf,SAASS;IACxB,MAAMO,aAAaP,OAAOQ,MAAM;IAEhC,MAAMC,MAAMX,IAAIY,aAAa,CAACH;IAC9B,MAAMI,QAAQF,IAAIG,OAAO,CAACb,UAAU;IACpC,IAAIY,UAAUE,WAAW;QACvBC,QAAQC,KAAK,CAAC,CAAC,gBAAgB,EAAEhB,UAAU,CAAC,CAAC;QAC7Ce,QAAQC,KAAK,CAAC,CAAC,eAAe,EAAEC,OAAOC,IAAI,CAACR,IAAIG,OAAO,EAAEM,IAAI,GAAGC,IAAI,CAAC,OAAO;QAC5EC,QAAQC,IAAI,CAAC;IACf;IAEA,IAAI,OAAOV,UAAU,UAAU;QAC7BjB,OAAOe,KAAKE,OAAOP,QAAQE,QAAQ,CAAC,OAAO,EAAEP,UAAU,CAAC,CAAC;QACzD;IACF;IACA,IAAI,SAASY,OAAO;QAClBjB,OAAOe,KAAKE,MAAMW,GAAG,EAAElB,QAAQE,QAAQ,CAAC,OAAO,EAAEP,UAAU,CAAC,CAAC;QAC7D;IACF;IAEA,uFAAuF;IACvF,IAAIK,OAAOmB,MAAM,GAAG,GAAG;QACrBzB,IAAI0B,UAAU,CAAC,CAAC,CAAC,EAAEzB,UAAU,wGAAwG,EAAED,IAAII,IAAI,CAAC,iBAAiB,CAAC;IACpK;IACA,MAAMuB,KAAIhC,UAAAA,OAAOO,OAAOyB,CAAC,EAAwB3B,IAAI0B,UAAU,eAArD/B,qBAAAA,UAA0DkB,MAAMc,CAAC;IAC3E,MAAMC,SAAS1B,gBAAAA,OAAO0B,KAAK,cAAZ1B,2BAAAA,gBAAuCW,MAAMe,KAAK;IACjE,MAAMC,UAAU3B,iBAAAA,OAAO2B,MAAM,cAAb3B,4BAAAA,iBAAwCW,MAAMgB,MAAM;IACpE,MAAMC,WAAW5B,kBAAAA,OAAO4B,OAAO,cAAd5B,6BAAAA,kBAA2CW,MAAMiB,OAAO;IACzE,iFAAiF;IACjF,mFAAmF;IACnF,MAAMC,WAAW7B,OAAO8B,OAAO,GAAG,QAAQnB,MAAMkB,QAAQ;IACxD,MAAMjC,OAAOE,KAAKS,YAAY,OAAOwB,IAAIC,cAAgB5C,UAAU,MAAMD,OAAO4C,IAAIC,aAAarB,MAAMxB,MAAM,EAAE;YAAEsC;YAAGC;YAAOC;YAAQC;YAASC;QAAS,IAAIvB;AAC3J"}
@@ -1,23 +1,18 @@
1
+ import type { ParseArgsOptionsConfig } from 'node:util';
1
2
  import type { ResolvedConfig } from '../config.js';
2
3
  import type { OpenResult } from '../db.js';
3
4
  import type { Ctx } from './types.js';
4
- export interface Flag {
5
- type: 'string' | 'boolean';
6
- default?: string | boolean;
7
- multiple?: boolean;
8
- short?: string;
9
- }
10
- export type Flags = Record<string, Flag>;
11
- export declare const FORMAT: Flags;
12
- export declare const CONFIG: Flags;
13
- export declare const SEARCH_FLAGS: Flags;
14
- export type Values = Record<string, string | boolean | string[] | undefined>;
5
+ export declare const FORMAT: ParseArgsOptionsConfig;
6
+ export declare const CONFIG: ParseArgsOptionsConfig;
7
+ export declare const SEARCH_FLAGS: ParseArgsOptionsConfig;
8
+ type Values = Record<string, string | boolean | string[] | undefined>;
15
9
  export declare function formatOf(values: Values): 'table' | 'json';
16
- export declare function parse(argv: string[], usage: string, flags?: Flags): {
10
+ export declare function parse(argv: string[], usage: string, options: ParseArgsOptionsConfig): {
17
11
  values: Values;
18
12
  positionals: string[];
19
13
  };
20
- export declare function parseK(k: string | undefined, usageErrorFn: (message: string) => never): number | undefined;
14
+ export declare function parseK(k: string | undefined, usageError: (message: string) => never): number | undefined;
21
15
  export declare function printWarnings(warnings: string[]): void;
22
16
  export declare function withDb(ctx: Ctx, configPath: string | undefined, fn: (db: OpenResult['db'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void>;
23
17
  export declare function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: 'table' | 'json', label: string): void;
18
+ export {};
@@ -1,8 +1,8 @@
1
- import getopts from 'getopts-compat';
1
+ import { parseArgs } from 'node:util';
2
2
  import { open } from '../db.js';
3
3
  import { printRows } from '../output.js';
4
4
  import { searchError } from '../search-error.js';
5
- import { ExitError, usageError } from './exit.js';
5
+ // Spreadable option fragments -- one flag name keeps one meaning across every command's table.
6
6
  export const FORMAT = {
7
7
  format: {
8
8
  type: 'string',
@@ -36,70 +36,45 @@ export const SEARCH_FLAGS = {
36
36
  export function formatOf(values) {
37
37
  return values.format === 'json' ? 'json' : 'table';
38
38
  }
39
- // Per-command parse: strict (a foreign flag exits 2), and every table gets --help for free.
40
- export function parse(argv, usage, flags = {}) {
41
- const table = {
42
- ...flags,
43
- help: {
44
- type: 'boolean',
45
- default: false,
46
- short: 'h'
47
- }
48
- };
49
- const string = [];
50
- const boolean = [];
51
- const alias = {};
52
- const defaults = {};
53
- for (const [name, flag] of Object.entries(table)){
54
- (flag.type === 'boolean' ? boolean : string).push(name);
55
- if (flag.default !== undefined) defaults[name] = flag.default;
56
- if (flag.short !== undefined) alias[name] = flag.short;
39
+ // Per-command parseArgs: strict (a foreign flag exits 2), and every table gets --help for free.
40
+ export function parse(argv, usage, options) {
41
+ let values;
42
+ let positionals;
43
+ try {
44
+ ({ values, positionals } = parseArgs({
45
+ args: argv,
46
+ options: {
47
+ ...options,
48
+ help: {
49
+ type: 'boolean',
50
+ default: false,
51
+ short: 'h'
52
+ }
53
+ },
54
+ strict: true,
55
+ allowPositionals: true
56
+ }));
57
+ } catch (err) {
58
+ console.error(err.message);
59
+ console.error(usage);
60
+ process.exit(2);
57
61
  }
58
- // getopts is lenient about undeclared flags -- they land in the result and are silently
59
- // ignored, which is the bug 0.9.2 fixed. Record the first and fail below; returning false
60
- // also keeps it out of the result. `--k -1` arrives here as unknown option "1", because
61
- // getopts reads a leading dash as a new option rather than as --k's value; the message is
62
- // blunter than the old one but it is still a usage error rather than a silent default.
63
- let unknown;
64
- const parsed = getopts(argv, {
65
- string,
66
- boolean,
67
- alias,
68
- default: defaults,
69
- unknown: (name)=>{
70
- if (unknown === undefined) unknown = name;
71
- return false;
72
- }
73
- });
74
- if (unknown !== undefined) usageError(`unknown option: ${unknown}`, usage);
75
- if (parsed.help) {
62
+ if (values.help) {
76
63
  console.log(usage);
77
- throw new ExitError(0);
78
- }
79
- // Two getopts shapes the callers must not see: an unset string flag reads as "" rather
80
- // than undefined, and a flag passed once reads as a string rather than a one-element
81
- // array. Both matter -- `?? saved.field` means "flag absent", and --include is a list.
82
- const values = {};
83
- for (const [name, flag] of Object.entries(table)){
84
- const raw = parsed[name];
85
- if (flag.type === 'boolean') values[name] = raw;
86
- else if (flag.multiple) values[name] = raw === '' ? undefined : Array.isArray(raw) ? raw : [
87
- raw
88
- ];
89
- else values[name] = raw === '' ? undefined : raw;
64
+ process.exit(0);
90
65
  }
91
66
  return {
92
67
  values,
93
- positionals: parsed._
68
+ positionals
94
69
  };
95
70
  }
96
71
  // --k must be a positive integer: SQLite reads a bound LIMIT of -1 as "unlimited" and 0 as
97
72
  // "nothing", and parseInt would silently truncate "5.9" -- all three are caller mistakes
98
73
  // worth a usage error, matching the config-level SavedSearch validation.
99
- export function parseK(k, usageErrorFn) {
74
+ export function parseK(k, usageError) {
100
75
  if (k === undefined) return undefined;
101
76
  const parsed = Number(k);
102
- if (!Number.isInteger(parsed) || parsed <= 0) usageErrorFn(`--k expects a positive integer, got "${k}"`);
77
+ if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--k expects a positive integer, got "${k}"`);
103
78
  return parsed;
104
79
  }
105
80
  // Shared open-query-close envelope for commands that touch the tree.
@@ -120,7 +95,10 @@ export async function withDb(ctx, configPath, fn) {
120
95
  export function runSql(cfg, sql, params, format, label) {
121
96
  var _sql_match;
122
97
  const placeholderCount = ((_sql_match = sql.match(/\?/g)) !== null && _sql_match !== void 0 ? _sql_match : []).length;
123
- if (params.length !== placeholderCount) usageError(`${label} expects ${placeholderCount} parameter(s), got ${params.length}`);
98
+ if (params.length !== placeholderCount) {
99
+ console.error(`${label} expects ${placeholderCount} parameter(s), got ${params.length}`);
100
+ process.exit(2);
101
+ }
124
102
  const { db, warnings } = open(cfg);
125
103
  printWarnings(warnings);
126
104
  let rows;