sensemaking 0.24.7 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -11
- package/dist/cjs/cli/build.d.cts +3 -0
- package/dist/cjs/cli/build.d.ts +3 -0
- package/dist/cjs/cli/build.js +195 -0
- package/dist/cjs/cli/build.js.map +1 -0
- package/dist/cjs/cli/index.d.cts +7 -6
- package/dist/cjs/cli/index.d.ts +7 -6
- package/dist/cjs/cli/index.js +12 -6
- package/dist/cjs/cli/index.js.map +1 -1
- package/dist/cjs/cli/init.js +2 -2
- package/dist/cjs/cli/init.js.map +1 -1
- package/dist/cjs/cli/map.js +7 -2
- package/dist/cjs/cli/map.js.map +1 -1
- package/dist/cjs/cli/named.js +63 -21
- package/dist/cjs/cli/named.js.map +1 -1
- package/dist/cjs/cli/path.js +7 -2
- package/dist/cjs/cli/path.js.map +1 -1
- package/dist/cjs/cli/peek.js +7 -2
- package/dist/cjs/cli/peek.js.map +1 -1
- package/dist/cjs/cli/related.js +55 -6
- package/dist/cjs/cli/related.js.map +1 -1
- package/dist/cjs/cli/search.js +54 -15
- package/dist/cjs/cli/search.js.map +1 -1
- package/dist/cjs/cli/shared.d.cts +9 -3
- package/dist/cjs/cli/shared.d.ts +9 -3
- package/dist/cjs/cli/shared.js +109 -74
- package/dist/cjs/cli/shared.js.map +1 -1
- package/dist/cjs/cli/sql.js +8 -3
- package/dist/cjs/cli/sql.js.map +1 -1
- package/dist/cjs/cli/status.js +142 -50
- package/dist/cjs/cli/status.js.map +1 -1
- package/dist/cjs/cli/types.d.cts +4 -2
- package/dist/cjs/cli/types.d.ts +4 -2
- package/dist/cjs/cli.js +10 -4
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/commands/map.js +10 -6
- package/dist/cjs/commands/map.js.map +1 -1
- package/dist/cjs/commands/peek.js +10 -6
- package/dist/cjs/commands/peek.js.map +1 -1
- package/dist/cjs/commands/related.d.cts +1 -0
- package/dist/cjs/commands/related.d.ts +1 -0
- package/dist/cjs/commands/related.js +56 -21
- package/dist/cjs/commands/related.js.map +1 -1
- package/dist/cjs/commands/scope.js +1 -1
- package/dist/cjs/commands/scope.js.map +1 -1
- package/dist/cjs/commands/search.js +102 -84
- package/dist/cjs/commands/search.js.map +1 -1
- package/dist/cjs/config/index.d.cts +1 -1
- package/dist/cjs/config/index.d.ts +1 -1
- package/dist/cjs/config/index.js.map +1 -1
- package/dist/cjs/config/load.d.cts +6 -1
- package/dist/cjs/config/load.d.ts +6 -1
- package/dist/cjs/config/load.js +38 -1
- package/dist/cjs/config/load.js.map +1 -1
- package/dist/cjs/config/types.d.cts +2 -1
- package/dist/cjs/config/types.d.ts +2 -1
- package/dist/cjs/config/types.js +1 -1
- package/dist/cjs/config/types.js.map +1 -1
- package/dist/cjs/config/validate.js +20 -0
- package/dist/cjs/config/validate.js.map +1 -1
- package/dist/cjs/embed/query.d.cts +2 -1
- package/dist/cjs/embed/query.d.ts +2 -1
- package/dist/cjs/embed/query.js +186 -109
- package/dist/cjs/embed/query.js.map +1 -1
- package/dist/cjs/errors.d.cts +1 -1
- package/dist/cjs/errors.d.ts +1 -1
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/features/embed.js.map +1 -1
- package/dist/cjs/graph/traverse.js +11 -6
- package/dist/cjs/graph/traverse.js.map +1 -1
- package/dist/cjs/index.d.cts +3 -3
- package/dist/cjs/index.d.ts +3 -3
- package/dist/cjs/index.js +3 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/atomic-write.js +20 -6
- package/dist/cjs/lib/atomic-write.js.map +1 -1
- package/dist/cjs/lib/serial-query.d.cts +1 -0
- package/dist/cjs/lib/serial-query.d.ts +1 -0
- package/dist/cjs/lib/serial-query.js +22 -0
- package/dist/cjs/lib/serial-query.js.map +1 -0
- package/dist/cjs/scan/index.d.cts +5 -0
- package/dist/cjs/scan/index.d.ts +5 -0
- package/dist/cjs/scan/index.js +12 -4
- package/dist/cjs/scan/index.js.map +1 -1
- package/dist/cjs/scan/pool.d.cts +5 -0
- package/dist/cjs/scan/pool.d.ts +5 -0
- package/dist/cjs/scan/pool.js +167 -55
- package/dist/cjs/scan/pool.js.map +1 -1
- package/dist/cjs/store/builder.d.cts +6 -1
- package/dist/cjs/store/builder.d.ts +6 -1
- package/dist/cjs/store/builder.js +135 -5
- package/dist/cjs/store/builder.js.map +1 -1
- package/dist/cjs/store/duckdb/lexical.d.cts +2 -0
- package/dist/cjs/store/duckdb/lexical.d.ts +2 -0
- package/dist/cjs/store/duckdb/lexical.js +139 -7
- package/dist/cjs/store/duckdb/lexical.js.map +1 -1
- package/dist/cjs/store/duckdb/open.d.cts +3 -3
- package/dist/cjs/store/duckdb/open.d.ts +3 -3
- package/dist/cjs/store/duckdb/open.js +53 -41
- package/dist/cjs/store/duckdb/open.js.map +1 -1
- package/dist/cjs/store/duckdb/reconcile.js +2 -2
- package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
- package/dist/cjs/store/index.d.cts +23 -4
- package/dist/cjs/store/index.d.ts +23 -4
- package/dist/cjs/store/index.js +224 -15
- package/dist/cjs/store/index.js.map +1 -1
- package/dist/cjs/store/open.d.cts +9 -1
- package/dist/cjs/store/open.d.ts +9 -1
- package/dist/cjs/store/open.js +479 -128
- package/dist/cjs/store/open.js.map +1 -1
- package/dist/cjs/store/reconcile.js +93 -63
- package/dist/cjs/store/reconcile.js.map +1 -1
- package/dist/cjs/store/sqlite/open.d.cts +3 -3
- package/dist/cjs/store/sqlite/open.d.ts +3 -3
- package/dist/cjs/store/sqlite/open.js +44 -36
- package/dist/cjs/store/sqlite/open.js.map +1 -1
- package/dist/cjs/store/turso/open.d.cts +3 -3
- package/dist/cjs/store/turso/open.d.ts +3 -3
- package/dist/cjs/store/turso/open.js +83 -66
- package/dist/cjs/store/turso/open.js.map +1 -1
- package/dist/cjs/store/turso/store.d.cts +3 -1
- package/dist/cjs/store/turso/store.d.ts +3 -1
- package/dist/cjs/store/turso/store.js +46 -31
- package/dist/cjs/store/turso/store.js.map +1 -1
- package/dist/cjs/store/types.d.cts +12 -3
- package/dist/cjs/store/types.d.ts +12 -3
- package/dist/cjs/store/types.js.map +1 -1
- package/dist/cjs/watch.js +155 -35
- package/dist/cjs/watch.js.map +1 -1
- package/dist/esm/cli/build.d.ts +3 -0
- package/dist/esm/cli/build.js +18 -0
- package/dist/esm/cli/build.js.map +1 -0
- package/dist/esm/cli/index.d.ts +7 -6
- package/dist/esm/cli/index.js +8 -6
- package/dist/esm/cli/index.js.map +1 -1
- package/dist/esm/cli/init.js +2 -2
- package/dist/esm/cli/init.js.map +1 -1
- package/dist/esm/cli/map.js +8 -2
- package/dist/esm/cli/map.js.map +1 -1
- package/dist/esm/cli/named.js +38 -14
- package/dist/esm/cli/named.js.map +1 -1
- package/dist/esm/cli/path.js +8 -2
- package/dist/esm/cli/path.js.map +1 -1
- package/dist/esm/cli/peek.js +8 -2
- package/dist/esm/cli/peek.js.map +1 -1
- package/dist/esm/cli/related.js +21 -3
- package/dist/esm/cli/related.js.map +1 -1
- package/dist/esm/cli/search.js +28 -7
- package/dist/esm/cli/search.js.map +1 -1
- package/dist/esm/cli/shared.d.ts +9 -3
- package/dist/esm/cli/shared.js +44 -24
- package/dist/esm/cli/shared.js.map +1 -1
- package/dist/esm/cli/sql.js +8 -2
- package/dist/esm/cli/sql.js.map +1 -1
- package/dist/esm/cli/status.js +166 -111
- package/dist/esm/cli/status.js.map +1 -1
- package/dist/esm/cli/types.d.ts +4 -2
- package/dist/esm/cli/types.js.map +1 -1
- package/dist/esm/cli.js +9 -4
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/commands/map.js +5 -1
- package/dist/esm/commands/map.js.map +1 -1
- package/dist/esm/commands/peek.js +5 -1
- package/dist/esm/commands/peek.js.map +1 -1
- package/dist/esm/commands/related.d.ts +1 -0
- package/dist/esm/commands/related.js +19 -10
- package/dist/esm/commands/related.js.map +1 -1
- package/dist/esm/commands/scope.js +1 -1
- package/dist/esm/commands/scope.js.map +1 -1
- package/dist/esm/commands/search.js +11 -10
- package/dist/esm/commands/search.js.map +1 -1
- package/dist/esm/config/index.d.ts +1 -1
- package/dist/esm/config/index.js.map +1 -1
- package/dist/esm/config/load.d.ts +6 -1
- package/dist/esm/config/load.js +32 -3
- package/dist/esm/config/load.js.map +1 -1
- package/dist/esm/config/types.d.ts +2 -1
- package/dist/esm/config/types.js +1 -1
- package/dist/esm/config/types.js.map +1 -1
- package/dist/esm/config/validate.js +20 -0
- package/dist/esm/config/validate.js.map +1 -1
- package/dist/esm/embed/query.d.ts +2 -1
- package/dist/esm/embed/query.js +40 -34
- package/dist/esm/embed/query.js.map +1 -1
- package/dist/esm/errors.d.ts +1 -1
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/features/embed.js.map +1 -1
- package/dist/esm/graph/traverse.js +5 -1
- package/dist/esm/graph/traverse.js.map +1 -1
- package/dist/esm/index.d.ts +3 -3
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/atomic-write.js +14 -6
- package/dist/esm/lib/atomic-write.js.map +1 -1
- package/dist/esm/lib/serial-query.d.ts +1 -0
- package/dist/esm/lib/serial-query.js +13 -0
- package/dist/esm/lib/serial-query.js.map +1 -0
- package/dist/esm/scan/index.d.ts +5 -0
- package/dist/esm/scan/index.js +7 -3
- package/dist/esm/scan/index.js.map +1 -1
- package/dist/esm/scan/pool.d.ts +5 -0
- package/dist/esm/scan/pool.js +41 -16
- package/dist/esm/scan/pool.js.map +1 -1
- package/dist/esm/store/builder.d.ts +6 -1
- package/dist/esm/store/builder.js +19 -0
- package/dist/esm/store/builder.js.map +1 -1
- package/dist/esm/store/duckdb/lexical.d.ts +2 -0
- package/dist/esm/store/duckdb/lexical.js +32 -4
- package/dist/esm/store/duckdb/lexical.js.map +1 -1
- package/dist/esm/store/duckdb/open.d.ts +3 -3
- package/dist/esm/store/duckdb/open.js +13 -6
- package/dist/esm/store/duckdb/open.js.map +1 -1
- package/dist/esm/store/duckdb/reconcile.js +2 -2
- package/dist/esm/store/duckdb/reconcile.js.map +1 -1
- package/dist/esm/store/index.d.ts +23 -4
- package/dist/esm/store/index.js +80 -15
- package/dist/esm/store/index.js.map +1 -1
- package/dist/esm/store/open.d.ts +9 -1
- package/dist/esm/store/open.js +175 -84
- package/dist/esm/store/open.js.map +1 -1
- package/dist/esm/store/reconcile.js +12 -0
- package/dist/esm/store/reconcile.js.map +1 -1
- package/dist/esm/store/sqlite/open.d.ts +3 -3
- package/dist/esm/store/sqlite/open.js +9 -6
- package/dist/esm/store/sqlite/open.js.map +1 -1
- package/dist/esm/store/turso/open.d.ts +3 -3
- package/dist/esm/store/turso/open.js +14 -10
- package/dist/esm/store/turso/open.js.map +1 -1
- package/dist/esm/store/turso/store.d.ts +3 -1
- package/dist/esm/store/turso/store.js +5 -1
- package/dist/esm/store/turso/store.js.map +1 -1
- package/dist/esm/store/types.d.ts +12 -3
- package/dist/esm/store/types.js.map +1 -1
- package/dist/esm/watch.js +57 -19
- package/dist/esm/watch.js.map +1 -1
- package/package.json +1 -1
- package/schema.json +7 -2
- package/skills/sense/SKILL.md +3 -3
- package/skills/sense-bases/SKILL.md +1 -2
- package/skills/sense-setup/SKILL.md +1 -1
- package/skills/sense-setup/references/embeddings.md +1 -1
- package/skills/sense-setup/references/store-benchmarks.md +6 -6
package/dist/cjs/cli/shared.js
CHANGED
|
@@ -15,6 +15,9 @@ _export(exports, {
|
|
|
15
15
|
get FORMAT () {
|
|
16
16
|
return FORMAT;
|
|
17
17
|
},
|
|
18
|
+
get NO_BUILD () {
|
|
19
|
+
return NO_BUILD;
|
|
20
|
+
},
|
|
18
21
|
get SCOPE () {
|
|
19
22
|
return SCOPE;
|
|
20
23
|
},
|
|
@@ -50,6 +53,9 @@ _export(exports, {
|
|
|
50
53
|
},
|
|
51
54
|
get withDb () {
|
|
52
55
|
return withDb;
|
|
56
|
+
},
|
|
57
|
+
get withResolvedDb () {
|
|
58
|
+
return withResolvedDb;
|
|
53
59
|
}
|
|
54
60
|
});
|
|
55
61
|
var _nodeutil = require("node:util");
|
|
@@ -270,6 +276,12 @@ var CONFIG = {
|
|
|
270
276
|
type: 'string'
|
|
271
277
|
}
|
|
272
278
|
};
|
|
279
|
+
var NO_BUILD = {
|
|
280
|
+
'no-build': {
|
|
281
|
+
type: 'boolean',
|
|
282
|
+
default: false
|
|
283
|
+
}
|
|
284
|
+
};
|
|
273
285
|
var SCOPE = {
|
|
274
286
|
where: {
|
|
275
287
|
type: 'string'
|
|
@@ -404,16 +416,20 @@ function printWarnings(warnings) {
|
|
|
404
416
|
}
|
|
405
417
|
}
|
|
406
418
|
}
|
|
407
|
-
function
|
|
419
|
+
function withResolvedDb(cfg, options, fn) {
|
|
408
420
|
return _async_to_generator(function() {
|
|
409
|
-
var
|
|
421
|
+
var requirements, build, _ref, store, warnings;
|
|
410
422
|
return _ts_generator(this, function(_state) {
|
|
411
423
|
switch(_state.label){
|
|
412
424
|
case 0:
|
|
413
|
-
|
|
425
|
+
requirements = typeof options.requirements === 'function' ? options.requirements(cfg) : options.requirements;
|
|
426
|
+
build = !options.noBuild && cfg.build !== false;
|
|
414
427
|
return [
|
|
415
428
|
4,
|
|
416
|
-
(0, _indexts1.
|
|
429
|
+
(0, _indexts1.openStoreFor)(cfg, {
|
|
430
|
+
build: build,
|
|
431
|
+
requirements: requirements
|
|
432
|
+
})
|
|
417
433
|
];
|
|
418
434
|
case 1:
|
|
419
435
|
_ref = _state.sent(), store = _ref.store, warnings = _ref.warnings;
|
|
@@ -428,7 +444,7 @@ function withDb(ctx, configPath, fn) {
|
|
|
428
444
|
]);
|
|
429
445
|
return [
|
|
430
446
|
4,
|
|
431
|
-
fn(store, cfg)
|
|
447
|
+
fn(store, cfg, build)
|
|
432
448
|
];
|
|
433
449
|
case 3:
|
|
434
450
|
_state.sent();
|
|
@@ -454,6 +470,21 @@ function withDb(ctx, configPath, fn) {
|
|
|
454
470
|
});
|
|
455
471
|
})();
|
|
456
472
|
}
|
|
473
|
+
function withDb(ctx, configPath, options, fn) {
|
|
474
|
+
return _async_to_generator(function() {
|
|
475
|
+
var cfg;
|
|
476
|
+
return _ts_generator(this, function(_state) {
|
|
477
|
+
cfg = ctx.resolveConfig(configPath, {
|
|
478
|
+
writeMigration: !options.noBuild,
|
|
479
|
+
query: true
|
|
480
|
+
});
|
|
481
|
+
return [
|
|
482
|
+
2,
|
|
483
|
+
withResolvedDb(cfg, options, fn)
|
|
484
|
+
];
|
|
485
|
+
});
|
|
486
|
+
})();
|
|
487
|
+
}
|
|
457
488
|
// `--preset` on SQL binds a temp `scope` table rather than transparently filtering: temp views shadowing the base tables can't cover `content`, since FTS5 MATCH treats the table name as a hidden column.
|
|
458
489
|
// A flag that silently scoped three tables of four would look scoped and not be.
|
|
459
490
|
function bindScope(store, cfg, preset) {
|
|
@@ -494,9 +525,9 @@ function bindScope(store, cfg, preset) {
|
|
|
494
525
|
});
|
|
495
526
|
})();
|
|
496
527
|
}
|
|
497
|
-
function runSql(cfg, sql, params, format, label, preset) {
|
|
528
|
+
function runSql(cfg, sql, params, format, label, noBuild, preset) {
|
|
498
529
|
return _async_to_generator(function() {
|
|
499
|
-
var _sql_match, placeholderCount
|
|
530
|
+
var _sql_match, placeholderCount;
|
|
500
531
|
return _ts_generator(this, function(_state) {
|
|
501
532
|
switch(_state.label){
|
|
502
533
|
case 0:
|
|
@@ -514,75 +545,79 @@ function runSql(cfg, sql, params, format, label, preset) {
|
|
|
514
545
|
}
|
|
515
546
|
return [
|
|
516
547
|
4,
|
|
517
|
-
(
|
|
548
|
+
withResolvedDb(cfg, {
|
|
549
|
+
noBuild: noBuild,
|
|
550
|
+
requirements: new Set([
|
|
551
|
+
'core'
|
|
552
|
+
])
|
|
553
|
+
}, function(store) {
|
|
554
|
+
return _async_to_generator(function() {
|
|
555
|
+
var _statement, statement, columns, err, hinted;
|
|
556
|
+
return _ts_generator(this, function(_state) {
|
|
557
|
+
switch(_state.label){
|
|
558
|
+
case 0:
|
|
559
|
+
if (!(preset !== undefined)) return [
|
|
560
|
+
3,
|
|
561
|
+
2
|
|
562
|
+
];
|
|
563
|
+
return [
|
|
564
|
+
4,
|
|
565
|
+
bindScope(store, cfg, preset)
|
|
566
|
+
];
|
|
567
|
+
case 1:
|
|
568
|
+
_state.sent();
|
|
569
|
+
_state.label = 2;
|
|
570
|
+
case 2:
|
|
571
|
+
_state.trys.push([
|
|
572
|
+
2,
|
|
573
|
+
5,
|
|
574
|
+
,
|
|
575
|
+
7
|
|
576
|
+
]);
|
|
577
|
+
return [
|
|
578
|
+
4,
|
|
579
|
+
store.raw.prepare(sql)
|
|
580
|
+
];
|
|
581
|
+
case 3:
|
|
582
|
+
statement = _state.sent();
|
|
583
|
+
columns = statement.columns().map(function(c) {
|
|
584
|
+
return c.name;
|
|
585
|
+
});
|
|
586
|
+
return [
|
|
587
|
+
4,
|
|
588
|
+
(0, _outputts.printRowStream)((_statement = statement).iterate.apply(_statement, _to_consumable_array(params)), format, columns)
|
|
589
|
+
];
|
|
590
|
+
case 4:
|
|
591
|
+
_state.sent();
|
|
592
|
+
return [
|
|
593
|
+
3,
|
|
594
|
+
7
|
|
595
|
+
];
|
|
596
|
+
case 5:
|
|
597
|
+
err = _state.sent();
|
|
598
|
+
return [
|
|
599
|
+
4,
|
|
600
|
+
store.docs.columns()
|
|
601
|
+
];
|
|
602
|
+
case 6:
|
|
603
|
+
hinted = _columnhintts.columnHint.apply(void 0, [
|
|
604
|
+
_state.sent(),
|
|
605
|
+
err
|
|
606
|
+
]);
|
|
607
|
+
// A saved query or ad-hoc SQL can carry `content MATCH ?` too, so the same FTS5 punctuation trap applies to its bound parameters.
|
|
608
|
+
// SQL without MATCH gets its error verbatim; search advice on a plain typo would mislead.
|
|
609
|
+
if (/\bMATCH\b/i.test(sql)) throw (0, _searcherrorts.searchError)(hinted, params.join(' '));
|
|
610
|
+
throw hinted;
|
|
611
|
+
case 7:
|
|
612
|
+
return [
|
|
613
|
+
2
|
|
614
|
+
];
|
|
615
|
+
}
|
|
616
|
+
});
|
|
617
|
+
})();
|
|
618
|
+
})
|
|
518
619
|
];
|
|
519
620
|
case 1:
|
|
520
|
-
_ref = _state.sent(), store = _ref.store, warnings = _ref.warnings;
|
|
521
|
-
printWarnings(warnings);
|
|
522
|
-
if (!(preset !== undefined)) return [
|
|
523
|
-
3,
|
|
524
|
-
3
|
|
525
|
-
];
|
|
526
|
-
return [
|
|
527
|
-
4,
|
|
528
|
-
bindScope(store, cfg, preset)
|
|
529
|
-
];
|
|
530
|
-
case 2:
|
|
531
|
-
_state.sent();
|
|
532
|
-
_state.label = 3;
|
|
533
|
-
case 3:
|
|
534
|
-
_state.trys.push([
|
|
535
|
-
3,
|
|
536
|
-
6,
|
|
537
|
-
,
|
|
538
|
-
9
|
|
539
|
-
]);
|
|
540
|
-
return [
|
|
541
|
-
4,
|
|
542
|
-
store.raw.prepare(sql)
|
|
543
|
-
];
|
|
544
|
-
case 4:
|
|
545
|
-
statement = _state.sent();
|
|
546
|
-
columns = statement.columns().map(function(c) {
|
|
547
|
-
return c.name;
|
|
548
|
-
});
|
|
549
|
-
return [
|
|
550
|
-
4,
|
|
551
|
-
(0, _outputts.printRowStream)((_statement = statement).iterate.apply(_statement, _to_consumable_array(params)), format, columns)
|
|
552
|
-
];
|
|
553
|
-
case 5:
|
|
554
|
-
_state.sent();
|
|
555
|
-
return [
|
|
556
|
-
3,
|
|
557
|
-
9
|
|
558
|
-
];
|
|
559
|
-
case 6:
|
|
560
|
-
err = _state.sent();
|
|
561
|
-
return [
|
|
562
|
-
4,
|
|
563
|
-
store.docs.columns()
|
|
564
|
-
];
|
|
565
|
-
case 7:
|
|
566
|
-
hinted = _columnhintts.columnHint.apply(void 0, [
|
|
567
|
-
_state.sent(),
|
|
568
|
-
err
|
|
569
|
-
]);
|
|
570
|
-
return [
|
|
571
|
-
4,
|
|
572
|
-
store.close()
|
|
573
|
-
];
|
|
574
|
-
case 8:
|
|
575
|
-
_state.sent();
|
|
576
|
-
// A saved query or ad-hoc SQL can carry `content MATCH ?` too, so the same FTS5 punctuation trap applies to its bound parameters.
|
|
577
|
-
// SQL without MATCH gets its error verbatim; search advice on a plain typo would mislead.
|
|
578
|
-
if (/\bMATCH\b/i.test(sql)) throw (0, _searcherrorts.searchError)(hinted, params.join(' '));
|
|
579
|
-
throw hinted;
|
|
580
|
-
case 9:
|
|
581
|
-
return [
|
|
582
|
-
4,
|
|
583
|
-
store.close()
|
|
584
|
-
];
|
|
585
|
-
case 10:
|
|
586
621
|
_state.sent();
|
|
587
622
|
return [
|
|
588
623
|
2
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/shared.ts"],"sourcesContent":["import type { ParseArgsOptionsConfig } from 'node:util';\nimport { parseArgs } from 'node:util';\nimport type { ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { resolvePreset } from '../config/index.ts';\nimport { columnHint } from '../output/column-hint.ts';\nimport type { Row, RowFormat } from '../output/output.ts';\nimport { printRowStream } from '../output/output.ts';\nimport { searchError } from '../output/search-error.ts';\nimport type { OpenResult } from '../store/index.ts';\nimport { openStore } from '../store/index.ts';\nimport type { Store } from '../store/types.ts';\nimport type { Ctx } from './types.ts';\n\n// Spreadable option fragments -- one flag name keeps one meaning across every command's table.\nexport const FORMAT: ParseArgsOptionsConfig = { format: { type: 'string', default: 'table' } };\nexport const CONFIG: ParseArgsOptionsConfig = { config: { type: 'string' } };\n// The scope vocabulary every scoped command shares: named preset, ad hoc include/exclude\n// globs, a where SQL condition. search adds k on top.\nexport const SCOPE: ParseArgsOptionsConfig = {\n where: { type: 'string' },\n preset: { type: 'string' },\n include: { type: 'string', multiple: true },\n exclude: { type: 'string', multiple: true },\n // Widening, which no other flag can express: --include and --exclude each override their\n // own side of the preset, so neither can drop an exclusion the preset declares.\n 'no-exclude': { type: 'boolean', default: false },\n};\nexport const SEARCH_FLAGS: ParseArgsOptionsConfig = { ...SCOPE, k: { type: 'string' }, 'snippet-char-limit': { type: 'string' }, 'snippet-count-limit': { type: 'string' } };\n\ntype Values = Record<string, string | boolean | string[] | undefined>;\n\n// The SCOPE fragment's parsed values as the overrides every scoped command passes down.\n// One place to read them: a new scope field is added to the fragment and here, not per-command.\nexport function scopeOf(values: Values): SearchOverrides {\n return {\n preset: values.preset as string | undefined,\n include: values.include as string[] | undefined,\n exclude: values.exclude as string[] | undefined,\n where: values.where as string | undefined,\n noExclude: values['no-exclude'] === true,\n };\n}\n\n// parseArgs is strict about flag names; this applies the same strictness to the value.\n// An unrecognised --format is a usage error, not a silent fallback to `table`.\nfunction pickFormat<T extends string>(values: Values, allowed: readonly T[]): T {\n const format = String(values.format);\n if ((allowed as readonly string[]).includes(format)) return format as T;\n console.error(`unknown --format \"${format}\"; expected ${allowed.join(', ')}`);\n process.exit(2);\n}\n\nexport function formatOf(values: Values): 'table' | 'json' {\n return pickFormat(values, ['table', 'json'] as const);\n}\n\n// csv is a row set rendered as rows; map, peek, status, and path render structures instead,\n// and take formatOf.\nexport function rowFormatOf(values: Values): RowFormat {\n return pickFormat(values, ['table', 'json', 'csv'] as const);\n}\n\n// Per-command parseArgs: strict (a foreign flag exits 2), and every table gets --help for free.\nexport function parse(argv: string[], usage: string, options: ParseArgsOptionsConfig): { values: Values; positionals: string[] } {\n let values: Values;\n let positionals: string[];\n try {\n ({ values, positionals } = parseArgs({\n args: argv,\n options: { ...options, help: { type: 'boolean', default: false, short: 'h' } },\n strict: true,\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage);\n process.exit(2);\n }\n if (values.help) {\n console.log(usage);\n process.exit(0);\n }\n return { values, positionals };\n}\n\n// --k must be a positive integer: SQLite reads a bound LIMIT of -1 as \"unlimited\" and 0 as \"nothing\", and parseInt would silently truncate \"5.9\".\n// All three are caller mistakes worth a usage error, matching the config-level SavedSearch validation.\nexport function parseK(k: string | undefined, usageError: (message: string) => never): number | undefined {\n if (k === undefined) return undefined;\n const parsed = Number(k);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--k expects a positive integer, got \"${k}\"`);\n return parsed;\n}\n\n// Same positive-integer rule as --k, beside it since both flags come from SEARCH_FLAGS.\nexport function parseSnippetCharLimit(value: string | undefined, usageError: (message: string) => never): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--snippet-char-limit expects a positive integer, got \"${value}\"`);\n return parsed;\n}\n\nexport function parseSnippetCountLimit(value: string | undefined, usageError: (message: string) => never): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--snippet-count-limit expects a positive integer, got \"${value}\"`);\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: (store: OpenResult['store'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void> {\n const cfg = ctx.resolveConfig(configPath);\n const { store, warnings } = await openStore(cfg);\n printWarnings(warnings);\n try {\n await fn(store, cfg);\n } finally {\n await store.close();\n }\n}\n\n// `--preset` on SQL binds a temp `scope` table rather than transparently filtering: temp views shadowing the base tables can't cover `content`, since FTS5 MATCH treats the table name as a hidden column.\n// A flag that silently scoped three tables of four would look scoped and not be.\nasync function bindScope(store: Store, cfg: ResolvedConfig, preset: string): Promise<void> {\n const { name } = resolvePreset(cfg, preset); // unknown names throw, listing what is declared\n await store.exec('DROP TABLE IF EXISTS temp.scope');\n await store.exec('CREATE TEMP TABLE scope (\"path\" TEXT PRIMARY KEY)');\n const insert = await store.prepare('INSERT INTO temp.scope (\"path\") SELECT \"path\" FROM preset_files WHERE preset = ?');\n await insert.run(name);\n}\n\n// An unbound `?` silently binds NULL, so mismatched param counts fail loudly instead.\nexport async function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: RowFormat, label: string, preset?: string): Promise<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 // Naming a preset and never joining it would return the whole index while reading as scoped,\n // which is the one hazard of binding rather than applying. Refuse instead.\n if (preset !== undefined && !/\\bscope\\b/i.test(sql)) {\n console.error(`--preset binds a temporary \"scope\" table of the preset's paths, and ${label} never joins it, so the preset would have no effect`);\n console.error(`add: JOIN scope ON scope.\"path\" = <table>.\"path\"`);\n process.exit(2);\n }\n const { store, warnings } = await openStore(cfg);\n printWarnings(warnings);\n if (preset !== undefined) await bindScope(store, cfg, preset);\n // Streamed, not collected: `sql`'s result size is the caller's business, not ours. columns() reads the statement's own metadata, so a 0-row csv gets a header too.\n // A mid-stream SQLite error (e.g. SQLITE_BUSY outlasting busy_timeout) may leave partial output; the nonzero exit code is the failure signal, not a completeness guarantee.\n try {\n const statement = await store.raw.prepare(sql);\n const columns = statement.columns().map((c) => c.name);\n await printRowStream(statement.iterate(...params) as AsyncIterable<Row>, format, columns);\n } catch (err) {\n const hinted = columnHint(await store.docs.columns(), err as Error); // columns read while the store is still open\n await store.close();\n // A saved query or ad-hoc SQL can carry `content MATCH ?` too, so the same FTS5 punctuation trap applies to its bound parameters.\n // SQL without MATCH gets its error verbatim; search advice on a plain typo would mislead.\n if (/\\bMATCH\\b/i.test(sql)) throw searchError(hinted, params.join(' '));\n throw hinted;\n }\n await store.close();\n}\n"],"names":["CONFIG","FORMAT","SCOPE","SEARCH_FLAGS","formatOf","parse","parseK","parseSnippetCharLimit","parseSnippetCountLimit","printWarnings","rowFormatOf","runSql","scopeOf","withDb","format","type","default","config","where","preset","include","multiple","exclude","k","values","noExclude","pickFormat","allowed","String","includes","console","error","join","process","exit","argv","usage","options","positionals","parseArgs","args","help","short","strict","allowPositionals","err","message","log","usageError","undefined","parsed","Number","isInteger","value","warnings","w","warn","ctx","configPath","fn","cfg","store","resolveConfig","openStore","close","bindScope","name","insert","resolvePreset","exec","prepare","run","sql","params","label","placeholderCount","statement","columns","hinted","match","length","test","raw","map","c","printRowStream","iterate","docs","columnHint","searchError"],"mappings":";;;;;;;;;;;QAeaA;eAAAA;;QADAC;eAAAA;;QAIAC;eAAAA;;QASAC;eAAAA;;QAyBGC;eAAAA;;QAWAC;eAAAA;;QAwBAC;eAAAA;;QAQAC;eAAAA;;QAOAC;eAAAA;;QASAC;eAAAA;;QArDAC;eAAAA;;QA+EMC;eAAAA;;QAxGNC;eAAAA;;QAkFMC;eAAAA;;;wBAlHI;uBAEI;4BACH;wBAEI;6BACH;wBAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKnB,IAAMZ,SAAiC;IAAEa,QAAQ;QAAEC,MAAM;QAAUC,SAAS;IAAQ;AAAE;AACtF,IAAMhB,SAAiC;IAAEiB,QAAQ;QAAEF,MAAM;IAAS;AAAE;AAGpE,IAAMb,QAAgC;IAC3CgB,OAAO;QAAEH,MAAM;IAAS;IACxBI,QAAQ;QAAEJ,MAAM;IAAS;IACzBK,SAAS;QAAEL,MAAM;QAAUM,UAAU;IAAK;IAC1CC,SAAS;QAAEP,MAAM;QAAUM,UAAU;IAAK;IAC1C,yFAAyF;IACzF,gFAAgF;IAChF,cAAc;QAAEN,MAAM;QAAWC,SAAS;IAAM;AAClD;AACO,IAAMb,eAAuC,wCAAKD;IAAOqB,GAAG;QAAER,MAAM;IAAS;IAAG,sBAAsB;QAAEA,MAAM;IAAS;IAAG,uBAAuB;QAAEA,MAAM;IAAS;;AAMlK,SAASH,QAAQY,MAAc;IACpC,OAAO;QACLL,QAAQK,OAAOL,MAAM;QACrBC,SAASI,OAAOJ,OAAO;QACvBE,SAASE,OAAOF,OAAO;QACvBJ,OAAOM,OAAON,KAAK;QACnBO,WAAWD,MAAM,CAAC,aAAa,KAAK;IACtC;AACF;AAEA,uFAAuF;AACvF,+EAA+E;AAC/E,SAASE,WAA6BF,MAAc,EAAEG,OAAqB;IACzE,IAAMb,SAASc,OAAOJ,OAAOV,MAAM;IACnC,IAAI,AAACa,QAA8BE,QAAQ,CAACf,SAAS,OAAOA;IAC5DgB,QAAQC,KAAK,CAAC,AAAC,qBAAyCJ,OAArBb,QAAO,gBAAiC,OAAnBa,QAAQK,IAAI,CAAC;IACrEC,QAAQC,IAAI,CAAC;AACf;AAEO,SAAS9B,SAASoB,MAAc;IACrC,OAAOE,WAAWF,QAAQ;QAAC;QAAS;KAAO;AAC7C;AAIO,SAASd,YAAYc,MAAc;IACxC,OAAOE,WAAWF,QAAQ;QAAC;QAAS;QAAQ;KAAM;AACpD;AAGO,SAASnB,MAAM8B,IAAc,EAAEC,KAAa,EAAEC,OAA+B;IAClF,IAAIb;IACJ,IAAIc;IACJ,IAAI;;cACyBC,IAAAA,mBAAS,EAAC;YACnCC,MAAML;YACNE,SAAS,wCAAKA;gBAASI,MAAM;oBAAE1B,MAAM;oBAAWC,SAAS;oBAAO0B,OAAO;gBAAI;;YAC3EC,QAAQ;YACRC,kBAAkB;QACpB,IALGpB,aAAAA,QAAQc,kBAAAA;IAMb,EAAE,OAAOO,KAAK;QACZf,QAAQC,KAAK,CAAC,AAACc,IAAcC,OAAO;QACpChB,QAAQC,KAAK,CAACK;QACdH,QAAQC,IAAI,CAAC;IACf;IACA,IAAIV,OAAOiB,IAAI,EAAE;QACfX,QAAQiB,GAAG,CAACX;QACZH,QAAQC,IAAI,CAAC;IACf;IACA,OAAO;QAAEV,QAAAA;QAAQc,aAAAA;IAAY;AAC/B;AAIO,SAAShC,OAAOiB,CAAqB,EAAEyB,UAAsC;IAClF,IAAIzB,MAAM0B,WAAW,OAAOA;IAC5B,IAAMC,SAASC,OAAO5B;IACtB,IAAI,CAAC4B,OAAOC,SAAS,CAACF,WAAWA,UAAU,GAAGF,WAAW,AAAC,wCAAyC,OAAFzB,GAAE;IACnG,OAAO2B;AACT;AAGO,SAAS3C,sBAAsB8C,KAAyB,EAAEL,UAAsC;IACrG,IAAIK,UAAUJ,WAAW,OAAOA;IAChC,IAAMC,SAASC,OAAOE;IACtB,IAAI,CAACF,OAAOC,SAAS,CAACF,WAAWA,UAAU,GAAGF,WAAW,AAAC,yDAA8D,OAANK,OAAM;IACxH,OAAOH;AACT;AAEO,SAAS1C,uBAAuB6C,KAAyB,EAAEL,UAAsC;IACtG,IAAIK,UAAUJ,WAAW,OAAOA;IAChC,IAAMC,SAASC,OAAOE;IACtB,IAAI,CAACF,OAAOC,SAAS,CAACF,WAAWA,UAAU,GAAGF,WAAW,AAAC,0DAA+D,OAANK,OAAM;IACzH,OAAOH;AACT;AAIO,SAASzC,cAAc6C,QAAkB;QACzC,kCAAA,2BAAA;;QAAL,QAAK,YAAWA,6BAAX,SAAA,6BAAA,QAAA,yBAAA;YAAA,IAAMC,IAAN;YAAqBzB,QAAQ0B,IAAI,CAACD;;;QAAlC;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;AACP;AAEO,SAAe1C,OAAO4C,GAAQ,EAAEC,UAA8B,EAAEC,EAA6E;;YAC5IC,KACsB,MAApBC,OAAOP;;;;oBADTM,MAAMH,IAAIK,aAAa,CAACJ;oBACF;;wBAAMK,IAAAA,mBAAS,EAACH;;;oBAAhB,OAAA,eAApBC,QAAoB,KAApBA,OAAOP,WAAa,KAAbA;oBACf7C,cAAc6C;;;;;;;;;oBAEZ;;wBAAMK,GAAGE,OAAOD;;;oBAAhB;;;;;;oBAEA;;wBAAMC,MAAMG,KAAK;;;oBAAjB;;;;;;;;;;IAEJ;;AAEA,2MAA2M;AAC3M,iFAAiF;AACjF,SAAeC,UAAUJ,KAAY,EAAED,GAAmB,EAAEzC,MAAc;;YAChE+C,MAGFC;;;;oBAHED,OAASE,IAAAA,sBAAa,EAACR,KAAKzC,QAA5B+C,MAAqC,gDAAgD;oBAC7F;;wBAAML,MAAMQ,IAAI,CAAC;;;oBAAjB;oBACA;;wBAAMR,MAAMQ,IAAI,CAAC;;;oBAAjB;oBACe;;wBAAMR,MAAMS,OAAO,CAAC;;;oBAA7BH,SAAS;oBACf;;wBAAMA,OAAOI,GAAG,CAACL;;;oBAAjB;;;;;;IACF;;AAGO,SAAevD,OAAOiD,GAAmB,EAAEY,GAAW,EAAEC,MAAgB,EAAE3D,MAAiB,EAAE4D,KAAa,EAAEvD,MAAe;;YACtGqD,YAApBG,kBAYsB,MAApBd,OAAOP,UAQQsB,YAFfA,WACAC,SAEChC,KACDiC;;;;oBAtBFH,mBAAmB,EAACH,aAAAA,IAAIO,KAAK,CAAC,oBAAVP,wBAAAA,iBAAwBQ,MAAM;oBACxD,IAAIP,OAAOO,MAAM,KAAKL,kBAAkB;wBACtC7C,QAAQC,KAAK,CAAC,AAAC,GAAmB4C,OAAjBD,OAAM,aAAiDD,OAAtCE,kBAAiB,uBAAmC,OAAdF,OAAOO,MAAM;wBACrF/C,QAAQC,IAAI,CAAC;oBACf;oBACA,6FAA6F;oBAC7F,2EAA2E;oBAC3E,IAAIf,WAAW8B,aAAa,CAAC,aAAagC,IAAI,CAACT,MAAM;wBACnD1C,QAAQC,KAAK,CAAC,AAAC,wEAA4E,OAAN2C,OAAM;wBAC3F5C,QAAQC,KAAK,CAAC;wBACdE,QAAQC,IAAI,CAAC;oBACf;oBAC4B;;wBAAM6B,IAAAA,mBAAS,EAACH;;;oBAAhB,OAAA,eAApBC,QAAoB,KAApBA,OAAOP,WAAa,KAAbA;oBACf7C,cAAc6C;yBACVnC,CAAAA,WAAW8B,SAAQ,GAAnB9B;;;;oBAAsB;;wBAAM8C,UAAUJ,OAAOD,KAAKzC;;;oBAA5B;;;;;;;;;oBAIN;;wBAAM0C,MAAMqB,GAAG,CAACZ,OAAO,CAACE;;;oBAApCI,YAAY;oBACZC,UAAUD,UAAUC,OAAO,GAAGM,GAAG,CAAC,SAACC;+BAAMA,EAAElB,IAAI;;oBACrD;;wBAAMmB,IAAAA,wBAAc,EAACT,CAAAA,aAAAA,WAAUU,OAAO,OAAjBV,YAAkB,qBAAGH,UAA+B3D,QAAQ+D;;;oBAAjF;;;;;;oBACOhC;oBACmB;;wBAAMgB,MAAM0B,IAAI,CAACV,OAAO;;;oBAA5CC,SAASU,wBAAU;wBAAC;wBAA4B3C;;oBACtD;;wBAAMgB,MAAMG,KAAK;;;oBAAjB;oBACA,kIAAkI;oBAClI,0FAA0F;oBAC1F,IAAI,aAAaiB,IAAI,CAACT,MAAM,MAAMiB,IAAAA,0BAAW,EAACX,QAAQL,OAAOzC,IAAI,CAAC;oBAClE,MAAM8C;;oBAER;;wBAAMjB,MAAMG,KAAK;;;oBAAjB;;;;;;IACF"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/shared.ts"],"sourcesContent":["import type { ParseArgsOptionsConfig } from 'node:util';\nimport { parseArgs } from 'node:util';\nimport type { ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { resolvePreset } from '../config/index.ts';\nimport { columnHint } from '../output/column-hint.ts';\nimport type { Row, RowFormat } from '../output/output.ts';\nimport { printRowStream } from '../output/output.ts';\nimport { searchError } from '../output/search-error.ts';\nimport { openStoreFor } from '../store/index.ts';\nimport type { BuildRequirement, OpenResult } from '../store/open.ts';\nimport type { Store } from '../store/types.ts';\nimport type { Ctx } from './types.ts';\n\n// Spreadable option fragments -- one flag name keeps one meaning across every command's table.\nexport const FORMAT: ParseArgsOptionsConfig = { format: { type: 'string', default: 'table' } };\nexport const CONFIG: ParseArgsOptionsConfig = { config: { type: 'string' } };\nexport const NO_BUILD: ParseArgsOptionsConfig = { 'no-build': { type: 'boolean', default: false } };\n// The scope vocabulary every scoped command shares: named preset, ad hoc include/exclude\n// globs, a where SQL condition. search adds k on top.\nexport const SCOPE: ParseArgsOptionsConfig = {\n where: { type: 'string' },\n preset: { type: 'string' },\n include: { type: 'string', multiple: true },\n exclude: { type: 'string', multiple: true },\n // Widening, which no other flag can express: --include and --exclude each override their\n // own side of the preset, so neither can drop an exclusion the preset declares.\n 'no-exclude': { type: 'boolean', default: false },\n};\nexport const SEARCH_FLAGS: ParseArgsOptionsConfig = { ...SCOPE, k: { type: 'string' }, 'snippet-char-limit': { type: 'string' }, 'snippet-count-limit': { type: 'string' } };\n\ntype Values = Record<string, string | boolean | string[] | undefined>;\n\n// The SCOPE fragment's parsed values as the overrides every scoped command passes down.\n// One place to read them: a new scope field is added to the fragment and here, not per-command.\nexport function scopeOf(values: Values): SearchOverrides {\n return {\n preset: values.preset as string | undefined,\n include: values.include as string[] | undefined,\n exclude: values.exclude as string[] | undefined,\n where: values.where as string | undefined,\n noExclude: values['no-exclude'] === true,\n };\n}\n\n// parseArgs is strict about flag names; this applies the same strictness to the value.\n// An unrecognised --format is a usage error, not a silent fallback to `table`.\nfunction pickFormat<T extends string>(values: Values, allowed: readonly T[]): T {\n const format = String(values.format);\n if ((allowed as readonly string[]).includes(format)) return format as T;\n console.error(`unknown --format \"${format}\"; expected ${allowed.join(', ')}`);\n process.exit(2);\n}\n\nexport function formatOf(values: Values): 'table' | 'json' {\n return pickFormat(values, ['table', 'json'] as const);\n}\n\n// csv is a row set rendered as rows; map, peek, status, and path render structures instead,\n// and take formatOf.\nexport function rowFormatOf(values: Values): RowFormat {\n return pickFormat(values, ['table', 'json', 'csv'] as const);\n}\n\n// Per-command parseArgs: strict (a foreign flag exits 2), and every table gets --help for free.\nexport function parse(argv: string[], usage: string, options: ParseArgsOptionsConfig): { values: Values; positionals: string[] } {\n let values: Values;\n let positionals: string[];\n try {\n ({ values, positionals } = parseArgs({\n args: argv,\n options: { ...options, help: { type: 'boolean', default: false, short: 'h' } },\n strict: true,\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage);\n process.exit(2);\n }\n if (values.help) {\n console.log(usage);\n process.exit(0);\n }\n return { values, positionals };\n}\n\n// --k must be a positive integer: SQLite reads a bound LIMIT of -1 as \"unlimited\" and 0 as \"nothing\", and parseInt would silently truncate \"5.9\".\n// All three are caller mistakes worth a usage error, matching the config-level SavedSearch validation.\nexport function parseK(k: string | undefined, usageError: (message: string) => never): number | undefined {\n if (k === undefined) return undefined;\n const parsed = Number(k);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--k expects a positive integer, got \"${k}\"`);\n return parsed;\n}\n\n// Same positive-integer rule as --k, beside it since both flags come from SEARCH_FLAGS.\nexport function parseSnippetCharLimit(value: string | undefined, usageError: (message: string) => never): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--snippet-char-limit expects a positive integer, got \"${value}\"`);\n return parsed;\n}\n\nexport function parseSnippetCountLimit(value: string | undefined, usageError: (message: string) => never): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--snippet-count-limit expects a positive integer, got \"${value}\"`);\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 interface DbOpenOptions {\n noBuild: boolean;\n requirements: ReadonlySet<BuildRequirement> | ((cfg: ResolvedConfig) => ReadonlySet<BuildRequirement>);\n}\n\nexport async function withResolvedDb(cfg: ResolvedConfig, options: DbOpenOptions, fn: (store: OpenResult['store'], cfg: ResolvedConfig, build: boolean) => void | Promise<void>): Promise<void> {\n const requirements = typeof options.requirements === 'function' ? options.requirements(cfg) : options.requirements;\n const build = !options.noBuild && cfg.build !== false;\n const { store, warnings } = await openStoreFor(cfg, {\n build,\n requirements,\n });\n printWarnings(warnings);\n try {\n await fn(store, cfg, build);\n } finally {\n await store.close();\n }\n}\n\nexport async function withDb(ctx: Ctx, configPath: string | undefined, options: DbOpenOptions, fn: (store: OpenResult['store'], cfg: ResolvedConfig, build: boolean) => void | Promise<void>): Promise<void> {\n const cfg = ctx.resolveConfig(configPath, { writeMigration: !options.noBuild, query: true });\n return withResolvedDb(cfg, options, fn);\n}\n\n// `--preset` on SQL binds a temp `scope` table rather than transparently filtering: temp views shadowing the base tables can't cover `content`, since FTS5 MATCH treats the table name as a hidden column.\n// A flag that silently scoped three tables of four would look scoped and not be.\nasync function bindScope(store: Store, cfg: ResolvedConfig, preset: string): Promise<void> {\n const { name } = resolvePreset(cfg, preset); // unknown names throw, listing what is declared\n await store.exec('DROP TABLE IF EXISTS temp.scope');\n await store.exec('CREATE TEMP TABLE scope (\"path\" TEXT PRIMARY KEY)');\n const insert = await store.prepare('INSERT INTO temp.scope (\"path\") SELECT \"path\" FROM preset_files WHERE preset = ?');\n await insert.run(name);\n}\n\n// An unbound `?` silently binds NULL, so mismatched param counts fail loudly instead.\nexport async function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: RowFormat, label: string, noBuild: boolean, preset?: string): Promise<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 // Naming a preset and never joining it would return the whole index while reading as scoped,\n // which is the one hazard of binding rather than applying. Refuse instead.\n if (preset !== undefined && !/\\bscope\\b/i.test(sql)) {\n console.error(`--preset binds a temporary \"scope\" table of the preset's paths, and ${label} never joins it, so the preset would have no effect`);\n console.error(`add: JOIN scope ON scope.\"path\" = <table>.\"path\"`);\n process.exit(2);\n }\n await withResolvedDb(cfg, { noBuild, requirements: new Set<BuildRequirement>(['core']) }, async (store) => {\n if (preset !== undefined) await bindScope(store, cfg, preset);\n // Streamed, not collected: `sql`'s result size is the caller's business, not ours. columns() reads the statement's own metadata, so a 0-row csv gets a header too.\n // A mid-stream SQLite error (e.g. SQLITE_BUSY outlasting busy_timeout) may leave partial output; the nonzero exit code is the failure signal, not a completeness guarantee.\n try {\n const statement = await store.raw.prepare(sql);\n const columns = statement.columns().map((c) => c.name);\n await printRowStream(statement.iterate(...params) as AsyncIterable<Row>, format, columns);\n } catch (err) {\n const hinted = columnHint(await store.docs.columns(), err as Error); // columns read while the store is still open\n // A saved query or ad-hoc SQL can carry `content MATCH ?` too, so the same FTS5 punctuation trap applies to its bound parameters.\n // SQL without MATCH gets its error verbatim; search advice on a plain typo would mislead.\n if (/\\bMATCH\\b/i.test(sql)) throw searchError(hinted, params.join(' '));\n throw hinted;\n }\n });\n}\n"],"names":["CONFIG","FORMAT","NO_BUILD","SCOPE","SEARCH_FLAGS","formatOf","parse","parseK","parseSnippetCharLimit","parseSnippetCountLimit","printWarnings","rowFormatOf","runSql","scopeOf","withDb","withResolvedDb","format","type","default","config","where","preset","include","multiple","exclude","k","values","noExclude","pickFormat","allowed","String","includes","console","error","join","process","exit","argv","usage","options","positionals","parseArgs","args","help","short","strict","allowPositionals","err","message","log","usageError","undefined","parsed","Number","isInteger","value","warnings","w","warn","cfg","fn","requirements","build","store","noBuild","openStoreFor","close","ctx","configPath","resolveConfig","writeMigration","query","bindScope","name","insert","resolvePreset","exec","prepare","run","sql","params","label","placeholderCount","match","length","test","Set","statement","columns","hinted","raw","map","c","printRowStream","iterate","docs","columnHint","searchError"],"mappings":"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"}
|
package/dist/cjs/cli/sql.js
CHANGED
|
@@ -213,12 +213,12 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
213
213
|
}
|
|
214
214
|
var sqlCmd = function sqlCmd(ctx) {
|
|
215
215
|
return _async_to_generator(function() {
|
|
216
|
-
var usage, _parse, values, positionals, _positionals, sql, params, format;
|
|
216
|
+
var usage, _parse, values, positionals, _positionals, sql, params, format, noBuild, cfg;
|
|
217
217
|
return _ts_generator(this, function(_state) {
|
|
218
218
|
switch(_state.label){
|
|
219
219
|
case 0:
|
|
220
220
|
usage = "usage: ".concat(ctx.name, " ").concat(_indexts.USAGE.sql);
|
|
221
|
-
_parse = (0, _sharedts.parse)(ctx.argv, usage, _object_spread_props(_object_spread({}, _sharedts.FORMAT, _sharedts.CONFIG), {
|
|
221
|
+
_parse = (0, _sharedts.parse)(ctx.argv, usage, _object_spread_props(_object_spread({}, _sharedts.NO_BUILD, _sharedts.FORMAT, _sharedts.CONFIG), {
|
|
222
222
|
preset: {
|
|
223
223
|
type: 'string'
|
|
224
224
|
}
|
|
@@ -226,9 +226,14 @@ var sqlCmd = function sqlCmd(ctx) {
|
|
|
226
226
|
_positionals = _to_array(positionals), sql = _positionals[0], params = _positionals.slice(1);
|
|
227
227
|
if (!sql) ctx.usageError(usage);
|
|
228
228
|
format = (0, _sharedts.rowFormatOf)(values);
|
|
229
|
+
noBuild = values['no-build'] === true;
|
|
230
|
+
cfg = ctx.resolveConfig(values.config, {
|
|
231
|
+
writeMigration: !noBuild,
|
|
232
|
+
query: true
|
|
233
|
+
});
|
|
229
234
|
return [
|
|
230
235
|
4,
|
|
231
|
-
(0, _sharedts.runSql)(
|
|
236
|
+
(0, _sharedts.runSql)(cfg, sql, params, format, 'ad-hoc statement', noBuild, values.preset)
|
|
232
237
|
];
|
|
233
238
|
case 1:
|
|
234
239
|
_state.sent();
|
package/dist/cjs/cli/sql.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/sql.ts"],"sourcesContent":["import { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, parse, rowFormatOf, runSql } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst sqlCmd: Command = async (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.sql}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...FORMAT, ...CONFIG, preset: { type: 'string' } });\n const [sql, ...params] = positionals;\n if (!sql) ctx.usageError(usage);\n const format = rowFormatOf(values);\n
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/sql.ts"],"sourcesContent":["import { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, NO_BUILD, parse, rowFormatOf, runSql } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst sqlCmd: Command = async (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.sql}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...NO_BUILD, ...FORMAT, ...CONFIG, preset: { type: 'string' } });\n const [sql, ...params] = positionals;\n if (!sql) ctx.usageError(usage);\n const format = rowFormatOf(values);\n const noBuild = values['no-build'] === true;\n const cfg = ctx.resolveConfig(values.config as string | undefined, { writeMigration: !noBuild, query: true });\n await runSql(cfg, sql, params, format, 'ad-hoc statement', noBuild, values.preset as string | undefined);\n};\nexport default sqlCmd;\n"],"names":["sqlCmd","ctx","usage","parse","values","positionals","sql","params","format","noBuild","cfg","USAGE","name","argv","NO_BUILD","FORMAT","CONFIG","preset","type","usageError","rowFormatOf","resolveConfig","config","writeMigration","query","runSql"],"mappings":";;;;+BAcA;;;eAAA;;;uBAdsB;wBAC+C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGrE,IAAMA,SAAkB,gBAAOC;;YACvBC,OAC0BC,QAAxBC,QAAQC,aACSA,cAAlBC,KAAQC,QAETC,QACAC,SACAC;;;;oBANAR,QAAQ,AAAC,UAAqBS,OAAZV,IAAIW,IAAI,EAAC,KAAa,OAAVD,cAAK,CAACL,GAAG;oBACbH,SAAAA,IAAAA,eAAK,EAACF,IAAIY,IAAI,EAAEX,OAAO,wCAAKY,kBAAQ,EAAKC,gBAAM,EAAKC,gBAAM;wBAAEC,QAAQ;4BAAEC,MAAM;wBAAS;yBAA7Gd,SAAwBD,OAAxBC,QAAQC,cAAgBF,OAAhBE;oBACSA,yBAAAA,cAAlBC,MAAkBD,iBAAVE,SAAUF,mBAAb;oBACZ,IAAI,CAACC,KAAKL,IAAIkB,UAAU,CAACjB;oBACnBM,SAASY,IAAAA,qBAAW,EAAChB;oBACrBK,UAAUL,MAAM,CAAC,WAAW,KAAK;oBACjCM,MAAMT,IAAIoB,aAAa,CAACjB,OAAOkB,MAAM,EAAwB;wBAAEC,gBAAgB,CAACd;wBAASe,OAAO;oBAAK;oBAC3G;;wBAAMC,IAAAA,gBAAM,EAACf,KAAKJ,KAAKC,QAAQC,QAAQ,oBAAoBC,SAASL,OAAOa,MAAM;;;oBAAjF;;;;;;IACF;;IACA,WAAejB"}
|