sensemaking 0.4.0 → 0.6.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 +16 -7
- package/dist/cjs/cli.js +5 -1
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/commands/find.js +173 -10
- package/dist/cjs/commands/find.js.map +1 -1
- package/dist/cjs/commands/map.js +1 -1
- package/dist/cjs/commands/map.js.map +1 -1
- package/dist/cjs/commands/peek.js +1 -1
- package/dist/cjs/commands/peek.js.map +1 -1
- package/dist/cjs/commands/shared.d.cts +1 -1
- package/dist/cjs/commands/shared.d.ts +1 -1
- package/dist/cjs/commands/shared.js +166 -8
- package/dist/cjs/commands/shared.js.map +1 -1
- package/dist/cjs/commands/status.js +10 -1
- package/dist/cjs/commands/status.js.map +1 -1
- package/dist/cjs/commands/types.d.cts +1 -0
- package/dist/cjs/commands/types.d.ts +1 -0
- package/dist/cjs/config.d.cts +26 -2
- package/dist/cjs/config.d.ts +26 -2
- package/dist/cjs/config.js +171 -10
- package/dist/cjs/config.js.map +1 -1
- package/dist/cjs/db.js +46 -16
- package/dist/cjs/db.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.d.cts +14 -0
- package/dist/cjs/features/embed.d.ts +14 -0
- package/dist/cjs/features/embed.js +840 -0
- package/dist/cjs/features/embed.js.map +1 -0
- package/dist/cjs/features/index.js +3 -1
- package/dist/cjs/features/index.js.map +1 -1
- package/dist/cjs/features/types.d.cts +4 -1
- package/dist/cjs/features/types.d.ts +4 -1
- package/dist/cjs/index.d.cts +3 -10
- package/dist/cjs/index.d.ts +3 -10
- package/dist/cjs/index.js +2 -52
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/output.d.cts +5 -0
- package/dist/cjs/output.d.ts +5 -0
- package/dist/cjs/output.js +14 -1
- package/dist/cjs/output.js.map +1 -1
- package/dist/cjs/scan.js +9 -8
- package/dist/cjs/scan.js.map +1 -1
- package/dist/cjs/verbs.d.cts +8 -2
- package/dist/cjs/verbs.d.ts +8 -2
- package/dist/cjs/verbs.js +263 -76
- package/dist/cjs/verbs.js.map +1 -1
- package/dist/esm/cli.js +5 -1
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/commands/find.js +5 -4
- package/dist/esm/commands/find.js.map +1 -1
- package/dist/esm/commands/map.js +1 -3
- package/dist/esm/commands/map.js.map +1 -1
- package/dist/esm/commands/peek.js +1 -1
- package/dist/esm/commands/peek.js.map +1 -1
- package/dist/esm/commands/shared.d.ts +1 -1
- package/dist/esm/commands/shared.js +2 -2
- package/dist/esm/commands/shared.js.map +1 -1
- package/dist/esm/commands/status.js +8 -1
- package/dist/esm/commands/status.js.map +1 -1
- package/dist/esm/commands/types.d.ts +1 -0
- package/dist/esm/commands/types.js.map +1 -1
- package/dist/esm/config.d.ts +26 -2
- package/dist/esm/config.js +88 -10
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/db.js +19 -10
- package/dist/esm/db.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.d.ts +14 -0
- package/dist/esm/features/embed.js +290 -0
- package/dist/esm/features/embed.js.map +1 -0
- package/dist/esm/features/index.js +3 -1
- package/dist/esm/features/index.js.map +1 -1
- package/dist/esm/features/types.d.ts +4 -1
- package/dist/esm/features/types.js.map +1 -1
- package/dist/esm/index.d.ts +3 -10
- package/dist/esm/index.js +4 -6
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/output.d.ts +5 -0
- package/dist/esm/output.js +11 -1
- package/dist/esm/output.js.map +1 -1
- package/dist/esm/scan.js +9 -8
- package/dist/esm/scan.js.map +1 -1
- package/dist/esm/verbs.d.ts +8 -2
- package/dist/esm/verbs.js +51 -13
- package/dist/esm/verbs.js.map +1 -1
- package/package.json +2 -1
- package/schema.json +17 -1
- package/skills/sense/EXAMPLES.md +16 -0
- package/skills/sense/SKILL.md +41 -19
- package/skills/sense-setup/SKILL.md +73 -0
package/dist/cjs/verbs.js
CHANGED
|
@@ -22,6 +22,7 @@ _export(exports, {
|
|
|
22
22
|
var _posix = /*#__PURE__*/ _interop_require_default(require("node:path/posix"));
|
|
23
23
|
var _configts = require("./config.js");
|
|
24
24
|
var _errorsts = require("./errors.js");
|
|
25
|
+
var _embedts = require("./features/embed.js");
|
|
25
26
|
var _indexts = require("./features/index.js");
|
|
26
27
|
var _graphts = require("./graph.js");
|
|
27
28
|
function _array_like_to_array(arr, len) {
|
|
@@ -35,6 +36,35 @@ function _array_with_holes(arr) {
|
|
|
35
36
|
function _array_without_holes(arr) {
|
|
36
37
|
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
37
38
|
}
|
|
39
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
40
|
+
try {
|
|
41
|
+
var info = gen[key](arg);
|
|
42
|
+
var value = info.value;
|
|
43
|
+
} catch (error) {
|
|
44
|
+
reject(error);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (info.done) {
|
|
48
|
+
resolve(value);
|
|
49
|
+
} else {
|
|
50
|
+
Promise.resolve(value).then(_next, _throw);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function _async_to_generator(fn) {
|
|
54
|
+
return function() {
|
|
55
|
+
var self = this, args = arguments;
|
|
56
|
+
return new Promise(function(resolve, reject) {
|
|
57
|
+
var gen = fn.apply(self, args);
|
|
58
|
+
function _next(value) {
|
|
59
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
60
|
+
}
|
|
61
|
+
function _throw(err) {
|
|
62
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
63
|
+
}
|
|
64
|
+
_next(undefined);
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
}
|
|
38
68
|
function _interop_require_default(obj) {
|
|
39
69
|
return obj && obj.__esModule ? obj : {
|
|
40
70
|
default: obj
|
|
@@ -87,87 +117,237 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
87
117
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
88
118
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
89
119
|
}
|
|
120
|
+
function _ts_generator(thisArg, body) {
|
|
121
|
+
var f, y, t, _ = {
|
|
122
|
+
label: 0,
|
|
123
|
+
sent: function() {
|
|
124
|
+
if (t[0] & 1) throw t[1];
|
|
125
|
+
return t[1];
|
|
126
|
+
},
|
|
127
|
+
trys: [],
|
|
128
|
+
ops: []
|
|
129
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
|
|
130
|
+
return d(g, "next", {
|
|
131
|
+
value: verb(0)
|
|
132
|
+
}), d(g, "throw", {
|
|
133
|
+
value: verb(1)
|
|
134
|
+
}), d(g, "return", {
|
|
135
|
+
value: verb(2)
|
|
136
|
+
}), typeof Symbol === "function" && d(g, Symbol.iterator, {
|
|
137
|
+
value: function() {
|
|
138
|
+
return this;
|
|
139
|
+
}
|
|
140
|
+
}), g;
|
|
141
|
+
function verb(n) {
|
|
142
|
+
return function(v) {
|
|
143
|
+
return step([
|
|
144
|
+
n,
|
|
145
|
+
v
|
|
146
|
+
]);
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function step(op) {
|
|
150
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
151
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
152
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
153
|
+
if (y = 0, t) op = [
|
|
154
|
+
op[0] & 2,
|
|
155
|
+
t.value
|
|
156
|
+
];
|
|
157
|
+
switch(op[0]){
|
|
158
|
+
case 0:
|
|
159
|
+
case 1:
|
|
160
|
+
t = op;
|
|
161
|
+
break;
|
|
162
|
+
case 4:
|
|
163
|
+
_.label++;
|
|
164
|
+
return {
|
|
165
|
+
value: op[1],
|
|
166
|
+
done: false
|
|
167
|
+
};
|
|
168
|
+
case 5:
|
|
169
|
+
_.label++;
|
|
170
|
+
y = op[1];
|
|
171
|
+
op = [
|
|
172
|
+
0
|
|
173
|
+
];
|
|
174
|
+
continue;
|
|
175
|
+
case 7:
|
|
176
|
+
op = _.ops.pop();
|
|
177
|
+
_.trys.pop();
|
|
178
|
+
continue;
|
|
179
|
+
default:
|
|
180
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
181
|
+
_ = 0;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
185
|
+
_.label = op[1];
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
189
|
+
_.label = t[1];
|
|
190
|
+
t = op;
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
if (t && _.label < t[2]) {
|
|
194
|
+
_.label = t[2];
|
|
195
|
+
_.ops.push(op);
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
if (t[2]) _.ops.pop();
|
|
199
|
+
_.trys.pop();
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
op = body.call(thisArg, _);
|
|
203
|
+
} catch (e) {
|
|
204
|
+
op = [
|
|
205
|
+
6,
|
|
206
|
+
e
|
|
207
|
+
];
|
|
208
|
+
y = 0;
|
|
209
|
+
} finally{
|
|
210
|
+
f = t = 0;
|
|
211
|
+
}
|
|
212
|
+
if (op[0] & 5) throw op[1];
|
|
213
|
+
return {
|
|
214
|
+
value: op[0] ? op[1] : void 0,
|
|
215
|
+
done: true
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
}
|
|
90
219
|
// The three layer verbs: mapTree (orient), find (locate), peek (structure).
|
|
91
220
|
// Each returns data; cli.ts renders. All of them degrade when a feature is off.
|
|
92
221
|
var WEIGHTED_BM25 = 'bm25(content, 10.0, 5.0, 1.0)';
|
|
93
222
|
var RRF_K = 60;
|
|
94
|
-
function find(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
223
|
+
function find(_0, _1, _2) {
|
|
224
|
+
return _async_to_generator(function(db, cfg, terms) {
|
|
225
|
+
var opts, _opts_k, _hits_get, _chunkLines_get, k, fetch, whereJoin, whereCond, matchSql, matchRows, hits, candidates, edges, linked, nodes, seeds, ranked, chunkLines, vec, insert, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _step_value, path, c, where, linesCol;
|
|
226
|
+
var _arguments = arguments;
|
|
227
|
+
return _ts_generator(this, function(_state) {
|
|
228
|
+
switch(_state.label){
|
|
229
|
+
case 0:
|
|
230
|
+
opts = _arguments.length > 3 && _arguments[3] !== void 0 ? _arguments[3] : {};
|
|
231
|
+
k = (_opts_k = opts.k) !== null && _opts_k !== void 0 ? _opts_k : 10;
|
|
232
|
+
fetch = Math.max(k * 3, 30);
|
|
233
|
+
// Terms pass verbatim to FTS5 MATCH: bare words AND-join, operators are the caller's.
|
|
234
|
+
// Invalid syntax propagates as an error, zero matches return zero -- no silent rewrites.
|
|
235
|
+
// --where applies inside the candidate query (a post-filter over the top-N would drop
|
|
236
|
+
// matches ranked past the pool) and again on the final select for link-derived rows.
|
|
237
|
+
whereJoin = opts.where ? 'JOIN frontmatter f ON f."path" = content.path' : '';
|
|
238
|
+
whereCond = opts.where ? "AND (".concat(opts.where, ")") : '';
|
|
239
|
+
matchSql = "SELECT content.path AS path, snippet(content, -1, '\xab', '\xbb', '…', 10) AS hit FROM content ".concat(whereJoin, " WHERE content MATCH ? ").concat(whereCond, " ORDER BY ").concat(WEIGHTED_BM25, " LIMIT ").concat(fetch);
|
|
240
|
+
matchRows = db.prepare(matchSql).all(terms);
|
|
241
|
+
hits = new Map(matchRows.map(function(r) {
|
|
242
|
+
return [
|
|
243
|
+
r.path,
|
|
244
|
+
r.hit
|
|
245
|
+
];
|
|
246
|
+
}));
|
|
247
|
+
candidates = new Map();
|
|
248
|
+
matchRows.forEach(function(r, i) {
|
|
249
|
+
candidates.set(r.path, {
|
|
250
|
+
score: 1 / (RRF_K + i),
|
|
251
|
+
via: 'match'
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
edges = (0, _configts.featureEnabled)(cfg, 'links') && matchRows.length > 0 ? (0, _indexts.linkEdges)(db) : [];
|
|
255
|
+
if (edges.length > 0) {
|
|
256
|
+
// `linked` gates the label only, not the score: PPR restart mass gives every seed a
|
|
257
|
+
// nonzero rank even without an incident edge, which is not link evidence — but dropping
|
|
258
|
+
// that mass from the score list reweights fusion toward connectivity and measurably
|
|
259
|
+
// wrecks ranking on link-dense corpora (FEVER hit@10 0.997 -> 0.907; fusion-tuning.md).
|
|
260
|
+
linked = new Set(edges.flat());
|
|
261
|
+
nodes = db.prepare('SELECT "path" FROM frontmatter').all().map(function(r) {
|
|
262
|
+
return r.path;
|
|
263
|
+
});
|
|
264
|
+
seeds = new Map(matchRows.map(function(r, i) {
|
|
265
|
+
return [
|
|
266
|
+
r.path,
|
|
267
|
+
1 / (i + 1)
|
|
268
|
+
];
|
|
269
|
+
}));
|
|
270
|
+
ranked = _to_consumable_array((0, _graphts.personalizedRank)(nodes, edges, seeds)).filter(function(param) {
|
|
271
|
+
var _param = _sliced_to_array(param, 2), score = _param[1];
|
|
272
|
+
return score > 1e-9;
|
|
273
|
+
}).sort(function(a, b) {
|
|
274
|
+
return b[1] - a[1];
|
|
275
|
+
}).slice(0, fetch);
|
|
276
|
+
ranked.forEach(function(param, i) {
|
|
277
|
+
var _param = _sliced_to_array(param, 1), path = _param[0];
|
|
278
|
+
var existing = candidates.get(path);
|
|
279
|
+
if (existing) {
|
|
280
|
+
existing.score += 1 / (RRF_K + i);
|
|
281
|
+
if (linked.has(path)) existing.via = 'match+link';
|
|
282
|
+
} else {
|
|
283
|
+
candidates.set(path, {
|
|
284
|
+
score: 1 / (RRF_K + i),
|
|
285
|
+
via: 'link'
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
// Vector expansion, invoked only: a third RRF list at the swept flat-region constants
|
|
291
|
+
// (weight 1, pool = fetch). Each row carries its best chunk's line range.
|
|
292
|
+
chunkLines = new Map();
|
|
293
|
+
if (!opts.semantic) return [
|
|
294
|
+
3,
|
|
295
|
+
2
|
|
296
|
+
];
|
|
297
|
+
return [
|
|
298
|
+
4,
|
|
299
|
+
(0, _embedts.semanticCandidates)(db, cfg, terms, fetch)
|
|
300
|
+
];
|
|
301
|
+
case 1:
|
|
302
|
+
vec = _state.sent();
|
|
303
|
+
vec.forEach(function(param, i) {
|
|
304
|
+
var path = param.path, lines = param.lines;
|
|
305
|
+
chunkLines.set(path, lines);
|
|
306
|
+
var existing = candidates.get(path);
|
|
307
|
+
if (existing) {
|
|
308
|
+
existing.score += 1 / (RRF_K + i);
|
|
309
|
+
existing.via = "".concat(existing.via, "+vector");
|
|
310
|
+
} else {
|
|
311
|
+
candidates.set(path, {
|
|
312
|
+
score: 1 / (RRF_K + i),
|
|
313
|
+
via: 'vector'
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
_state.label = 2;
|
|
318
|
+
case 2:
|
|
319
|
+
db.exec('DROP TABLE IF EXISTS _find');
|
|
320
|
+
db.exec('CREATE TEMP TABLE _find ("path" TEXT PRIMARY KEY, score REAL, via TEXT, hit TEXT, lines TEXT)');
|
|
321
|
+
insert = db.prepare('INSERT INTO _find ("path", score, via, hit, lines) VALUES (?, ?, ?, ?, ?)');
|
|
322
|
+
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
323
|
+
try {
|
|
324
|
+
for(_iterator = candidates[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
325
|
+
_step_value = _sliced_to_array(_step.value, 2), path = _step_value[0], c = _step_value[1];
|
|
326
|
+
insert.run(path, c.score, c.via, (_hits_get = hits.get(path)) !== null && _hits_get !== void 0 ? _hits_get : null, (_chunkLines_get = chunkLines.get(path)) !== null && _chunkLines_get !== void 0 ? _chunkLines_get : null);
|
|
327
|
+
}
|
|
328
|
+
} catch (err) {
|
|
329
|
+
_didIteratorError = true;
|
|
330
|
+
_iteratorError = err;
|
|
331
|
+
} finally{
|
|
332
|
+
try {
|
|
333
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
334
|
+
_iterator.return();
|
|
335
|
+
}
|
|
336
|
+
} finally{
|
|
337
|
+
if (_didIteratorError) {
|
|
338
|
+
throw _iteratorError;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
where = opts.where ? "WHERE ".concat(opts.where) : '';
|
|
343
|
+
linesCol = opts.semantic ? ', _find.lines' : '';
|
|
344
|
+
return [
|
|
345
|
+
2,
|
|
346
|
+
db.prepare('SELECT f."path" AS path, content.title, content.summary, _find.hit, _find.via, round(_find.score, 4) AS score'.concat(linesCol, '\n FROM _find JOIN frontmatter f ON f."path" = _find."path" JOIN content ON content.path = _find."path"\n ').concat(where, " ORDER BY _find.score DESC LIMIT ?")).all(k)
|
|
347
|
+
];
|
|
143
348
|
}
|
|
144
349
|
});
|
|
145
|
-
}
|
|
146
|
-
db.exec('CREATE TEMP TABLE IF NOT EXISTS _find ("path" TEXT PRIMARY KEY, score REAL, via TEXT, hit TEXT)');
|
|
147
|
-
db.exec('DELETE FROM _find');
|
|
148
|
-
var insert = db.prepare('INSERT INTO _find ("path", score, via, hit) VALUES (?, ?, ?, ?)');
|
|
149
|
-
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
150
|
-
try {
|
|
151
|
-
for(var _iterator = candidates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
152
|
-
var _step_value = _sliced_to_array(_step.value, 2), path = _step_value[0], c = _step_value[1];
|
|
153
|
-
insert.run(path, c.score, c.via, (_hits_get = hits.get(path)) !== null && _hits_get !== void 0 ? _hits_get : null);
|
|
154
|
-
}
|
|
155
|
-
} catch (err) {
|
|
156
|
-
_didIteratorError = true;
|
|
157
|
-
_iteratorError = err;
|
|
158
|
-
} finally{
|
|
159
|
-
try {
|
|
160
|
-
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
161
|
-
_iterator.return();
|
|
162
|
-
}
|
|
163
|
-
} finally{
|
|
164
|
-
if (_didIteratorError) {
|
|
165
|
-
throw _iteratorError;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
var where = opts.where ? "WHERE ".concat(opts.where) : '';
|
|
170
|
-
return db.prepare('SELECT f."path" AS path, content.title, content.summary, _find.hit, _find.via, round(_find.score, 4) AS score\n FROM _find JOIN frontmatter f ON f."path" = _find."path" JOIN content ON content.path = _find."path"\n '.concat(where, " ORDER BY _find.score DESC LIMIT ?")).all(k);
|
|
350
|
+
}).apply(this, arguments);
|
|
171
351
|
}
|
|
172
352
|
var INTERNAL_COLUMNS = new Set([
|
|
173
353
|
'path',
|
|
@@ -198,6 +378,7 @@ function mapTree(db, cfg) {
|
|
|
198
378
|
docs: docs,
|
|
199
379
|
fields: fields,
|
|
200
380
|
fieldsTotal: allFields.length,
|
|
381
|
+
features: (0, _configts.featureStates)(cfg),
|
|
201
382
|
hubs: hubs,
|
|
202
383
|
recent: recent
|
|
203
384
|
};
|
|
@@ -274,7 +455,13 @@ function peek(db, cfg, pathArg) {
|
|
|
274
455
|
unresolved: unresolved.slice(0, PEEK_LINK_LIMIT),
|
|
275
456
|
outboundTotal: outbound.length,
|
|
276
457
|
backlinksTotal: backlinksTotal,
|
|
277
|
-
unresolvedTotal: unresolved.length
|
|
458
|
+
unresolvedTotal: unresolved.length,
|
|
459
|
+
off: [
|
|
460
|
+
'sections',
|
|
461
|
+
'links'
|
|
462
|
+
].filter(function(name) {
|
|
463
|
+
return !(0, _configts.featureEnabled)(cfg, name);
|
|
464
|
+
})
|
|
278
465
|
};
|
|
279
466
|
}
|
|
280
467
|
/* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
|
package/dist/cjs/verbs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/verbs.ts"],"sourcesContent":["import posix from 'node:path/posix';\nimport type { DatabaseSync } from 'node:sqlite';\nimport type { Config } from './config.ts';\nimport { featureEnabled } from './config.ts';\nimport { SenseError } from './errors.ts';\nimport { linkEdges } from './features/index.ts';\nimport { personalizedRank } from './graph.ts';\nimport type { Row } from './output.ts';\n\n// The three layer verbs: mapTree (orient), find (locate), peek (structure).\n// Each returns data; cli.ts renders. All of them degrade when a feature is off.\n\nconst WEIGHTED_BM25 = 'bm25(content, 10.0, 5.0, 1.0)';\nconst RRF_K = 60;\n\nexport interface FindOptions {\n k?: number;\n where?: string; // SQL fragment against frontmatter alias `f`, e.g. \"f.status = 'active'\"\n}\n\n// Layer 1: BM25 + link-graph expansion, fused by reciprocal rank. `via` says which\n// signal produced each row so the agent knows what evidence it is trusting.\nexport function find(db: DatabaseSync, cfg: Config, terms: string, opts: FindOptions = {}): Row[] {\n const k = opts.k ?? 10;\n const fetch = Math.max(k * 3, 30);\n\n // Terms pass verbatim to FTS5 MATCH: bare words AND-join, operators are the caller's.\n // Invalid syntax propagates as an error, zero matches return zero -- no silent rewrites.\n const matchSql = `SELECT content.path AS path, snippet(content, -1, '«', '»', '…', 10) AS hit FROM content WHERE content MATCH ? ORDER BY ${WEIGHTED_BM25} LIMIT ${fetch}`;\n const matchRows = db.prepare(matchSql).all(terms) as Array<{ path: string; hit: string }>;\n\n const hits = new Map(matchRows.map((r) => [r.path, r.hit]));\n const candidates = new Map<string, { score: number; via: string }>();\n matchRows.forEach((r, i) => {\n candidates.set(r.path, { score: 1 / (RRF_K + i), via: 'match' });\n });\n\n if (featureEnabled(cfg, 'links') && matchRows.length > 0) {\n const nodes = (db.prepare('SELECT \"path\" FROM frontmatter').all() as Array<{ path: string }>).map((r) => r.path);\n const seeds = new Map(matchRows.map((r, i) => [r.path, 1 / (i + 1)]));\n const ranked = [...personalizedRank(nodes, linkEdges(db), seeds)]\n .filter(([, score]) => score > 1e-9)\n .sort((a, b) => b[1] - a[1])\n .slice(0, fetch);\n ranked.forEach(([path], i) => {\n const existing = candidates.get(path);\n if (existing) {\n existing.score += 1 / (RRF_K + i);\n existing.via = 'match+link';\n } else {\n candidates.set(path, { score: 1 / (RRF_K + i), via: 'link' });\n }\n });\n }\n\n db.exec('CREATE TEMP TABLE IF NOT EXISTS _find (\"path\" TEXT PRIMARY KEY, score REAL, via TEXT, hit TEXT)');\n db.exec('DELETE FROM _find');\n const insert = db.prepare('INSERT INTO _find (\"path\", score, via, hit) VALUES (?, ?, ?, ?)');\n for (const [path, c] of candidates) insert.run(path, c.score, c.via, hits.get(path) ?? null);\n\n const where = opts.where ? `WHERE ${opts.where}` : '';\n return db\n .prepare(\n `SELECT f.\"path\" AS path, content.title, content.summary, _find.hit, _find.via, round(_find.score, 4) AS score\n FROM _find JOIN frontmatter f ON f.\"path\" = _find.\"path\" JOIN content ON content.path = _find.\"path\"\n ${where} ORDER BY _find.score DESC LIMIT ?`\n )\n .all(k) as Row[];\n}\n\nexport interface TreeMap {\n docs: { count: number; bytes: number };\n fields: Row[]; // top 20 by coverage; fieldsTotal carries the real count\n fieldsTotal: number;\n hubs: Row[];\n recent: Row[];\n}\n\nconst INTERNAL_COLUMNS = new Set(['path', '_mtime', '_size', '_rank']);\n\n// Layer 0: what is this tree. Fixed-size output regardless of tree size.\nexport function mapTree(db: DatabaseSync, cfg: Config): TreeMap {\n const docs = db.prepare('SELECT COUNT(*) AS count, COALESCE(SUM(\"_size\"), 0) AS bytes FROM frontmatter').get() as { count: number; bytes: number };\n\n const columns = (db.prepare('PRAGMA table_info(frontmatter)').all() as Array<{ name: string }>).map((r) => r.name).filter((name) => !INTERNAL_COLUMNS.has(name));\n const allFields = columns\n .map((name) => {\n const { n } = db.prepare(`SELECT COUNT(\"${name.split('\"').join('\"\"')}\") AS n FROM frontmatter`).get() as { n: number };\n return { field: name, coverage: n };\n })\n .sort((a, b) => (b.coverage as number) - (a.coverage as number)) as Row[];\n const fields = allFields.slice(0, 20);\n\n const hubs = featureEnabled(cfg, 'rank') ? (db.prepare(`SELECT f.\"path\" AS path, round(f.\"_rank\" * 100, 2) AS rank, content.title FROM frontmatter f JOIN content ON content.path = f.\"path\" WHERE f.\"_rank\" IS NOT NULL ORDER BY f.\"_rank\" DESC LIMIT 8`).all() as Row[]) : [];\n\n const recent = db.prepare(`SELECT \"path\", datetime(\"_mtime\" / 1000, 'unixepoch') AS modified FROM frontmatter ORDER BY \"_mtime\" DESC LIMIT 5`).all() as Row[];\n\n return { docs, fields, fieldsTotal: allFields.length, hubs, recent };\n}\n\nexport interface Peek {\n path: string;\n tokens: number;\n frontmatter: Row;\n sections: Row[];\n outbound: string[];\n backlinks: string[];\n unresolved: string[];\n // Totals before truncation: a hub can have thousands of backlinks, and peek's whole\n // point is bounded output. Query the links table directly for the full list.\n outboundTotal: number;\n backlinksTotal: number;\n unresolvedTotal: number;\n}\n\nconst PEEK_LINK_LIMIT = 20;\n\n// Layer 2: everything about one note except its prose -- frontmatter, outline with line\n// ranges + token estimates (so the follow-up Read is a range, not the file), links both ways.\nexport function peek(db: DatabaseSync, cfg: Config, pathArg: string): Peek {\n const paths = (db.prepare('SELECT \"path\" FROM frontmatter').all() as Array<{ path: string }>).map((r) => r.path);\n let path = paths.find((p) => p === pathArg);\n if (!path) {\n const base = posix.basename(pathArg).replace(/\\.md$/i, '').toLowerCase();\n const matches = paths.filter((p) => posix.basename(p).replace(/\\.md$/i, '').toLowerCase() === base);\n if (matches.length === 1) path = matches[0];\n else if (matches.length > 1) throw new SenseError('NOTE_AMBIGUOUS', `\"${pathArg}\" is ambiguous: ${matches.join(', ')}`);\n else throw new SenseError('NOTE_NOT_FOUND', `no note matches \"${pathArg}\"`);\n }\n\n const row = db.prepare('SELECT * FROM frontmatter WHERE \"path\" = ?').get(path) as Row;\n const frontmatter: Row = {};\n for (const [key, value] of Object.entries(row)) {\n if (!INTERNAL_COLUMNS.has(key) && value !== null) frontmatter[key] = value;\n }\n\n const sections = featureEnabled(cfg, 'sections') ? (db.prepare('SELECT level, heading, start_line, end_line, tokens FROM sections WHERE \"path\" = ? ORDER BY idx').all(path) as Row[]) : [];\n\n let outbound: string[] = [];\n let backlinks: string[] = [];\n let unresolved: string[] = [];\n let backlinksTotal = 0;\n if (featureEnabled(cfg, 'links')) {\n const out = db.prepare('SELECT target, dst FROM links WHERE src = ? ORDER BY target').all(path) as Array<{ target: string; dst: string | null }>;\n outbound = [...new Set(out.filter((l) => l.dst !== null).map((l) => l.dst as string))];\n unresolved = out.filter((l) => l.dst === null).map((l) => l.target);\n backlinksTotal = (db.prepare('SELECT COUNT(DISTINCT src) AS n FROM links WHERE dst = ?').get(path) as { n: number }).n;\n backlinks = (db.prepare('SELECT DISTINCT src FROM links WHERE dst = ? ORDER BY src LIMIT ?').all(path, PEEK_LINK_LIMIT) as Array<{ src: string }>).map((r) => r.src);\n }\n\n return {\n path,\n tokens: Math.ceil(((row._size as number) ?? 0) / 4),\n frontmatter,\n sections,\n outbound: outbound.slice(0, PEEK_LINK_LIMIT),\n backlinks,\n unresolved: unresolved.slice(0, PEEK_LINK_LIMIT),\n outboundTotal: outbound.length,\n backlinksTotal,\n unresolvedTotal: unresolved.length,\n };\n}\n"],"names":["find","mapTree","peek","WEIGHTED_BM25","RRF_K","db","cfg","terms","opts","hits","k","fetch","Math","max","matchSql","matchRows","prepare","all","Map","map","r","path","hit","candidates","forEach","i","set","score","via","featureEnabled","length","nodes","seeds","ranked","personalizedRank","linkEdges","filter","sort","a","b","slice","existing","get","exec","insert","c","run","where","INTERNAL_COLUMNS","Set","docs","columns","name","has","allFields","n","split","join","field","coverage","fields","hubs","recent","fieldsTotal","PEEK_LINK_LIMIT","pathArg","row","paths","p","base","posix","basename","replace","toLowerCase","matches","SenseError","frontmatter","Object","entries","key","value","sections","outbound","backlinks","unresolved","backlinksTotal","out","l","dst","target","src","tokens","ceil","_size","outboundTotal","unresolvedTotal"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/verbs.ts"],"sourcesContent":["import posix from 'node:path/posix';\nimport type { DatabaseSync } from 'node:sqlite';\nimport type { Config, FeatureName } from './config.ts';\nimport { featureEnabled, featureStates } from './config.ts';\nimport { SenseError } from './errors.ts';\nimport { semanticCandidates } from './features/embed.ts';\nimport { linkEdges } from './features/index.ts';\nimport { personalizedRank } from './graph.ts';\nimport type { Row } from './output.ts';\n\n// The three layer verbs: mapTree (orient), find (locate), peek (structure).\n// Each returns data; cli.ts renders. All of them degrade when a feature is off.\n\nconst WEIGHTED_BM25 = 'bm25(content, 10.0, 5.0, 1.0)';\nconst RRF_K = 60;\n\nexport interface FindOptions {\n k?: number;\n where?: string; // SQL fragment against frontmatter alias `f`, e.g. \"f.status = 'active'\"\n semantic?: boolean; // invoke vector expansion (requires features.embed); rows gain via 'vector' and a lines column\n}\n\n// Layer 1: BM25 + link-graph expansion, fused by reciprocal rank. `via` says which\n// signal produced each row so the agent knows what evidence it is trusting.\n// Semantic expansion is per-query opt-in: without opts.semantic the result is\n// byte-for-byte independent of the embed feature.\nexport async function find(db: DatabaseSync, cfg: Config, terms: string, opts: FindOptions = {}): Promise<Row[]> {\n const k = opts.k ?? 10;\n const fetch = Math.max(k * 3, 30);\n\n // Terms pass verbatim to FTS5 MATCH: bare words AND-join, operators are the caller's.\n // Invalid syntax propagates as an error, zero matches return zero -- no silent rewrites.\n // --where applies inside the candidate query (a post-filter over the top-N would drop\n // matches ranked past the pool) and again on the final select for link-derived rows.\n const whereJoin = opts.where ? `JOIN frontmatter f ON f.\"path\" = content.path` : '';\n const whereCond = opts.where ? `AND (${opts.where})` : '';\n const matchSql = `SELECT content.path AS path, snippet(content, -1, '«', '»', '…', 10) AS hit FROM content ${whereJoin} WHERE content MATCH ? ${whereCond} ORDER BY ${WEIGHTED_BM25} LIMIT ${fetch}`;\n const matchRows = db.prepare(matchSql).all(terms) as Array<{ path: string; hit: string }>;\n\n const hits = new Map(matchRows.map((r) => [r.path, r.hit]));\n const candidates = new Map<string, { score: number; via: string }>();\n matchRows.forEach((r, i) => {\n candidates.set(r.path, { score: 1 / (RRF_K + i), via: 'match' });\n });\n\n const edges = featureEnabled(cfg, 'links') && matchRows.length > 0 ? linkEdges(db) : [];\n if (edges.length > 0) {\n // `linked` gates the label only, not the score: PPR restart mass gives every seed a\n // nonzero rank even without an incident edge, which is not link evidence — but dropping\n // that mass from the score list reweights fusion toward connectivity and measurably\n // wrecks ranking on link-dense corpora (FEVER hit@10 0.997 -> 0.907; fusion-tuning.md).\n const linked = new Set(edges.flat());\n const nodes = (db.prepare('SELECT \"path\" FROM frontmatter').all() as Array<{ path: string }>).map((r) => r.path);\n const seeds = new Map(matchRows.map((r, i) => [r.path, 1 / (i + 1)]));\n const ranked = [...personalizedRank(nodes, edges, seeds)]\n .filter(([, score]) => score > 1e-9)\n .sort((a, b) => b[1] - a[1])\n .slice(0, fetch);\n ranked.forEach(([path], i) => {\n const existing = candidates.get(path);\n if (existing) {\n existing.score += 1 / (RRF_K + i);\n if (linked.has(path)) existing.via = 'match+link';\n } else {\n candidates.set(path, { score: 1 / (RRF_K + i), via: 'link' });\n }\n });\n }\n\n // Vector expansion, invoked only: a third RRF list at the swept flat-region constants\n // (weight 1, pool = fetch). Each row carries its best chunk's line range.\n const chunkLines = new Map<string, string>();\n if (opts.semantic) {\n const vec = await semanticCandidates(db, cfg, terms, fetch);\n vec.forEach(({ path, lines }, i) => {\n chunkLines.set(path, lines);\n const existing = candidates.get(path);\n if (existing) {\n existing.score += 1 / (RRF_K + i);\n existing.via = `${existing.via}+vector`;\n } else {\n candidates.set(path, { score: 1 / (RRF_K + i), via: 'vector' });\n }\n });\n }\n\n db.exec('DROP TABLE IF EXISTS _find');\n db.exec('CREATE TEMP TABLE _find (\"path\" TEXT PRIMARY KEY, score REAL, via TEXT, hit TEXT, lines TEXT)');\n const insert = db.prepare('INSERT INTO _find (\"path\", score, via, hit, lines) VALUES (?, ?, ?, ?, ?)');\n for (const [path, c] of candidates) insert.run(path, c.score, c.via, hits.get(path) ?? null, chunkLines.get(path) ?? null);\n\n const where = opts.where ? `WHERE ${opts.where}` : '';\n const linesCol = opts.semantic ? ', _find.lines' : '';\n return db\n .prepare(\n `SELECT f.\"path\" AS path, content.title, content.summary, _find.hit, _find.via, round(_find.score, 4) AS score${linesCol}\n FROM _find JOIN frontmatter f ON f.\"path\" = _find.\"path\" JOIN content ON content.path = _find.\"path\"\n ${where} ORDER BY _find.score DESC LIMIT ?`\n )\n .all(k) as Row[];\n}\n\nexport interface TreeMap {\n docs: { count: number; bytes: number };\n fields: Row[]; // top 20 by coverage; fieldsTotal carries the real count\n fieldsTotal: number;\n features: { on: FeatureName[]; off: FeatureName[] };\n hubs: Row[];\n recent: Row[];\n}\n\nconst INTERNAL_COLUMNS = new Set(['path', '_mtime', '_size', '_rank']);\n\n// Layer 0: what is this tree. Fixed-size output regardless of tree size.\nexport function mapTree(db: DatabaseSync, cfg: Config): TreeMap {\n const docs = db.prepare('SELECT COUNT(*) AS count, COALESCE(SUM(\"_size\"), 0) AS bytes FROM frontmatter').get() as { count: number; bytes: number };\n\n const columns = (db.prepare('PRAGMA table_info(frontmatter)').all() as Array<{ name: string }>).map((r) => r.name).filter((name) => !INTERNAL_COLUMNS.has(name));\n const allFields = columns\n .map((name) => {\n const { n } = db.prepare(`SELECT COUNT(\"${name.split('\"').join('\"\"')}\") AS n FROM frontmatter`).get() as { n: number };\n return { field: name, coverage: n };\n })\n .sort((a, b) => (b.coverage as number) - (a.coverage as number)) as Row[];\n const fields = allFields.slice(0, 20);\n\n const hubs = featureEnabled(cfg, 'rank') ? (db.prepare(`SELECT f.\"path\" AS path, round(f.\"_rank\" * 100, 2) AS rank, content.title FROM frontmatter f JOIN content ON content.path = f.\"path\" WHERE f.\"_rank\" IS NOT NULL ORDER BY f.\"_rank\" DESC LIMIT 8`).all() as Row[]) : [];\n\n const recent = db.prepare(`SELECT \"path\", datetime(\"_mtime\" / 1000, 'unixepoch') AS modified FROM frontmatter ORDER BY \"_mtime\" DESC LIMIT 5`).all() as Row[];\n\n return { docs, fields, fieldsTotal: allFields.length, features: featureStates(cfg), hubs, recent };\n}\n\nexport interface Peek {\n path: string;\n tokens: number;\n frontmatter: Row;\n sections: Row[];\n outbound: string[];\n backlinks: string[];\n unresolved: string[];\n // Totals before truncation: a hub can have thousands of backlinks, and peek's whole\n // point is bounded output. Query the links table directly for the full list.\n outboundTotal: number;\n backlinksTotal: number;\n unresolvedTotal: number;\n off: FeatureName[]; // disabled features whose blocks are omitted (not empty)\n}\n\nconst PEEK_LINK_LIMIT = 20;\n\n// Layer 2: everything about one note except its prose -- frontmatter, outline with line\n// ranges + token estimates (so the follow-up Read is a range, not the file), links both ways.\nexport function peek(db: DatabaseSync, cfg: Config, pathArg: string): Peek {\n const paths = (db.prepare('SELECT \"path\" FROM frontmatter').all() as Array<{ path: string }>).map((r) => r.path);\n let path = paths.find((p) => p === pathArg);\n if (!path) {\n const base = posix.basename(pathArg).replace(/\\.md$/i, '').toLowerCase();\n const matches = paths.filter((p) => posix.basename(p).replace(/\\.md$/i, '').toLowerCase() === base);\n if (matches.length === 1) path = matches[0];\n else if (matches.length > 1) throw new SenseError('NOTE_AMBIGUOUS', `\"${pathArg}\" is ambiguous: ${matches.join(', ')}`);\n else throw new SenseError('NOTE_NOT_FOUND', `no note matches \"${pathArg}\"`);\n }\n\n const row = db.prepare('SELECT * FROM frontmatter WHERE \"path\" = ?').get(path) as Row;\n const frontmatter: Row = {};\n for (const [key, value] of Object.entries(row)) {\n if (!INTERNAL_COLUMNS.has(key) && value !== null) frontmatter[key] = value;\n }\n\n const sections = featureEnabled(cfg, 'sections') ? (db.prepare('SELECT level, heading, start_line, end_line, tokens FROM sections WHERE \"path\" = ? ORDER BY idx').all(path) as Row[]) : [];\n\n let outbound: string[] = [];\n let backlinks: string[] = [];\n let unresolved: string[] = [];\n let backlinksTotal = 0;\n if (featureEnabled(cfg, 'links')) {\n const out = db.prepare('SELECT target, dst FROM links WHERE src = ? ORDER BY target').all(path) as Array<{ target: string; dst: string | null }>;\n outbound = [...new Set(out.filter((l) => l.dst !== null).map((l) => l.dst as string))];\n unresolved = out.filter((l) => l.dst === null).map((l) => l.target);\n backlinksTotal = (db.prepare('SELECT COUNT(DISTINCT src) AS n FROM links WHERE dst = ?').get(path) as { n: number }).n;\n backlinks = (db.prepare('SELECT DISTINCT src FROM links WHERE dst = ? ORDER BY src LIMIT ?').all(path, PEEK_LINK_LIMIT) as Array<{ src: string }>).map((r) => r.src);\n }\n\n return {\n path,\n tokens: Math.ceil(((row._size as number) ?? 0) / 4),\n frontmatter,\n sections,\n outbound: outbound.slice(0, PEEK_LINK_LIMIT),\n backlinks,\n unresolved: unresolved.slice(0, PEEK_LINK_LIMIT),\n outboundTotal: outbound.length,\n backlinksTotal,\n unresolvedTotal: unresolved.length,\n off: (['sections', 'links'] as FeatureName[]).filter((name) => !featureEnabled(cfg, name)),\n };\n}\n"],"names":["find","mapTree","peek","WEIGHTED_BM25","RRF_K","db","cfg","terms","opts","hits","chunkLines","k","fetch","whereJoin","whereCond","matchSql","matchRows","candidates","edges","linked","nodes","seeds","ranked","vec","insert","path","c","where","linesCol","Math","max","prepare","all","Map","map","r","hit","forEach","i","set","score","via","featureEnabled","length","linkEdges","Set","flat","personalizedRank","filter","sort","a","b","slice","existing","get","has","semantic","semanticCandidates","lines","exec","run","INTERNAL_COLUMNS","docs","columns","name","allFields","n","split","join","field","coverage","fields","hubs","recent","fieldsTotal","features","featureStates","PEEK_LINK_LIMIT","pathArg","row","paths","p","base","posix","basename","replace","toLowerCase","matches","SenseError","frontmatter","Object","entries","key","value","sections","outbound","backlinks","unresolved","backlinksTotal","out","l","dst","target","src","tokens","ceil","_size","outboundTotal","unresolvedTotal","off"],"mappings":"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"}
|
package/dist/esm/cli.js
CHANGED
|
@@ -20,7 +20,7 @@ function packageVersion() {
|
|
|
20
20
|
return 'unknown';
|
|
21
21
|
}
|
|
22
22
|
function usage(name) {
|
|
23
|
-
return `usage: ${name} <name> [params...] [--format table|json] [--config path]\n` + ` ${name} query "<sql>" [params...]\n` + ` ${name} find "<terms>" [--where "<sql>"] [--k n]\n` + ` ${name} map\n` + ` ${name} peek <path>\n` + ` ${name} --list\n` + ` ${name} init\n` + ` ${name} watch [--force]\n` + ` ${name} status\n` + ` ${name} rebuild\n` + ` ${name} --version`;
|
|
23
|
+
return `usage: ${name} <name> [params...] [--format table|json] [--config path]\n` + ` ${name} query "<sql>" [params...]\n` + ` ${name} find "<terms>" [--where "<sql>"] [--k n] [--semantic]\n` + ` ${name} map\n` + ` ${name} peek <path>\n` + ` ${name} --list\n` + ` ${name} init\n` + ` ${name} watch [--force]\n` + ` ${name} status\n` + ` ${name} rebuild\n` + ` ${name} --version`;
|
|
24
24
|
}
|
|
25
25
|
// Thrown errors -> exit 1 with the message verbatim; usage errors exit 2 directly.
|
|
26
26
|
export default async function cli(argv, name) {
|
|
@@ -43,6 +43,10 @@ export default async function cli(argv, name) {
|
|
|
43
43
|
k: {
|
|
44
44
|
type: 'string'
|
|
45
45
|
},
|
|
46
|
+
semantic: {
|
|
47
|
+
type: 'boolean',
|
|
48
|
+
default: false
|
|
49
|
+
},
|
|
46
50
|
list: {
|
|
47
51
|
type: 'boolean',
|
|
48
52
|
default: false
|
package/dist/esm/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { parseArgs } from 'node:util';\nimport { COMMANDS } from './commands/index.ts';\nimport type { Ctx } from './commands/types.ts';\nimport { loadConfig, SUPPORTED_CONFIG_VERSION } from './config.ts';\n\n// Parsing and dispatch only. Commands live in src/commands/, one file each, lazy-loaded --\n// nothing tree- or dependency-heavy may be imported at the top of this file.\n\n// Works from dist/cjs and dist/esm alike: walk up past the dist type-marker package.json.\nfunction packageVersion(): string {\n const load = createRequire(import.meta.url);\n for (const rel of ['../package.json', '../../package.json', '../../../package.json']) {\n try {\n const pkg = load(rel) as { name?: string; version?: string };\n if (pkg.name === 'sensemaking' && pkg.version) return pkg.version;\n } catch {}\n }\n return 'unknown';\n}\n\nfunction usage(name: string): string {\n return (\n `usage: ${name} <name> [params...] [--format table|json] [--config path]\\n` +\n ` ${name} query \"<sql>\" [params...]\\n` +\n ` ${name} find \"<terms>\" [--where \"<sql>\"] [--k n]\\n` +\n ` ${name} map\\n` +\n ` ${name} peek <path>\\n` +\n ` ${name} --list\\n` +\n ` ${name} init\\n` +\n ` ${name} watch [--force]\\n` +\n ` ${name} status\\n` +\n ` ${name} rebuild\\n` +\n ` ${name} --version`\n );\n}\n\n// Thrown errors -> exit 1 with the message verbatim; usage errors exit 2 directly.\nexport default async function cli(argv: string[], name: string): Promise<void> {\n let values: Record<string, string | boolean | undefined>;\n let positionals: string[];\n try {\n ({ values, positionals } = parseArgs({\n args: argv,\n options: {\n format: { type: 'string', default: 'table' },\n config: { type: 'string' },\n where: { type: 'string' },\n k: { type: 'string' },\n list: { type: 'boolean', default: false },\n force: { type: 'boolean', default: false },\n version: { type: 'boolean', default: false, short: 'v' },\n help: { type: 'boolean', default: false, short: 'h' },\n },\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage(name));\n process.exit(2);\n }\n\n if (values.version) {\n console.log(`v${packageVersion()}`);\n return;\n }\n if (values.help) {\n console.log(usage(name));\n return;\n }\n\n const ctx: Ctx = {\n name,\n rest: positionals.slice(1),\n format: values.format === 'json' ? 'json' : 'table',\n values: values as Ctx['values'],\n resolveConfig() {\n const cfg = loadConfig(values.config as string | undefined);\n if (cfg.migratedFrom !== undefined) {\n console.warn(`${name}: migrated ${cfg.configPath} from config version ${cfg.migratedFrom} to ${SUPPORTED_CONFIG_VERSION}`);\n }\n return cfg;\n },\n usageError(message) {\n console.error(message);\n process.exit(2);\n },\n };\n\n try {\n if (values.list) {\n for (const queryName of Object.keys(ctx.resolveConfig().queries).sort()) console.log(queryName);\n return;\n }\n\n const [first, ...params] = positionals;\n if (!first) {\n console.error(usage(name));\n process.exit(2);\n }\n\n const load = COMMANDS[first];\n if (load) await (await load()).default(ctx);\n else (await import('./commands/named.ts')).default(ctx, first, params);\n } catch (err) {\n console.error((err as Error).message);\n process.exit(1);\n }\n}\n"],"names":["createRequire","parseArgs","COMMANDS","loadConfig","SUPPORTED_CONFIG_VERSION","packageVersion","load","url","rel","pkg","name","version","usage","cli","argv","values","positionals","args","options","format","type","default","config","where","k","list","force","short","help","allowPositionals","err","console","error","message","process","exit","log","ctx","rest","slice","resolveConfig","cfg","migratedFrom","undefined","warn","configPath","usageError","queryName","Object","keys","queries","sort","first","params"],"mappings":"AAAA,SAASA,aAAa,QAAQ,cAAc;AAC5C,SAASC,SAAS,QAAQ,YAAY;AACtC,SAASC,QAAQ,QAAQ,sBAAsB;AAE/C,SAASC,UAAU,EAAEC,wBAAwB,QAAQ,cAAc;AAEnE,2FAA2F;AAC3F,6EAA6E;AAE7E,0FAA0F;AAC1F,SAASC;IACP,MAAMC,OAAON,cAAc,YAAYO,GAAG;IAC1C,KAAK,MAAMC,OAAO;QAAC;QAAmB;QAAsB;KAAwB,CAAE;QACpF,IAAI;YACF,MAAMC,MAAMH,KAAKE;YACjB,IAAIC,IAAIC,IAAI,KAAK,iBAAiBD,IAAIE,OAAO,EAAE,OAAOF,IAAIE,OAAO;QACnE,EAAE,OAAM,CAAC;IACX;IACA,OAAO;AACT;AAEA,SAASC,MAAMF,IAAY;IACzB,OACE,CAAC,OAAO,EAAEA,KAAK,2DAA2D,CAAC,GAC3E,CAAC,OAAO,EAAEA,KAAK,4BAA4B,CAAC,GAC5C,CAAC,OAAO,EAAEA,KAAK,
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { parseArgs } from 'node:util';\nimport { COMMANDS } from './commands/index.ts';\nimport type { Ctx } from './commands/types.ts';\nimport { loadConfig, SUPPORTED_CONFIG_VERSION } from './config.ts';\n\n// Parsing and dispatch only. Commands live in src/commands/, one file each, lazy-loaded --\n// nothing tree- or dependency-heavy may be imported at the top of this file.\n\n// Works from dist/cjs and dist/esm alike: walk up past the dist type-marker package.json.\nfunction packageVersion(): string {\n const load = createRequire(import.meta.url);\n for (const rel of ['../package.json', '../../package.json', '../../../package.json']) {\n try {\n const pkg = load(rel) as { name?: string; version?: string };\n if (pkg.name === 'sensemaking' && pkg.version) return pkg.version;\n } catch {}\n }\n return 'unknown';\n}\n\nfunction usage(name: string): string {\n return (\n `usage: ${name} <name> [params...] [--format table|json] [--config path]\\n` +\n ` ${name} query \"<sql>\" [params...]\\n` +\n ` ${name} find \"<terms>\" [--where \"<sql>\"] [--k n] [--semantic]\\n` +\n ` ${name} map\\n` +\n ` ${name} peek <path>\\n` +\n ` ${name} --list\\n` +\n ` ${name} init\\n` +\n ` ${name} watch [--force]\\n` +\n ` ${name} status\\n` +\n ` ${name} rebuild\\n` +\n ` ${name} --version`\n );\n}\n\n// Thrown errors -> exit 1 with the message verbatim; usage errors exit 2 directly.\nexport default async function cli(argv: string[], name: string): Promise<void> {\n let values: Record<string, string | boolean | undefined>;\n let positionals: string[];\n try {\n ({ values, positionals } = parseArgs({\n args: argv,\n options: {\n format: { type: 'string', default: 'table' },\n config: { type: 'string' },\n where: { type: 'string' },\n k: { type: 'string' },\n semantic: { type: 'boolean', default: false },\n list: { type: 'boolean', default: false },\n force: { type: 'boolean', default: false },\n version: { type: 'boolean', default: false, short: 'v' },\n help: { type: 'boolean', default: false, short: 'h' },\n },\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage(name));\n process.exit(2);\n }\n\n if (values.version) {\n console.log(`v${packageVersion()}`);\n return;\n }\n if (values.help) {\n console.log(usage(name));\n return;\n }\n\n const ctx: Ctx = {\n name,\n rest: positionals.slice(1),\n format: values.format === 'json' ? 'json' : 'table',\n values: values as Ctx['values'],\n resolveConfig() {\n const cfg = loadConfig(values.config as string | undefined);\n if (cfg.migratedFrom !== undefined) {\n console.warn(`${name}: migrated ${cfg.configPath} from config version ${cfg.migratedFrom} to ${SUPPORTED_CONFIG_VERSION}`);\n }\n return cfg;\n },\n usageError(message) {\n console.error(message);\n process.exit(2);\n },\n };\n\n try {\n if (values.list) {\n for (const queryName of Object.keys(ctx.resolveConfig().queries).sort()) console.log(queryName);\n return;\n }\n\n const [first, ...params] = positionals;\n if (!first) {\n console.error(usage(name));\n process.exit(2);\n }\n\n const load = COMMANDS[first];\n if (load) await (await load()).default(ctx);\n else (await import('./commands/named.ts')).default(ctx, first, params);\n } catch (err) {\n console.error((err as Error).message);\n process.exit(1);\n }\n}\n"],"names":["createRequire","parseArgs","COMMANDS","loadConfig","SUPPORTED_CONFIG_VERSION","packageVersion","load","url","rel","pkg","name","version","usage","cli","argv","values","positionals","args","options","format","type","default","config","where","k","semantic","list","force","short","help","allowPositionals","err","console","error","message","process","exit","log","ctx","rest","slice","resolveConfig","cfg","migratedFrom","undefined","warn","configPath","usageError","queryName","Object","keys","queries","sort","first","params"],"mappings":"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"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { printRows } from '../output.js';
|
|
2
2
|
import { find } from '../verbs.js';
|
|
3
3
|
import { withDb } from './shared.js';
|
|
4
|
-
const findCmd = (ctx)=>{
|
|
4
|
+
const findCmd = async (ctx)=>{
|
|
5
5
|
const [terms] = ctx.rest;
|
|
6
|
-
if (!terms) ctx.usageError(`usage: ${ctx.name} find "<terms>" [--where "<sql>"] [--k n]`);
|
|
6
|
+
if (!terms) ctx.usageError(`usage: ${ctx.name} find "<terms>" [--where "<sql>"] [--k n] [--semantic]`);
|
|
7
7
|
const k = ctx.values.k === undefined ? undefined : Number.parseInt(ctx.values.k, 10);
|
|
8
8
|
if (ctx.values.k !== undefined && !Number.isInteger(k)) ctx.usageError(`--k expects an integer, got "${ctx.values.k}"`);
|
|
9
|
-
withDb(ctx, (db, cfg)=>printRows(find(db, cfg, terms, {
|
|
9
|
+
await withDb(ctx, async (db, cfg)=>printRows(await find(db, cfg, terms, {
|
|
10
10
|
k,
|
|
11
|
-
where: ctx.values.where
|
|
11
|
+
where: ctx.values.where,
|
|
12
|
+
semantic: ctx.values.semantic
|
|
12
13
|
}), ctx.format));
|
|
13
14
|
};
|
|
14
15
|
export default findCmd;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/find.ts"],"sourcesContent":["import { printRows } from '../output.ts';\nimport { find } from '../verbs.ts';\nimport { withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst findCmd: Command = (ctx) => {\n const [terms] = ctx.rest;\n if (!terms) ctx.usageError(`usage: ${ctx.name} find \"<terms>\" [--where \"<sql>\"] [--k n]`);\n const k = ctx.values.k === undefined ? undefined : Number.parseInt(ctx.values.k, 10);\n if (ctx.values.k !== undefined && !Number.isInteger(k)) ctx.usageError(`--k expects an integer, got \"${ctx.values.k}\"`);\n withDb(ctx, (db, cfg) => printRows(find(db, cfg, terms, { k, where: ctx.values.where }), ctx.format));\n};\nexport default findCmd;\n"],"names":["printRows","find","withDb","findCmd","ctx","terms","rest","usageError","name","k","values","undefined","Number","parseInt","isInteger","db","cfg","where","format"],"mappings":"AAAA,SAASA,SAAS,QAAQ,eAAe;AACzC,SAASC,IAAI,QAAQ,cAAc;AACnC,SAASC,MAAM,QAAQ,cAAc;AAGrC,MAAMC,UAAmB,
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/find.ts"],"sourcesContent":["import { printRows } from '../output.ts';\nimport { find } from '../verbs.ts';\nimport { withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst findCmd: Command = async (ctx) => {\n const [terms] = ctx.rest;\n if (!terms) ctx.usageError(`usage: ${ctx.name} find \"<terms>\" [--where \"<sql>\"] [--k n] [--semantic]`);\n const k = ctx.values.k === undefined ? undefined : Number.parseInt(ctx.values.k, 10);\n if (ctx.values.k !== undefined && !Number.isInteger(k)) ctx.usageError(`--k expects an integer, got \"${ctx.values.k}\"`);\n await withDb(ctx, async (db, cfg) => printRows(await find(db, cfg, terms, { k, where: ctx.values.where, semantic: ctx.values.semantic }), ctx.format));\n};\nexport default findCmd;\n"],"names":["printRows","find","withDb","findCmd","ctx","terms","rest","usageError","name","k","values","undefined","Number","parseInt","isInteger","db","cfg","where","semantic","format"],"mappings":"AAAA,SAASA,SAAS,QAAQ,eAAe;AACzC,SAASC,IAAI,QAAQ,cAAc;AACnC,SAASC,MAAM,QAAQ,cAAc;AAGrC,MAAMC,UAAmB,OAAOC;IAC9B,MAAM,CAACC,MAAM,GAAGD,IAAIE,IAAI;IACxB,IAAI,CAACD,OAAOD,IAAIG,UAAU,CAAC,CAAC,OAAO,EAAEH,IAAII,IAAI,CAAC,sDAAsD,CAAC;IACrG,MAAMC,IAAIL,IAAIM,MAAM,CAACD,CAAC,KAAKE,YAAYA,YAAYC,OAAOC,QAAQ,CAACT,IAAIM,MAAM,CAACD,CAAC,EAAE;IACjF,IAAIL,IAAIM,MAAM,CAACD,CAAC,KAAKE,aAAa,CAACC,OAAOE,SAAS,CAACL,IAAIL,IAAIG,UAAU,CAAC,CAAC,6BAA6B,EAAEH,IAAIM,MAAM,CAACD,CAAC,CAAC,CAAC,CAAC;IACtH,MAAMP,OAAOE,KAAK,OAAOW,IAAIC,MAAQhB,UAAU,MAAMC,KAAKc,IAAIC,KAAKX,OAAO;YAAEI;YAAGQ,OAAOb,IAAIM,MAAM,CAACO,KAAK;YAAEC,UAAUd,IAAIM,MAAM,CAACQ,QAAQ;QAAC,IAAId,IAAIe,MAAM;AACtJ;AACA,eAAehB,QAAQ"}
|
package/dist/esm/commands/map.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { renderMap } from '../output.js';
|
|
2
2
|
import { mapTree } from '../verbs.js';
|
|
3
3
|
import { withDb } from './shared.js';
|
|
4
|
-
const map = (ctx)=>{
|
|
5
|
-
withDb(ctx, (db, cfg)=>{
|
|
4
|
+
const map = (ctx)=>withDb(ctx, (db, cfg)=>{
|
|
6
5
|
const result = mapTree(db, cfg);
|
|
7
6
|
console.log(ctx.format === 'json' ? JSON.stringify(result, null, 2) : renderMap(result));
|
|
8
7
|
});
|
|
9
|
-
};
|
|
10
8
|
export default map;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/map.ts"],"sourcesContent":["import { renderMap } from '../output.ts';\nimport { mapTree } from '../verbs.ts';\nimport { withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst map: Command = (ctx)
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/map.ts"],"sourcesContent":["import { renderMap } from '../output.ts';\nimport { mapTree } from '../verbs.ts';\nimport { withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst map: Command = (ctx) =>\n withDb(ctx, (db, cfg) => {\n const result = mapTree(db, cfg);\n console.log(ctx.format === 'json' ? JSON.stringify(result, null, 2) : renderMap(result));\n });\nexport default map;\n"],"names":["renderMap","mapTree","withDb","map","ctx","db","cfg","result","console","log","format","JSON","stringify"],"mappings":"AAAA,SAASA,SAAS,QAAQ,eAAe;AACzC,SAASC,OAAO,QAAQ,cAAc;AACtC,SAASC,MAAM,QAAQ,cAAc;AAGrC,MAAMC,MAAe,CAACC,MACpBF,OAAOE,KAAK,CAACC,IAAIC;QACf,MAAMC,SAASN,QAAQI,IAAIC;QAC3BE,QAAQC,GAAG,CAACL,IAAIM,MAAM,KAAK,SAASC,KAAKC,SAAS,CAACL,QAAQ,MAAM,KAAKP,UAAUO;IAClF;AACF,eAAeJ,IAAI"}
|
|
@@ -4,7 +4,7 @@ import { withDb } from './shared.js';
|
|
|
4
4
|
const peekCmd = (ctx)=>{
|
|
5
5
|
const [pathArg] = ctx.rest;
|
|
6
6
|
if (!pathArg) ctx.usageError(`usage: ${ctx.name} peek <path>`);
|
|
7
|
-
withDb(ctx, (db, cfg)=>{
|
|
7
|
+
return withDb(ctx, (db, cfg)=>{
|
|
8
8
|
const result = peek(db, cfg, pathArg);
|
|
9
9
|
console.log(ctx.format === 'json' ? JSON.stringify(result, null, 2) : renderPeek(result));
|
|
10
10
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/peek.ts"],"sourcesContent":["import { renderPeek } from '../output.ts';\nimport { peek } from '../verbs.ts';\nimport { withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst peekCmd: Command = (ctx) => {\n const [pathArg] = ctx.rest;\n if (!pathArg) ctx.usageError(`usage: ${ctx.name} peek <path>`);\n withDb(ctx, (db, cfg) => {\n const result = peek(db, cfg, pathArg);\n console.log(ctx.format === 'json' ? JSON.stringify(result, null, 2) : renderPeek(result));\n });\n};\nexport default peekCmd;\n"],"names":["renderPeek","peek","withDb","peekCmd","ctx","pathArg","rest","usageError","name","db","cfg","result","console","log","format","JSON","stringify"],"mappings":"AAAA,SAASA,UAAU,QAAQ,eAAe;AAC1C,SAASC,IAAI,QAAQ,cAAc;AACnC,SAASC,MAAM,QAAQ,cAAc;AAGrC,MAAMC,UAAmB,CAACC;IACxB,MAAM,CAACC,QAAQ,GAAGD,IAAIE,IAAI;IAC1B,IAAI,CAACD,SAASD,IAAIG,UAAU,CAAC,CAAC,OAAO,EAAEH,IAAII,IAAI,CAAC,YAAY,CAAC;
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/peek.ts"],"sourcesContent":["import { renderPeek } from '../output.ts';\nimport { peek } from '../verbs.ts';\nimport { withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst peekCmd: Command = (ctx) => {\n const [pathArg] = ctx.rest;\n if (!pathArg) ctx.usageError(`usage: ${ctx.name} peek <path>`);\n return withDb(ctx, (db, cfg) => {\n const result = peek(db, cfg, pathArg);\n console.log(ctx.format === 'json' ? JSON.stringify(result, null, 2) : renderPeek(result));\n });\n};\nexport default peekCmd;\n"],"names":["renderPeek","peek","withDb","peekCmd","ctx","pathArg","rest","usageError","name","db","cfg","result","console","log","format","JSON","stringify"],"mappings":"AAAA,SAASA,UAAU,QAAQ,eAAe;AAC1C,SAASC,IAAI,QAAQ,cAAc;AACnC,SAASC,MAAM,QAAQ,cAAc;AAGrC,MAAMC,UAAmB,CAACC;IACxB,MAAM,CAACC,QAAQ,GAAGD,IAAIE,IAAI;IAC1B,IAAI,CAACD,SAASD,IAAIG,UAAU,CAAC,CAAC,OAAO,EAAEH,IAAII,IAAI,CAAC,YAAY,CAAC;IAC7D,OAAON,OAAOE,KAAK,CAACK,IAAIC;QACtB,MAAMC,SAASV,KAAKQ,IAAIC,KAAKL;QAC7BO,QAAQC,GAAG,CAACT,IAAIU,MAAM,KAAK,SAASC,KAAKC,SAAS,CAACL,QAAQ,MAAM,KAAKX,WAAWW;IACnF;AACF;AACA,eAAeR,QAAQ"}
|
|
@@ -2,5 +2,5 @@ import type { ResolvedConfig } from '../config.js';
|
|
|
2
2
|
import type { OpenResult } from '../db.js';
|
|
3
3
|
import type { Ctx } from './types.js';
|
|
4
4
|
export declare function printWarnings(warnings: string[]): void;
|
|
5
|
-
export declare function withDb(ctx: Ctx, fn: (db: OpenResult['db'], cfg: ResolvedConfig) => void): void
|
|
5
|
+
export declare function withDb(ctx: Ctx, fn: (db: OpenResult['db'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void>;
|
|
6
6
|
export declare function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: 'table' | 'json', label: string): void;
|
|
@@ -4,12 +4,12 @@ import { printRows } from '../output.js';
|
|
|
4
4
|
export function printWarnings(warnings) {
|
|
5
5
|
for (const w of warnings)console.warn(w);
|
|
6
6
|
}
|
|
7
|
-
export function withDb(ctx, fn) {
|
|
7
|
+
export async function withDb(ctx, fn) {
|
|
8
8
|
const cfg = ctx.resolveConfig();
|
|
9
9
|
const { db, warnings } = open(cfg);
|
|
10
10
|
printWarnings(warnings);
|
|
11
11
|
try {
|
|
12
|
-
fn(db, cfg);
|
|
12
|
+
await fn(db, cfg);
|
|
13
13
|
} finally{
|
|
14
14
|
db.close();
|
|
15
15
|
}
|