sensemaking 0.9.5 → 0.10.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 +24 -18
- package/dist/cjs/cli/check.js +7 -13
- package/dist/cjs/cli/check.js.map +1 -1
- package/dist/cjs/cli/download.d.cts +3 -0
- package/dist/cjs/cli/download.d.ts +3 -0
- package/dist/cjs/cli/download.js +214 -0
- package/dist/cjs/cli/download.js.map +1 -0
- package/dist/cjs/cli/index.d.cts +6 -3
- package/dist/cjs/cli/index.d.ts +6 -3
- package/dist/cjs/cli/index.js +23 -5
- package/dist/cjs/cli/index.js.map +1 -1
- package/dist/cjs/cli/init.js +4 -1
- package/dist/cjs/cli/init.js.map +1 -1
- package/dist/cjs/cli/map.js +2 -2
- package/dist/cjs/cli/map.js.map +1 -1
- package/dist/cjs/cli/named.js +10 -18
- package/dist/cjs/cli/named.js.map +1 -1
- package/dist/cjs/cli/path.d.cts +3 -0
- package/dist/cjs/cli/path.d.ts +3 -0
- package/dist/cjs/cli/path.js +161 -0
- package/dist/cjs/cli/path.js.map +1 -0
- package/dist/cjs/cli/peek.js +3 -2
- package/dist/cjs/cli/peek.js.map +1 -1
- package/dist/cjs/cli/related.d.cts +3 -0
- package/dist/cjs/cli/related.d.ts +3 -0
- package/dist/cjs/cli/related.js +279 -0
- package/dist/cjs/cli/related.js.map +1 -0
- package/dist/cjs/cli/search.js +3 -7
- package/dist/cjs/cli/search.js.map +1 -1
- package/dist/cjs/cli/shared.d.cts +3 -1
- package/dist/cjs/cli/shared.d.ts +3 -1
- package/dist/cjs/cli/shared.js +28 -5
- package/dist/cjs/cli/shared.js.map +1 -1
- package/dist/cjs/cli/sql.d.cts +3 -0
- package/dist/cjs/cli/sql.d.ts +3 -0
- package/dist/cjs/cli/{query.js → sql.js} +4 -4
- package/dist/cjs/cli/sql.js.map +1 -0
- package/dist/cjs/cli/status.js +9 -2
- package/dist/cjs/cli/status.js.map +1 -1
- package/dist/cjs/cli.js +14 -15
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/commands.d.cts +12 -4
- package/dist/cjs/commands.d.ts +12 -4
- package/dist/cjs/commands.js +138 -58
- package/dist/cjs/commands.js.map +1 -1
- package/dist/cjs/config.d.cts +6 -4
- package/dist/cjs/config.d.ts +6 -4
- package/dist/cjs/config.js +137 -58
- package/dist/cjs/config.js.map +1 -1
- package/dist/cjs/db.js +14 -34
- 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 +248 -54
- package/dist/cjs/features/embed.js.map +1 -1
- package/dist/cjs/features/links.js +7 -16
- package/dist/cjs/features/links.js.map +1 -1
- package/dist/cjs/features/rank.js +2 -6
- package/dist/cjs/features/rank.js.map +1 -1
- package/dist/cjs/index.d.cts +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/output.js +11 -14
- package/dist/cjs/output.js.map +1 -1
- package/dist/cjs/progress.js +2 -4
- package/dist/cjs/progress.js.map +1 -1
- package/dist/cjs/scan.d.cts +1 -0
- package/dist/cjs/scan.d.ts +1 -0
- package/dist/cjs/scan.js +67 -32
- package/dist/cjs/scan.js.map +1 -1
- package/dist/cjs/search-error.js +4 -6
- package/dist/cjs/search-error.js.map +1 -1
- package/dist/cjs/traverse.d.cts +8 -0
- package/dist/cjs/traverse.d.ts +8 -0
- package/dist/cjs/traverse.js +97 -0
- package/dist/cjs/traverse.js.map +1 -0
- package/dist/esm/cli/check.js +7 -13
- package/dist/esm/cli/check.js.map +1 -1
- package/dist/esm/cli/download.d.ts +3 -0
- package/dist/esm/cli/download.js +27 -0
- package/dist/esm/cli/download.js.map +1 -0
- package/dist/esm/cli/index.d.ts +6 -3
- package/dist/esm/cli/index.js +13 -7
- package/dist/esm/cli/index.js.map +1 -1
- package/dist/esm/cli/init.js +4 -1
- package/dist/esm/cli/init.js.map +1 -1
- package/dist/esm/cli/map.js +3 -2
- package/dist/esm/cli/map.js.map +1 -1
- package/dist/esm/cli/named.js +10 -16
- package/dist/esm/cli/named.js.map +1 -1
- package/dist/esm/cli/path.d.ts +3 -0
- package/dist/esm/cli/path.js +51 -0
- package/dist/esm/cli/path.js.map +1 -0
- package/dist/esm/cli/peek.js +4 -2
- package/dist/esm/cli/peek.js.map +1 -1
- package/dist/esm/cli/related.d.ts +3 -0
- package/dist/esm/cli/related.js +26 -0
- package/dist/esm/cli/related.js.map +1 -0
- package/dist/esm/cli/search.js +2 -5
- package/dist/esm/cli/search.js.map +1 -1
- package/dist/esm/cli/shared.d.ts +3 -1
- package/dist/esm/cli/shared.js +28 -5
- package/dist/esm/cli/shared.js.map +1 -1
- package/dist/esm/cli/sql.d.ts +3 -0
- package/dist/esm/cli/{query.js → sql.js} +4 -4
- package/dist/esm/cli/sql.js.map +1 -0
- package/dist/esm/cli/status.js +8 -1
- package/dist/esm/cli/status.js.map +1 -1
- package/dist/esm/cli.js +13 -10
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/commands.d.ts +12 -4
- package/dist/esm/commands.js +111 -68
- package/dist/esm/commands.js.map +1 -1
- package/dist/esm/config.d.ts +6 -4
- package/dist/esm/config.js +126 -75
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/db.js +16 -38
- 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 +110 -35
- package/dist/esm/features/embed.js.map +1 -1
- package/dist/esm/features/links.js +8 -17
- package/dist/esm/features/links.js.map +1 -1
- package/dist/esm/features/rank.js +2 -6
- package/dist/esm/features/rank.js.map +1 -1
- package/dist/esm/features/types.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/output.js +13 -16
- package/dist/esm/output.js.map +1 -1
- package/dist/esm/progress.js +2 -4
- package/dist/esm/progress.js.map +1 -1
- package/dist/esm/scan.d.ts +1 -0
- package/dist/esm/scan.js +41 -34
- package/dist/esm/scan.js.map +1 -1
- package/dist/esm/search-error.js +4 -6
- package/dist/esm/search-error.js.map +1 -1
- package/dist/esm/traverse.d.ts +8 -0
- package/dist/esm/traverse.js +71 -0
- package/dist/esm/traverse.js.map +1 -0
- package/package.json +7 -3
- package/schema.json +12 -16
- package/skills/sense/EXAMPLES.md +8 -8
- package/skills/sense/SKILL.md +41 -19
- package/skills/sense-setup/EXAMPLES.md +24 -21
- package/skills/sense-setup/SKILL.md +9 -9
- package/dist/cjs/cli/query.d.cts +0 -3
- package/dist/cjs/cli/query.d.ts +0 -3
- package/dist/cjs/cli/query.js.map +0 -1
- package/dist/esm/cli/query.d.ts +0 -3
- package/dist/esm/cli/query.js.map +0 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
2
|
+
interface FindPathOptions {
|
|
3
|
+
directed?: boolean;
|
|
4
|
+
maxDepth?: number;
|
|
5
|
+
allowed?: Set<string>;
|
|
6
|
+
}
|
|
7
|
+
export declare function findPath(db: DatabaseSync, from: string, to: string, opts?: FindPathOptions): string[] | null;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// Frontier-by-frontier BFS through a temp visited table, one indexed anti-join per ring: a
|
|
2
|
+
// local question touches a neighborhood, never the whole edge list.
|
|
3
|
+
"use strict";
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
Object.defineProperty(exports, "findPath", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function() {
|
|
10
|
+
return findPath;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
function _array_like_to_array(arr, len) {
|
|
14
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
15
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
16
|
+
return arr2;
|
|
17
|
+
}
|
|
18
|
+
function _array_without_holes(arr) {
|
|
19
|
+
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
20
|
+
}
|
|
21
|
+
function _iterable_to_array(iter) {
|
|
22
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
23
|
+
}
|
|
24
|
+
function _non_iterable_spread() {
|
|
25
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
26
|
+
}
|
|
27
|
+
function _to_consumable_array(arr) {
|
|
28
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
29
|
+
}
|
|
30
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
31
|
+
if (!o) return;
|
|
32
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
33
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
34
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
35
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
36
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
37
|
+
}
|
|
38
|
+
function resetVisited(db) {
|
|
39
|
+
db.exec('DROP TABLE IF EXISTS temp.visited');
|
|
40
|
+
db.exec('CREATE TEMP TABLE visited (path TEXT PRIMARY KEY, depth INTEGER NOT NULL, pred TEXT)');
|
|
41
|
+
}
|
|
42
|
+
// Materializes the caller-resolved scope Set into a temp table so it joins like any other
|
|
43
|
+
// indexed column. `extra`, when given, is always in scope -- findPath's `to` endpoint.
|
|
44
|
+
function setupAllowed(db, allowed, extra) {
|
|
45
|
+
db.exec('DROP TABLE IF EXISTS temp.allowed_nodes');
|
|
46
|
+
db.exec('CREATE TEMP TABLE allowed_nodes (path TEXT PRIMARY KEY)');
|
|
47
|
+
db.prepare('INSERT INTO allowed_nodes SELECT DISTINCT value FROM json_each(?1)').run(JSON.stringify(_to_consumable_array(allowed)));
|
|
48
|
+
if (extra !== undefined) db.prepare('INSERT OR IGNORE INTO allowed_nodes VALUES (?)').run(extra);
|
|
49
|
+
}
|
|
50
|
+
// Only resolved links (dst IS NOT NULL) are followed, in either direction.
|
|
51
|
+
function candidateSelect(direction) {
|
|
52
|
+
var forward = 'SELECT l.dst AS path, l.src AS pred FROM links l JOIN visited v ON v.path = l.src AND v.depth = ?1 WHERE l.dst IS NOT NULL';
|
|
53
|
+
var reverse = 'SELECT l.src AS path, l.dst AS pred FROM links l JOIN visited v ON v.path = l.dst AND v.depth = ?1 WHERE l.dst IS NOT NULL';
|
|
54
|
+
if (direction === 'forward') return forward;
|
|
55
|
+
if (direction === 'reverse') return reverse;
|
|
56
|
+
return "".concat(forward, " UNION ALL ").concat(reverse);
|
|
57
|
+
}
|
|
58
|
+
// One ring: candidates adjacent to the previous ring's frontier (?1), anti-joined against
|
|
59
|
+
// everything already visited, optionally filtered to the allowed set, capped (?3) and
|
|
60
|
+
// inserted at the new depth (?2). RETURNING hands back exactly what this ring newly reached.
|
|
61
|
+
function ringSql(direction, hasAllowed) {
|
|
62
|
+
return "\nINSERT INTO visited (path, depth, pred)\nSELECT cand.path, ?2, MIN(cand.pred)\nFROM (".concat(candidateSelect(direction), ") cand\nWHERE NOT EXISTS (SELECT 1 FROM visited v2 WHERE v2.path = cand.path)\n").concat(hasAllowed ? 'AND EXISTS (SELECT 1 FROM allowed_nodes a WHERE a.path = cand.path)' : '', "\nGROUP BY cand.path\nORDER BY cand.path\nLIMIT ?3\nRETURNING path");
|
|
63
|
+
}
|
|
64
|
+
function reconstructPath(db, to) {
|
|
65
|
+
var lookup = db.prepare('SELECT pred FROM visited WHERE path = ?');
|
|
66
|
+
var path = [];
|
|
67
|
+
var cur = to;
|
|
68
|
+
while(cur !== null){
|
|
69
|
+
path.push(cur);
|
|
70
|
+
var row = lookup.get(cur);
|
|
71
|
+
cur = row ? row.pred : null;
|
|
72
|
+
}
|
|
73
|
+
return path.reverse();
|
|
74
|
+
}
|
|
75
|
+
function findPath(db, from, to) {
|
|
76
|
+
var opts = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : {};
|
|
77
|
+
var _opts_maxDepth;
|
|
78
|
+
if (from === to) return [
|
|
79
|
+
from
|
|
80
|
+
];
|
|
81
|
+
var direction = opts.directed ? 'forward' : 'both';
|
|
82
|
+
var maxDepth = (_opts_maxDepth = opts.maxDepth) !== null && _opts_maxDepth !== void 0 ? _opts_maxDepth : Infinity;
|
|
83
|
+
if (maxDepth <= 0) return null;
|
|
84
|
+
resetVisited(db);
|
|
85
|
+
db.prepare('INSERT INTO visited (path, depth, pred) VALUES (?, 0, NULL)').run(from);
|
|
86
|
+
if (opts.allowed) setupAllowed(db, opts.allowed, to);
|
|
87
|
+
var stmt = db.prepare(ringSql(direction, !!opts.allowed));
|
|
88
|
+
for(var ring = 1; ring <= maxDepth; ring++){
|
|
89
|
+
var rows = stmt.all(ring - 1, ring, -1);
|
|
90
|
+
if (rows.length === 0) break;
|
|
91
|
+
if (rows.some(function(row) {
|
|
92
|
+
return row.path === to;
|
|
93
|
+
})) return reconstructPath(db, to);
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
/* 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; }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/traverse.ts"],"sourcesContent":["// Frontier-by-frontier BFS through a temp visited table, one indexed anti-join per ring: a\n// local question touches a neighborhood, never the whole edge list.\nimport type { DatabaseSync } from 'node:sqlite';\n\ntype Direction = 'forward' | 'reverse' | 'both';\n\ninterface FindPathOptions {\n directed?: boolean;\n maxDepth?: number;\n allowed?: Set<string>;\n}\n\nfunction resetVisited(db: DatabaseSync): void {\n db.exec('DROP TABLE IF EXISTS temp.visited');\n db.exec('CREATE TEMP TABLE visited (path TEXT PRIMARY KEY, depth INTEGER NOT NULL, pred TEXT)');\n}\n\n// Materializes the caller-resolved scope Set into a temp table so it joins like any other\n// indexed column. `extra`, when given, is always in scope -- findPath's `to` endpoint.\nfunction setupAllowed(db: DatabaseSync, allowed: Set<string>, extra?: string): void {\n db.exec('DROP TABLE IF EXISTS temp.allowed_nodes');\n db.exec('CREATE TEMP TABLE allowed_nodes (path TEXT PRIMARY KEY)');\n db.prepare('INSERT INTO allowed_nodes SELECT DISTINCT value FROM json_each(?1)').run(JSON.stringify([...allowed]));\n if (extra !== undefined) db.prepare('INSERT OR IGNORE INTO allowed_nodes VALUES (?)').run(extra);\n}\n\n// Only resolved links (dst IS NOT NULL) are followed, in either direction.\nfunction candidateSelect(direction: Direction): string {\n const forward = 'SELECT l.dst AS path, l.src AS pred FROM links l JOIN visited v ON v.path = l.src AND v.depth = ?1 WHERE l.dst IS NOT NULL';\n const reverse = 'SELECT l.src AS path, l.dst AS pred FROM links l JOIN visited v ON v.path = l.dst AND v.depth = ?1 WHERE l.dst IS NOT NULL';\n if (direction === 'forward') return forward;\n if (direction === 'reverse') return reverse;\n return `${forward} UNION ALL ${reverse}`;\n}\n\n// One ring: candidates adjacent to the previous ring's frontier (?1), anti-joined against\n// everything already visited, optionally filtered to the allowed set, capped (?3) and\n// inserted at the new depth (?2). RETURNING hands back exactly what this ring newly reached.\nfunction ringSql(direction: Direction, hasAllowed: boolean): string {\n return `\nINSERT INTO visited (path, depth, pred)\nSELECT cand.path, ?2, MIN(cand.pred)\nFROM (${candidateSelect(direction)}) cand\nWHERE NOT EXISTS (SELECT 1 FROM visited v2 WHERE v2.path = cand.path)\n${hasAllowed ? 'AND EXISTS (SELECT 1 FROM allowed_nodes a WHERE a.path = cand.path)' : ''}\nGROUP BY cand.path\nORDER BY cand.path\nLIMIT ?3\nRETURNING path`;\n}\n\nfunction reconstructPath(db: DatabaseSync, to: string): string[] {\n const lookup = db.prepare('SELECT pred FROM visited WHERE path = ?');\n const path: string[] = [];\n let cur: string | null = to;\n while (cur !== null) {\n path.push(cur);\n const row = lookup.get(cur) as { pred: string | null } | undefined;\n cur = row ? row.pred : null;\n }\n return path.reverse();\n}\n\n// One BFS from `from`, tracking a predecessor per node. Undirected by default, matching\n// personalizedRank; null when `to` is unreached within `maxDepth`.\nexport function findPath(db: DatabaseSync, from: string, to: string, opts: FindPathOptions = {}): string[] | null {\n if (from === to) return [from];\n\n const direction: Direction = opts.directed ? 'forward' : 'both';\n const maxDepth = opts.maxDepth ?? Infinity;\n if (maxDepth <= 0) return null;\n\n resetVisited(db);\n db.prepare('INSERT INTO visited (path, depth, pred) VALUES (?, 0, NULL)').run(from);\n if (opts.allowed) setupAllowed(db, opts.allowed, to);\n\n const stmt = db.prepare(ringSql(direction, !!opts.allowed));\n for (let ring = 1; ring <= maxDepth; ring++) {\n const rows = stmt.all(ring - 1, ring, -1) as Array<{ path: string }>;\n if (rows.length === 0) break;\n if (rows.some((row) => row.path === to)) return reconstructPath(db, to);\n }\n return null;\n}\n"],"names":["findPath","resetVisited","db","exec","setupAllowed","allowed","extra","prepare","run","JSON","stringify","undefined","candidateSelect","direction","forward","reverse","ringSql","hasAllowed","reconstructPath","to","lookup","path","cur","push","row","get","pred","from","opts","directed","maxDepth","Infinity","stmt","ring","rows","all","length","some"],"mappings":"AAAA,2FAA2F;AAC3F,oEAAoE;;;;;+BAgEpDA;;;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AArDhB,SAASC,aAAaC,EAAgB;IACpCA,GAAGC,IAAI,CAAC;IACRD,GAAGC,IAAI,CAAC;AACV;AAEA,0FAA0F;AAC1F,uFAAuF;AACvF,SAASC,aAAaF,EAAgB,EAAEG,OAAoB,EAAEC,KAAc;IAC1EJ,GAAGC,IAAI,CAAC;IACRD,GAAGC,IAAI,CAAC;IACRD,GAAGK,OAAO,CAAC,sEAAsEC,GAAG,CAACC,KAAKC,SAAS,CAAE,qBAAGL;IACxG,IAAIC,UAAUK,WAAWT,GAAGK,OAAO,CAAC,kDAAkDC,GAAG,CAACF;AAC5F;AAEA,2EAA2E;AAC3E,SAASM,gBAAgBC,SAAoB;IAC3C,IAAMC,UAAU;IAChB,IAAMC,UAAU;IAChB,IAAIF,cAAc,WAAW,OAAOC;IACpC,IAAID,cAAc,WAAW,OAAOE;IACpC,OAAO,AAAC,GAAuBA,OAArBD,SAAQ,eAAqB,OAARC;AACjC;AAEA,0FAA0F;AAC1F,sFAAsF;AACtF,6FAA6F;AAC7F,SAASC,QAAQH,SAAoB,EAAEI,UAAmB;IACxD,OAAO,AAAC,0FAKRA,OAFML,gBAAgBC,YAAW,mFAEuD,OAAxFI,aAAa,wEAAwE,IAAG;AAK1F;AAEA,SAASC,gBAAgBhB,EAAgB,EAAEiB,EAAU;IACnD,IAAMC,SAASlB,GAAGK,OAAO,CAAC;IAC1B,IAAMc,OAAiB,EAAE;IACzB,IAAIC,MAAqBH;IACzB,MAAOG,QAAQ,KAAM;QACnBD,KAAKE,IAAI,CAACD;QACV,IAAME,MAAMJ,OAAOK,GAAG,CAACH;QACvBA,MAAME,MAAMA,IAAIE,IAAI,GAAG;IACzB;IACA,OAAOL,KAAKN,OAAO;AACrB;AAIO,SAASf,SAASE,EAAgB,EAAEyB,IAAY,EAAER,EAAU;QAAES,OAAAA,iEAAwB,CAAC;QAI3EA;IAHjB,IAAID,SAASR,IAAI,OAAO;QAACQ;KAAK;IAE9B,IAAMd,YAAuBe,KAAKC,QAAQ,GAAG,YAAY;IACzD,IAAMC,YAAWF,iBAAAA,KAAKE,QAAQ,cAAbF,4BAAAA,iBAAiBG;IAClC,IAAID,YAAY,GAAG,OAAO;IAE1B7B,aAAaC;IACbA,GAAGK,OAAO,CAAC,+DAA+DC,GAAG,CAACmB;IAC9E,IAAIC,KAAKvB,OAAO,EAAED,aAAaF,IAAI0B,KAAKvB,OAAO,EAAEc;IAEjD,IAAMa,OAAO9B,GAAGK,OAAO,CAACS,QAAQH,WAAW,CAAC,CAACe,KAAKvB,OAAO;IACzD,IAAK,IAAI4B,OAAO,GAAGA,QAAQH,UAAUG,OAAQ;QAC3C,IAAMC,OAAOF,KAAKG,GAAG,CAACF,OAAO,GAAGA,MAAM,CAAC;QACvC,IAAIC,KAAKE,MAAM,KAAK,GAAG;QACvB,IAAIF,KAAKG,IAAI,CAAC,SAACb;mBAAQA,IAAIH,IAAI,KAAKF;YAAK,OAAOD,gBAAgBhB,IAAIiB;IACtE;IACA,OAAO;AACT"}
|
package/dist/esm/cli/check.js
CHANGED
|
@@ -3,16 +3,9 @@ import { open } from '../db.js';
|
|
|
3
3
|
import { printRows } from '../output.js';
|
|
4
4
|
import { USAGE } from './index.js';
|
|
5
5
|
import { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.js';
|
|
6
|
-
// A
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// unknown-column errors without executing it; queries that take no parameters are also run
|
|
10
|
-
// for a row count. Parameterised queries are validated but not counted: inventing arguments
|
|
11
|
-
// would report a count for a query nobody ran. Saved searches run lexically with k=1 -- that
|
|
12
|
-
// validates the `where` fragment, the FTS5 terms, and the `preset` name (resolveSearch throws
|
|
13
|
-
// on an unknown one, the same breakage class prepare() catches for SQL strings) -- but never
|
|
14
|
-
// semantically (a semantic pass costs model time and, on api trees, network). Whether a
|
|
15
|
-
// result being empty is good or bad is the reader's judgment -- there is no assertion path.
|
|
6
|
+
// A broken query and an empty one look identical, so prepare each to catch syntax and column
|
|
7
|
+
// errors. Parameterised ones are not run (inventing arguments would report a bogus count);
|
|
8
|
+
// searches probe at k=1 without vectors. Empty results are the reader's judgment, not a fail.
|
|
16
9
|
const check = async (ctx)=>{
|
|
17
10
|
var _cfg_queries;
|
|
18
11
|
const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.check}`, {
|
|
@@ -34,13 +27,14 @@ const check = async (ctx)=>{
|
|
|
34
27
|
where: entry.where,
|
|
35
28
|
preset: entry.preset,
|
|
36
29
|
include: entry.include,
|
|
37
|
-
|
|
30
|
+
exclude: entry.exclude,
|
|
31
|
+
probe: true
|
|
38
32
|
})).length;
|
|
39
33
|
rows.push({
|
|
40
34
|
query: name,
|
|
41
35
|
params: '—',
|
|
42
36
|
rows: '—',
|
|
43
|
-
status: count === 0 ? 'ok, but matches 0 notes (
|
|
37
|
+
status: count === 0 ? 'ok, but matches 0 notes (words and links only)' : 'ok (probe run with k=1)'
|
|
44
38
|
});
|
|
45
39
|
} catch (err) {
|
|
46
40
|
failed++;
|
|
@@ -53,7 +47,7 @@ const check = async (ctx)=>{
|
|
|
53
47
|
}
|
|
54
48
|
continue;
|
|
55
49
|
}
|
|
56
|
-
const sql =
|
|
50
|
+
const sql = entry.sql;
|
|
57
51
|
const params = ((_sql_match = sql.match(/\?/g)) !== null && _sql_match !== void 0 ? _sql_match : []).length;
|
|
58
52
|
try {
|
|
59
53
|
const statement = db.prepare(sql);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/check.ts"],"sourcesContent":["import { search } from '../commands.ts';\nimport { open } from '../db.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } from '../output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// A
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/check.ts"],"sourcesContent":["import { search } from '../commands.ts';\nimport { open } from '../db.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } from '../output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// A broken query and an empty one look identical, so prepare each to catch syntax and column\n// errors. Parameterised ones are not run (inventing arguments would report a bogus count);\n// searches probe at k=1 without vectors. Empty results are the reader's judgment, not a fail.\nconst check: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.check}`, { ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const cfg = ctx.resolveConfig(values.config as string | undefined);\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n\n const rows: Row[] = [];\n let failed = 0;\n for (const [name, entry] of Object.entries(cfg.queries ?? {})) {\n if (typeof entry === 'object' && entry !== null && 'search' in entry) {\n try {\n const count = (await search(db, cfg, entry.search, { k: 1, where: entry.where, preset: entry.preset, include: entry.include, exclude: entry.exclude, probe: true })).length;\n rows.push({ query: name, params: '—', rows: '—', status: count === 0 ? 'ok, but matches 0 notes (words and links only)' : 'ok (probe run with k=1)' });\n } catch (err) {\n failed++;\n rows.push({ query: name, params: '—', rows: '—', status: `FAILED: ${(err as Error).message}` });\n }\n continue;\n }\n const sql = entry.sql;\n const params = (sql.match(/\\?/g) ?? []).length;\n try {\n const statement = db.prepare(sql);\n if (params > 0) {\n rows.push({ query: name, params, rows: '—', status: 'ok (not run: needs parameters)' });\n continue;\n }\n const count = (statement.all() as unknown[]).length;\n rows.push({ query: name, params, rows: count, status: count === 0 ? 'ok, but returns 0 rows' : 'ok' });\n } catch (err) {\n failed++;\n rows.push({ query: name, params, rows: '—', status: `FAILED: ${(err as Error).message}` });\n }\n }\n\n db.close();\n if (rows.length === 0) {\n console.log('no saved queries in config');\n return;\n }\n printRows(rows, format);\n if (failed > 0) process.exit(1);\n};\nexport default check;\n"],"names":["search","open","printRows","USAGE","CONFIG","FORMAT","formatOf","parse","printWarnings","check","ctx","cfg","values","argv","name","format","resolveConfig","config","db","warnings","rows","failed","entry","Object","entries","queries","sql","count","k","where","preset","include","exclude","probe","length","push","query","params","status","err","message","match","statement","prepare","all","close","console","log","process","exit"],"mappings":"AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,IAAI,QAAQ,WAAW;AAEhC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,aAAa,QAAQ,cAAc;AAG7E,6FAA6F;AAC7F,2FAA2F;AAC3F,8FAA8F;AAC9F,MAAMC,QAAiB,OAAOC;QASeC;IAR3C,MAAM,EAAEC,MAAM,EAAE,GAAGL,MAAMG,IAAIG,IAAI,EAAE,CAAC,OAAO,EAAEH,IAAII,IAAI,CAAC,CAAC,EAAEX,MAAMM,KAAK,EAAE,EAAE;QAAE,GAAGJ,MAAM;QAAE,GAAGD,MAAM;IAAC;IAC/F,MAAMW,SAAST,SAASM;IACxB,MAAMD,MAAMD,IAAIM,aAAa,CAACJ,OAAOK,MAAM;IAC3C,MAAM,EAAEC,EAAE,EAAEC,QAAQ,EAAE,GAAGlB,KAAKU;IAC9BH,cAAcW;IAEd,MAAMC,OAAc,EAAE;IACtB,IAAIC,SAAS;IACb,KAAK,MAAM,CAACP,MAAMQ,MAAM,IAAIC,OAAOC,OAAO,EAACb,eAAAA,IAAIc,OAAO,cAAXd,0BAAAA,eAAe,CAAC,GAAI;YAY7Ce;QAXhB,IAAI,OAAOJ,UAAU,YAAYA,UAAU,QAAQ,YAAYA,OAAO;YACpE,IAAI;gBACF,MAAMK,QAAQ,AAAC,CAAA,MAAM3B,OAAOkB,IAAIP,KAAKW,MAAMtB,MAAM,EAAE;oBAAE4B,GAAG;oBAAGC,OAAOP,MAAMO,KAAK;oBAAEC,QAAQR,MAAMQ,MAAM;oBAAEC,SAAST,MAAMS,OAAO;oBAAEC,SAASV,MAAMU,OAAO;oBAAEC,OAAO;gBAAK,EAAC,EAAGC,MAAM;gBAC3Kd,KAAKe,IAAI,CAAC;oBAAEC,OAAOtB;oBAAMuB,QAAQ;oBAAKjB,MAAM;oBAAKkB,QAAQX,UAAU,IAAI,mDAAmD;gBAA0B;YACtJ,EAAE,OAAOY,KAAK;gBACZlB;gBACAD,KAAKe,IAAI,CAAC;oBAAEC,OAAOtB;oBAAMuB,QAAQ;oBAAKjB,MAAM;oBAAKkB,QAAQ,CAAC,QAAQ,EAAE,AAACC,IAAcC,OAAO,EAAE;gBAAC;YAC/F;YACA;QACF;QACA,MAAMd,MAAMJ,MAAMI,GAAG;QACrB,MAAMW,SAAS,EAACX,aAAAA,IAAIe,KAAK,CAAC,oBAAVf,wBAAAA,aAAoB,EAAE,EAAEQ,MAAM;QAC9C,IAAI;YACF,MAAMQ,YAAYxB,GAAGyB,OAAO,CAACjB;YAC7B,IAAIW,SAAS,GAAG;gBACdjB,KAAKe,IAAI,CAAC;oBAAEC,OAAOtB;oBAAMuB;oBAAQjB,MAAM;oBAAKkB,QAAQ;gBAAiC;gBACrF;YACF;YACA,MAAMX,QAAQ,AAACe,UAAUE,GAAG,GAAiBV,MAAM;YACnDd,KAAKe,IAAI,CAAC;gBAAEC,OAAOtB;gBAAMuB;gBAAQjB,MAAMO;gBAAOW,QAAQX,UAAU,IAAI,2BAA2B;YAAK;QACtG,EAAE,OAAOY,KAAK;YACZlB;YACAD,KAAKe,IAAI,CAAC;gBAAEC,OAAOtB;gBAAMuB;gBAAQjB,MAAM;gBAAKkB,QAAQ,CAAC,QAAQ,EAAE,AAACC,IAAcC,OAAO,EAAE;YAAC;QAC1F;IACF;IAEAtB,GAAG2B,KAAK;IACR,IAAIzB,KAAKc,MAAM,KAAK,GAAG;QACrBY,QAAQC,GAAG,CAAC;QACZ;IACF;IACA7C,UAAUkB,MAAML;IAChB,IAAIM,SAAS,GAAG2B,QAAQC,IAAI,CAAC;AAC/B;AACA,eAAexC,MAAM"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { embedConfig } from '../config.js';
|
|
2
|
+
import { SenseError } from '../errors.js';
|
|
3
|
+
import { downloadModel, modelDir, modelPresent } from '../features/embed.js';
|
|
4
|
+
import { USAGE } from './index.js';
|
|
5
|
+
import { CONFIG, parse } from './shared.js';
|
|
6
|
+
// The one command that fetches weights. Nothing else touches the network for them, so a
|
|
7
|
+
// query that reads like a query never spends minutes pulling 124 MB. Asks nothing, so there
|
|
8
|
+
// is no prompt for CI to bypass; running it twice is a no-op.
|
|
9
|
+
const download = async (ctx)=>{
|
|
10
|
+
const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.download}`, {
|
|
11
|
+
...CONFIG
|
|
12
|
+
});
|
|
13
|
+
const cfg = ctx.resolveConfig(values.config);
|
|
14
|
+
const e = embedConfig(cfg);
|
|
15
|
+
if (!e) throw new SenseError('EMBED_DISABLED', 'no preset asks for vectors, so there is no model to download');
|
|
16
|
+
if (e.type === 'api') {
|
|
17
|
+
console.log(`embed type is "api" (${e.url}), so there is nothing to download; ${ctx.name} search reaches it over the network`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (modelPresent(cfg)) {
|
|
21
|
+
console.log(`${e.model} is already available in ${modelDir(e.model)}`);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const dir = await downloadModel(e.model, (file, into)=>console.error(`fetching ${e.model}/${file} into ${into}`));
|
|
25
|
+
console.log(`downloaded ${e.model} into ${dir}`);
|
|
26
|
+
};
|
|
27
|
+
export default download;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/download.ts"],"sourcesContent":["import { embedConfig } from '../config.ts';\nimport { SenseError } from '../errors.ts';\nimport { downloadModel, modelDir, modelPresent } from '../features/embed.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, parse } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// The one command that fetches weights. Nothing else touches the network for them, so a\n// query that reads like a query never spends minutes pulling 124 MB. Asks nothing, so there\n// is no prompt for CI to bypass; running it twice is a no-op.\nconst download: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.download}`, { ...CONFIG });\n const cfg = ctx.resolveConfig(values.config as string | undefined);\n const e = embedConfig(cfg);\n if (!e) throw new SenseError('EMBED_DISABLED', 'no preset asks for vectors, so there is no model to download');\n\n if (e.type === 'api') {\n console.log(`embed type is \"api\" (${e.url}), so there is nothing to download; ${ctx.name} search reaches it over the network`);\n return;\n }\n if (modelPresent(cfg)) {\n console.log(`${e.model} is already available in ${modelDir(e.model)}`);\n return;\n }\n const dir = await downloadModel(e.model, (file, into) => console.error(`fetching ${e.model}/${file} into ${into}`));\n console.log(`downloaded ${e.model} into ${dir}`);\n};\nexport default download;\n"],"names":["embedConfig","SenseError","downloadModel","modelDir","modelPresent","USAGE","CONFIG","parse","download","ctx","values","argv","name","cfg","resolveConfig","config","e","type","console","log","url","model","dir","file","into","error"],"mappings":"AAAA,SAASA,WAAW,QAAQ,eAAe;AAC3C,SAASC,UAAU,QAAQ,eAAe;AAC1C,SAASC,aAAa,EAAEC,QAAQ,EAAEC,YAAY,QAAQ,uBAAuB;AAC7E,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,KAAK,QAAQ,cAAc;AAG5C,wFAAwF;AACxF,4FAA4F;AAC5F,8DAA8D;AAC9D,MAAMC,WAAoB,OAAOC;IAC/B,MAAM,EAAEC,MAAM,EAAE,GAAGH,MAAME,IAAIE,IAAI,EAAE,CAAC,OAAO,EAAEF,IAAIG,IAAI,CAAC,CAAC,EAAEP,MAAMG,QAAQ,EAAE,EAAE;QAAE,GAAGF,MAAM;IAAC;IACvF,MAAMO,MAAMJ,IAAIK,aAAa,CAACJ,OAAOK,MAAM;IAC3C,MAAMC,IAAIhB,YAAYa;IACtB,IAAI,CAACG,GAAG,MAAM,IAAIf,WAAW,kBAAkB;IAE/C,IAAIe,EAAEC,IAAI,KAAK,OAAO;QACpBC,QAAQC,GAAG,CAAC,CAAC,qBAAqB,EAAEH,EAAEI,GAAG,CAAC,oCAAoC,EAAEX,IAAIG,IAAI,CAAC,mCAAmC,CAAC;QAC7H;IACF;IACA,IAAIR,aAAaS,MAAM;QACrBK,QAAQC,GAAG,CAAC,GAAGH,EAAEK,KAAK,CAAC,yBAAyB,EAAElB,SAASa,EAAEK,KAAK,GAAG;QACrE;IACF;IACA,MAAMC,MAAM,MAAMpB,cAAcc,EAAEK,KAAK,EAAE,CAACE,MAAMC,OAASN,QAAQO,KAAK,CAAC,CAAC,SAAS,EAAET,EAAEK,KAAK,CAAC,CAAC,EAAEE,KAAK,MAAM,EAAEC,MAAM;IACjHN,QAAQC,GAAG,CAAC,CAAC,WAAW,EAAEH,EAAEK,KAAK,CAAC,MAAM,EAAEC,KAAK;AACjD;AACA,eAAed,SAAS"}
|
package/dist/esm/cli/index.d.ts
CHANGED
|
@@ -5,10 +5,13 @@ export declare const USAGE: {
|
|
|
5
5
|
readonly status: "status [--format table|json] [--config path]";
|
|
6
6
|
readonly check: "check [--format table|json] [--config path]";
|
|
7
7
|
readonly rebuild: "rebuild [--config path]";
|
|
8
|
-
readonly
|
|
9
|
-
readonly
|
|
8
|
+
readonly download: "download [--config path]";
|
|
9
|
+
readonly sql: "sql \"<statement>\" [params...] [--format table|json] [--config path]";
|
|
10
|
+
readonly search: "search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--format table|json] [--config path]";
|
|
10
11
|
readonly map: "map [--format table|json] [--config path]";
|
|
11
|
-
readonly peek: "peek <path> [--format table|json] [--config path]";
|
|
12
|
+
readonly peek: "peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--format table|json] [--config path]";
|
|
13
|
+
readonly path: "path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--format table|json] [--config path]";
|
|
14
|
+
readonly related: "related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--format table|json] [--config path]";
|
|
12
15
|
};
|
|
13
16
|
export declare const COMMANDS: Record<string, () => Promise<{
|
|
14
17
|
default: Command;
|
package/dist/esm/cli/index.js
CHANGED
|
@@ -7,22 +7,28 @@ export const USAGE = {
|
|
|
7
7
|
status: 'status [--format table|json] [--config path]',
|
|
8
8
|
check: 'check [--format table|json] [--config path]',
|
|
9
9
|
rebuild: 'rebuild [--config path]',
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
download: 'download [--config path]',
|
|
11
|
+
sql: 'sql "<statement>" [params...] [--format table|json] [--config path]',
|
|
12
|
+
search: 'search "<terms>" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--k n] [--format table|json] [--config path]',
|
|
12
13
|
map: 'map [--format table|json] [--config path]',
|
|
13
|
-
peek: 'peek <path> [--format table|json] [--config path]'
|
|
14
|
+
peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--format table|json] [--config path]',
|
|
15
|
+
path: 'path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--max-depth n] [--format table|json] [--config path]',
|
|
16
|
+
related: 'related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--k n] [--format table|json] [--config path]'
|
|
14
17
|
};
|
|
15
18
|
// Lazy registry: a command's imports load only when it runs, so a heavy dependency in one
|
|
16
|
-
// command never taxes the others (or --version/--help). These names are reserved: a
|
|
17
|
-
//
|
|
19
|
+
// command never taxes the others (or --version/--help). These names are reserved: a saved
|
|
20
|
+
// entry in config can never shadow them.
|
|
18
21
|
export const COMMANDS = {
|
|
19
22
|
init: ()=>import('./init.js'),
|
|
20
23
|
watch: ()=>import('./watch.js'),
|
|
21
24
|
status: ()=>import('./status.js'),
|
|
22
25
|
check: ()=>import('./check.js'),
|
|
23
26
|
rebuild: ()=>import('./rebuild.js'),
|
|
24
|
-
|
|
27
|
+
download: ()=>import('./download.js'),
|
|
28
|
+
sql: ()=>import('./sql.js'),
|
|
25
29
|
search: ()=>import('./search.js'),
|
|
26
30
|
map: ()=>import('./map.js'),
|
|
27
|
-
peek: ()=>import('./peek.js')
|
|
31
|
+
peek: ()=>import('./peek.js'),
|
|
32
|
+
path: ()=>import('./path.js'),
|
|
33
|
+
related: ()=>import('./related.js')
|
|
28
34
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/index.ts"],"sourcesContent":["import type { Command } from './types.ts';\n\n// Each command's usage line, minus the leading \"usage: <name> \" -- shared by cli.ts's\n// top-level usage() and the command's own parse() error/--help output, so there is one\n// copy of each line, not two that can drift.\nexport const USAGE = {\n init: 'init',\n watch: 'watch [--force] [--config path]',\n status: 'status [--format table|json] [--config path]',\n check: 'check [--format table|json] [--config path]',\n rebuild: 'rebuild [--config path]',\n
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/index.ts"],"sourcesContent":["import type { Command } from './types.ts';\n\n// Each command's usage line, minus the leading \"usage: <name> \" -- shared by cli.ts's\n// top-level usage() and the command's own parse() error/--help output, so there is one\n// copy of each line, not two that can drift.\nexport const USAGE = {\n init: 'init',\n watch: 'watch [--force] [--config path]',\n status: 'status [--format table|json] [--config path]',\n check: 'check [--format table|json] [--config path]',\n rebuild: 'rebuild [--config path]',\n download: 'download [--config path]',\n sql: 'sql \"<statement>\" [params...] [--format table|json] [--config path]',\n search: 'search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--format table|json] [--config path]',\n map: 'map [--format table|json] [--config path]',\n peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--format table|json] [--config path]',\n path: 'path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--format table|json] [--config path]',\n related: 'related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--format table|json] [--config path]',\n} as const;\n\n// Lazy registry: a command's imports load only when it runs, so a heavy dependency in one\n// command never taxes the others (or --version/--help). These names are reserved: a saved\n// entry in config can never shadow them.\nexport const COMMANDS: Record<string, () => Promise<{ default: Command }>> = {\n init: () => import('./init.ts'),\n watch: () => import('./watch.ts'),\n status: () => import('./status.ts'),\n check: () => import('./check.ts'),\n rebuild: () => import('./rebuild.ts'),\n download: () => import('./download.ts'),\n sql: () => import('./sql.ts'),\n search: () => import('./search.ts'),\n map: () => import('./map.ts'),\n peek: () => import('./peek.ts'),\n path: () => import('./path.ts'),\n related: () => import('./related.ts'),\n};\n\nexport type { Command, Ctx } from './types.ts';\n"],"names":["USAGE","init","watch","status","check","rebuild","download","sql","search","map","peek","path","related","COMMANDS"],"mappings":"AAEA,sFAAsF;AACtF,uFAAuF;AACvF,6CAA6C;AAC7C,OAAO,MAAMA,QAAQ;IACnBC,MAAM;IACNC,OAAO;IACPC,QAAQ;IACRC,OAAO;IACPC,SAAS;IACTC,UAAU;IACVC,KAAK;IACLC,QAAQ;IACRC,KAAK;IACLC,MAAM;IACNC,MAAM;IACNC,SAAS;AACX,EAAW;AAEX,0FAA0F;AAC1F,0FAA0F;AAC1F,yCAAyC;AACzC,OAAO,MAAMC,WAAgE;IAC3EZ,MAAM,IAAM,MAAM,CAAC;IACnBC,OAAO,IAAM,MAAM,CAAC;IACpBC,QAAQ,IAAM,MAAM,CAAC;IACrBC,OAAO,IAAM,MAAM,CAAC;IACpBC,SAAS,IAAM,MAAM,CAAC;IACtBC,UAAU,IAAM,MAAM,CAAC;IACvBC,KAAK,IAAM,MAAM,CAAC;IAClBC,QAAQ,IAAM,MAAM,CAAC;IACrBC,KAAK,IAAM,MAAM,CAAC;IAClBC,MAAM,IAAM,MAAM,CAAC;IACnBC,MAAM,IAAM,MAAM,CAAC;IACnBC,SAAS,IAAM,MAAM,CAAC;AACxB,EAAE"}
|
package/dist/esm/cli/init.js
CHANGED
|
@@ -5,7 +5,10 @@ const init = (ctx)=>{
|
|
|
5
5
|
parse(ctx.argv, `usage: ${ctx.name} ${USAGE.init}`, {});
|
|
6
6
|
const configPath = initConfig(process.cwd());
|
|
7
7
|
console.log(`created ${configPath}`);
|
|
8
|
-
console.log(`query away: ${ctx.name}
|
|
8
|
+
console.log(`query away: ${ctx.name} sql "SELECT path FROM frontmatter LIMIT 10"`);
|
|
9
|
+
// Semantic search needs a 124 MB model that nothing downloads implicitly; name the step
|
|
10
|
+
// here so the first search meets it as a choice rather than as a degraded result.
|
|
11
|
+
console.log(`for meaning-based search: ${ctx.name} download (one 124 MB model, once)`);
|
|
9
12
|
// The decisions a new tree faces -- features, frontmatter conventions, note size -- are not
|
|
10
13
|
// in this output; name both places that hold them, since an agent may have neither.
|
|
11
14
|
console.log('features and tree design: the sense-setup skill, or schema.json');
|
package/dist/esm/cli/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/init.ts"],"sourcesContent":["import { initConfig } from '../config.ts';\nimport { USAGE } from './index.ts';\nimport { parse } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst init: Command = (ctx) => {\n parse(ctx.argv, `usage: ${ctx.name} ${USAGE.init}`, {});\n const configPath = initConfig(process.cwd());\n console.log(`created ${configPath}`);\n console.log(`query away: ${ctx.name}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/init.ts"],"sourcesContent":["import { initConfig } from '../config.ts';\nimport { USAGE } from './index.ts';\nimport { parse } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst init: Command = (ctx) => {\n parse(ctx.argv, `usage: ${ctx.name} ${USAGE.init}`, {});\n const configPath = initConfig(process.cwd());\n console.log(`created ${configPath}`);\n console.log(`query away: ${ctx.name} sql \"SELECT path FROM frontmatter LIMIT 10\"`);\n // Semantic search needs a 124 MB model that nothing downloads implicitly; name the step\n // here so the first search meets it as a choice rather than as a degraded result.\n console.log(`for meaning-based search: ${ctx.name} download (one 124 MB model, once)`);\n // The decisions a new tree faces -- features, frontmatter conventions, note size -- are not\n // in this output; name both places that hold them, since an agent may have neither.\n console.log('features and tree design: the sense-setup skill, or schema.json');\n};\nexport default init;\n"],"names":["initConfig","USAGE","parse","init","ctx","argv","name","configPath","process","cwd","console","log"],"mappings":"AAAA,SAASA,UAAU,QAAQ,eAAe;AAC1C,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,KAAK,QAAQ,cAAc;AAGpC,MAAMC,OAAgB,CAACC;IACrBF,MAAME,IAAIC,IAAI,EAAE,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEL,MAAME,IAAI,EAAE,EAAE,CAAC;IACrD,MAAMI,aAAaP,WAAWQ,QAAQC,GAAG;IACzCC,QAAQC,GAAG,CAAC,CAAC,QAAQ,EAAEJ,YAAY;IACnCG,QAAQC,GAAG,CAAC,CAAC,YAAY,EAAEP,IAAIE,IAAI,CAAC,4CAA4C,CAAC;IACjF,wFAAwF;IACxF,kFAAkF;IAClFI,QAAQC,GAAG,CAAC,CAAC,0BAA0B,EAAEP,IAAIE,IAAI,CAAC,kCAAkC,CAAC;IACrF,4FAA4F;IAC5F,oFAAoF;IACpFI,QAAQC,GAAG,CAAC;AACd;AACA,eAAeR,KAAK"}
|
package/dist/esm/cli/map.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { mapTree } from '../commands.js';
|
|
2
2
|
import { renderMap } from '../output.js';
|
|
3
3
|
import { USAGE } from './index.js';
|
|
4
|
-
import { CONFIG, FORMAT, formatOf, parse, withDb } from './shared.js';
|
|
4
|
+
import { CONFIG, FORMAT, formatOf, parse, SCOPE, scopeOf, withDb } from './shared.js';
|
|
5
5
|
const map = (ctx)=>{
|
|
6
6
|
const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.map}`, {
|
|
7
|
+
...SCOPE,
|
|
7
8
|
...FORMAT,
|
|
8
9
|
...CONFIG
|
|
9
10
|
});
|
|
10
11
|
const format = formatOf(values);
|
|
11
12
|
return withDb(ctx, values.config, (db, cfg)=>{
|
|
12
|
-
const result = mapTree(db, cfg);
|
|
13
|
+
const result = mapTree(db, cfg, scopeOf(values));
|
|
13
14
|
console.log(format === 'json' ? JSON.stringify(result, null, 2) : renderMap(result));
|
|
14
15
|
});
|
|
15
16
|
};
|
package/dist/esm/cli/map.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/map.ts"],"sourcesContent":["import { mapTree } from '../commands.ts';\nimport { renderMap } from '../output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst map: Command = (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.map}`, { ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, (db, cfg) => {\n const result = mapTree(db, cfg);\n console.log(format === 'json' ? JSON.stringify(result, null, 2) : renderMap(result));\n });\n};\nexport default map;\n"],"names":["mapTree","renderMap","USAGE","CONFIG","FORMAT","formatOf","parse","withDb","map","ctx","values","argv","name","format","config","db","cfg","result","console","log","JSON","stringify"],"mappings":"AAAA,SAASA,OAAO,QAAQ,iBAAiB;AACzC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,MAAM,QAAQ,cAAc;
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/map.ts"],"sourcesContent":["import { mapTree } from '../commands.ts';\nimport { renderMap } from '../output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst map: Command = (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.map}`, { ...SCOPE, ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, (db, cfg) => {\n const result = mapTree(db, cfg, scopeOf(values));\n console.log(format === 'json' ? JSON.stringify(result, null, 2) : renderMap(result));\n });\n};\nexport default map;\n"],"names":["mapTree","renderMap","USAGE","CONFIG","FORMAT","formatOf","parse","SCOPE","scopeOf","withDb","map","ctx","values","argv","name","format","config","db","cfg","result","console","log","JSON","stringify"],"mappings":"AAAA,SAASA,OAAO,QAAQ,iBAAiB;AACzC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGtF,MAAMC,MAAe,CAACC;IACpB,MAAM,EAAEC,MAAM,EAAE,GAAGN,MAAMK,IAAIE,IAAI,EAAE,CAAC,OAAO,EAAEF,IAAIG,IAAI,CAAC,CAAC,EAAEZ,MAAMQ,GAAG,EAAE,EAAE;QAAE,GAAGH,KAAK;QAAE,GAAGH,MAAM;QAAE,GAAGD,MAAM;IAAC;IACvG,MAAMY,SAASV,SAASO;IACxB,OAAOH,OAAOE,KAAKC,OAAOI,MAAM,EAAwB,CAACC,IAAIC;QAC3D,MAAMC,SAASnB,QAAQiB,IAAIC,KAAKV,QAAQI;QACxCQ,QAAQC,GAAG,CAACN,WAAW,SAASO,KAAKC,SAAS,CAACJ,QAAQ,MAAM,KAAKlB,UAAUkB;IAC9E;AACF;AACA,eAAeT,IAAI"}
|
package/dist/esm/cli/named.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { search } from '../commands.js';
|
|
2
2
|
import { printRows } from '../output.js';
|
|
3
3
|
import { CONFIG, FORMAT, formatOf, parse, parseK, runSql, SEARCH_FLAGS, withDb } from './shared.js';
|
|
4
|
-
// Fallback when the first positional is not a command: a
|
|
5
|
-
//
|
|
6
|
-
// Flags cover both shapes -- SEARCH_FLAGS override a saved search's fields the same way they
|
|
7
|
-
// override a preset's.
|
|
4
|
+
// Fallback when the first positional is not a command: a saved query, { sql } or { search }.
|
|
5
|
+
// SEARCH_FLAGS override a saved search's fields the same way they override a preset's.
|
|
8
6
|
export default async function named(ctx, queryName) {
|
|
9
|
-
var _parseK, _values_where, _values_preset, _values_include;
|
|
10
|
-
const usage = `usage: ${ctx.name} ${queryName} [params...] [--format table|json] [--config path] [--where "<sql>"] [--k n] [--preset name] [--include glob ...] [--
|
|
7
|
+
var _parseK, _values_where, _values_preset, _values_include, _values_exclude;
|
|
8
|
+
const usage = `usage: ${ctx.name} ${queryName} [params...] [--format table|json] [--config path] [--where "<sql>"] [--k n] [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude]`;
|
|
11
9
|
const { values, positionals: params } = parse(ctx.argv, usage, {
|
|
12
10
|
...SEARCH_FLAGS,
|
|
13
11
|
...FORMAT,
|
|
@@ -18,14 +16,10 @@ export default async function named(ctx, queryName) {
|
|
|
18
16
|
const cfg = ctx.resolveConfig(configPath);
|
|
19
17
|
const entry = cfg.queries[queryName];
|
|
20
18
|
if (entry === undefined) {
|
|
21
|
-
console.error(`unknown
|
|
22
|
-
console.error(`
|
|
19
|
+
console.error(`unknown command or saved entry: "${queryName}"`);
|
|
20
|
+
console.error(`saved queries: ${Object.keys(cfg.queries).sort().join(', ')}`);
|
|
23
21
|
process.exit(2);
|
|
24
22
|
}
|
|
25
|
-
if (typeof entry === 'string') {
|
|
26
|
-
runSql(cfg, entry, params, format, `query "${queryName}"`);
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
23
|
if ('sql' in entry) {
|
|
30
24
|
runSql(cfg, entry.sql, params, format, `query "${queryName}"`);
|
|
31
25
|
return;
|
|
@@ -38,14 +32,14 @@ export default async function named(ctx, queryName) {
|
|
|
38
32
|
const where = (_values_where = values.where) !== null && _values_where !== void 0 ? _values_where : entry.where;
|
|
39
33
|
const preset = (_values_preset = values.preset) !== null && _values_preset !== void 0 ? _values_preset : entry.preset;
|
|
40
34
|
const include = (_values_include = values.include) !== null && _values_include !== void 0 ? _values_include : entry.include;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const semantic = values.lexical ? false : entry.semantic;
|
|
35
|
+
const exclude = (_values_exclude = values.exclude) !== null && _values_exclude !== void 0 ? _values_exclude : entry.exclude;
|
|
36
|
+
const noExclude = values['no-exclude'] === true;
|
|
44
37
|
await withDb(ctx, configPath, async (db, resolvedCfg)=>printRows(await search(db, resolvedCfg, entry.search, {
|
|
45
38
|
k,
|
|
46
39
|
where,
|
|
47
40
|
preset,
|
|
48
41
|
include,
|
|
49
|
-
|
|
42
|
+
exclude,
|
|
43
|
+
noExclude
|
|
50
44
|
}), format));
|
|
51
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/named.ts"],"sourcesContent":["import { search } from '../commands.ts';\nimport { printRows } from '../output.ts';\nimport { CONFIG, FORMAT, formatOf, parse, parseK, runSql, SEARCH_FLAGS, withDb } from './shared.ts';\nimport type { Ctx } from './types.ts';\n\n// Fallback when the first positional is not a command: a
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/named.ts"],"sourcesContent":["import { search } from '../commands.ts';\nimport { printRows } from '../output.ts';\nimport { CONFIG, FORMAT, formatOf, parse, parseK, runSql, SEARCH_FLAGS, withDb } from './shared.ts';\nimport type { Ctx } from './types.ts';\n\n// Fallback when the first positional is not a command: a saved query, { sql } or { search }.\n// SEARCH_FLAGS override a saved search's fields the same way they override a preset's.\nexport default async function named(ctx: Ctx, queryName: string): Promise<void> {\n const usage = `usage: ${ctx.name} ${queryName} [params...] [--format table|json] [--config path] [--where \"<sql>\"] [--k n] [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude]`;\n const { values, positionals: params } = parse(ctx.argv, usage, { ...SEARCH_FLAGS, ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const configPath = values.config as string | undefined;\n\n const cfg = ctx.resolveConfig(configPath);\n const entry = cfg.queries[queryName];\n if (entry === undefined) {\n console.error(`unknown command or saved entry: \"${queryName}\"`);\n console.error(`saved queries: ${Object.keys(cfg.queries).sort().join(', ')}`);\n process.exit(2);\n }\n\n if ('sql' in entry) {\n runSql(cfg, entry.sql, params, format, `query \"${queryName}\"`);\n return;\n }\n\n // A saved search's text is fixed in config; there is nowhere for a positional to bind.\n if (params.length > 0) {\n ctx.usageError(`\"${queryName}\" is a saved search and takes no positional parameters; edit its \"search\" in sense.config.json, or use \"${ctx.name} search\" directly`);\n }\n const k = parseK(values.k as string | undefined, ctx.usageError) ?? entry.k;\n const where = (values.where as string | undefined) ?? entry.where;\n const preset = (values.preset as string | undefined) ?? entry.preset;\n const include = (values.include as string[] | undefined) ?? entry.include;\n const exclude = (values.exclude as string[] | undefined) ?? entry.exclude;\n const noExclude = values['no-exclude'] === true;\n await withDb(ctx, configPath, async (db, resolvedCfg) => printRows(await search(db, resolvedCfg, entry.search, { k, where, preset, include, exclude, noExclude }), format));\n}\n"],"names":["search","printRows","CONFIG","FORMAT","formatOf","parse","parseK","runSql","SEARCH_FLAGS","withDb","named","ctx","queryName","values","usage","name","positionals","params","argv","format","configPath","config","cfg","resolveConfig","entry","queries","undefined","console","error","Object","keys","sort","join","process","exit","sql","length","usageError","k","where","preset","include","exclude","noExclude","db","resolvedCfg"],"mappings":"AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,MAAM,EAAEC,MAAM,EAAEC,YAAY,EAAEC,MAAM,QAAQ,cAAc;AAGpG,6FAA6F;AAC7F,uFAAuF;AACvF,eAAe,eAAeC,MAAMC,GAAQ,EAAEC,SAAiB;QAuBnDN,SACKO,eACCA,gBACCA,iBACAA;IA1BjB,MAAMC,QAAQ,CAAC,OAAO,EAAEH,IAAII,IAAI,CAAC,CAAC,EAAEH,UAAU,qJAAqJ,CAAC;IACpM,MAAM,EAAEC,MAAM,EAAEG,aAAaC,MAAM,EAAE,GAAGZ,MAAMM,IAAIO,IAAI,EAAEJ,OAAO;QAAE,GAAGN,YAAY;QAAE,GAAGL,MAAM;QAAE,GAAGD,MAAM;IAAC;IACvG,MAAMiB,SAASf,SAASS;IACxB,MAAMO,aAAaP,OAAOQ,MAAM;IAEhC,MAAMC,MAAMX,IAAIY,aAAa,CAACH;IAC9B,MAAMI,QAAQF,IAAIG,OAAO,CAACb,UAAU;IACpC,IAAIY,UAAUE,WAAW;QACvBC,QAAQC,KAAK,CAAC,CAAC,iCAAiC,EAAEhB,UAAU,CAAC,CAAC;QAC9De,QAAQC,KAAK,CAAC,CAAC,eAAe,EAAEC,OAAOC,IAAI,CAACR,IAAIG,OAAO,EAAEM,IAAI,GAAGC,IAAI,CAAC,OAAO;QAC5EC,QAAQC,IAAI,CAAC;IACf;IAEA,IAAI,SAASV,OAAO;QAClBjB,OAAOe,KAAKE,MAAMW,GAAG,EAAElB,QAAQE,QAAQ,CAAC,OAAO,EAAEP,UAAU,CAAC,CAAC;QAC7D;IACF;IAEA,uFAAuF;IACvF,IAAIK,OAAOmB,MAAM,GAAG,GAAG;QACrBzB,IAAI0B,UAAU,CAAC,CAAC,CAAC,EAAEzB,UAAU,wGAAwG,EAAED,IAAII,IAAI,CAAC,iBAAiB,CAAC;IACpK;IACA,MAAMuB,KAAIhC,UAAAA,OAAOO,OAAOyB,CAAC,EAAwB3B,IAAI0B,UAAU,eAArD/B,qBAAAA,UAA0DkB,MAAMc,CAAC;IAC3E,MAAMC,SAAS1B,gBAAAA,OAAO0B,KAAK,cAAZ1B,2BAAAA,gBAAuCW,MAAMe,KAAK;IACjE,MAAMC,UAAU3B,iBAAAA,OAAO2B,MAAM,cAAb3B,4BAAAA,iBAAwCW,MAAMgB,MAAM;IACpE,MAAMC,WAAW5B,kBAAAA,OAAO4B,OAAO,cAAd5B,6BAAAA,kBAA2CW,MAAMiB,OAAO;IACzE,MAAMC,WAAW7B,kBAAAA,OAAO6B,OAAO,cAAd7B,6BAAAA,kBAA2CW,MAAMkB,OAAO;IACzE,MAAMC,YAAY9B,MAAM,CAAC,aAAa,KAAK;IAC3C,MAAMJ,OAAOE,KAAKS,YAAY,OAAOwB,IAAIC,cAAgB5C,UAAU,MAAMD,OAAO4C,IAAIC,aAAarB,MAAMxB,MAAM,EAAE;YAAEsC;YAAGC;YAAOC;YAAQC;YAASC;YAASC;QAAU,IAAIxB;AACrK"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { resolveNote, scopedPaths } from '../commands.js';
|
|
2
|
+
import { printRows } from '../output.js';
|
|
3
|
+
import { findPath } from '../traverse.js';
|
|
4
|
+
import { USAGE } from './index.js';
|
|
5
|
+
import { CONFIG, FORMAT, formatOf, parse, SCOPE, scopeOf, withDb } from './shared.js';
|
|
6
|
+
// --max-depth must be a positive integer, mirroring shared.ts's parseK.
|
|
7
|
+
function parseMaxDepth(depth, usageError) {
|
|
8
|
+
if (depth === undefined) return undefined;
|
|
9
|
+
const parsed = Number(depth);
|
|
10
|
+
if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--max-depth expects a positive integer, got "${depth}"`);
|
|
11
|
+
return parsed;
|
|
12
|
+
}
|
|
13
|
+
const pathCmd = (ctx)=>{
|
|
14
|
+
const usage = `usage: ${ctx.name} ${USAGE.path}`;
|
|
15
|
+
const { values, positionals } = parse(ctx.argv, usage, {
|
|
16
|
+
...SCOPE,
|
|
17
|
+
...FORMAT,
|
|
18
|
+
...CONFIG,
|
|
19
|
+
'max-depth': {
|
|
20
|
+
type: 'string'
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
const [a, b] = positionals;
|
|
24
|
+
if (!a || !b) ctx.usageError(usage);
|
|
25
|
+
const maxDepth = parseMaxDepth(values['max-depth'], ctx.usageError);
|
|
26
|
+
const format = formatOf(values);
|
|
27
|
+
return withDb(ctx, values.config, (db, cfg)=>{
|
|
28
|
+
const paths = db.prepare('SELECT "path" FROM frontmatter').all().map((r)=>r.path);
|
|
29
|
+
const from = resolveNote(paths, a);
|
|
30
|
+
const to = resolveNote(paths, b);
|
|
31
|
+
const allowed = scopedPaths(db, cfg, scopeOf(values));
|
|
32
|
+
const hops = findPath(db, from, to, {
|
|
33
|
+
maxDepth,
|
|
34
|
+
allowed
|
|
35
|
+
});
|
|
36
|
+
if (format === 'json') {
|
|
37
|
+
console.log(JSON.stringify(hops));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (hops === null) {
|
|
41
|
+
console.log(maxDepth ? `no path within ${maxDepth} hops` : 'no path');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const rows = hops.map((p, step)=>({
|
|
45
|
+
step,
|
|
46
|
+
path: p
|
|
47
|
+
}));
|
|
48
|
+
printRows(rows, format);
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
export default pathCmd;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/path.ts"],"sourcesContent":["import { resolveNote, scopedPaths } from '../commands.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } from '../output.ts';\nimport { findPath } from '../traverse.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// --max-depth must be a positive integer, mirroring shared.ts's parseK.\nfunction parseMaxDepth(depth: string | undefined, usageError: (message: string) => never): number | undefined {\n if (depth === undefined) return undefined;\n const parsed = Number(depth);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--max-depth expects a positive integer, got \"${depth}\"`);\n return parsed;\n}\n\nconst pathCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.path}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...FORMAT, ...CONFIG, 'max-depth': { type: 'string' } });\n const [a, b] = positionals;\n if (!a || !b) ctx.usageError(usage);\n const maxDepth = parseMaxDepth(values['max-depth'] as string | undefined, ctx.usageError);\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, (db, cfg) => {\n const paths = (db.prepare('SELECT \"path\" FROM frontmatter').all() as Array<{ path: string }>).map((r) => r.path);\n const from = resolveNote(paths, a);\n const to = resolveNote(paths, b);\n const allowed = scopedPaths(db, cfg, scopeOf(values));\n const hops = findPath(db, from, to, { maxDepth, allowed });\n\n if (format === 'json') {\n console.log(JSON.stringify(hops));\n return;\n }\n if (hops === null) {\n console.log(maxDepth ? `no path within ${maxDepth} hops` : 'no path');\n return;\n }\n const rows: Row[] = hops.map((p, step) => ({ step, path: p }));\n printRows(rows, format);\n });\n};\nexport default pathCmd;\n"],"names":["resolveNote","scopedPaths","printRows","findPath","USAGE","CONFIG","FORMAT","formatOf","parse","SCOPE","scopeOf","withDb","parseMaxDepth","depth","usageError","undefined","parsed","Number","isInteger","pathCmd","ctx","usage","name","path","values","positionals","argv","type","a","b","maxDepth","format","config","db","cfg","paths","prepare","all","map","r","from","to","allowed","hops","console","log","JSON","stringify","rows","p","step"],"mappings":"AAAA,SAASA,WAAW,EAAEC,WAAW,QAAQ,iBAAiB;AAE1D,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,QAAQ,QAAQ,iBAAiB;AAC1C,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGtF,wEAAwE;AACxE,SAASC,cAAcC,KAAyB,EAAEC,UAAsC;IACtF,IAAID,UAAUE,WAAW,OAAOA;IAChC,MAAMC,SAASC,OAAOJ;IACtB,IAAI,CAACI,OAAOC,SAAS,CAACF,WAAWA,UAAU,GAAGF,WAAW,CAAC,6CAA6C,EAAED,MAAM,CAAC,CAAC;IACjH,OAAOG;AACT;AAEA,MAAMG,UAAmB,CAACC;IACxB,MAAMC,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAElB,MAAMmB,IAAI,EAAE;IAChD,MAAM,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGjB,MAAMY,IAAIM,IAAI,EAAEL,OAAO;QAAE,GAAGZ,KAAK;QAAE,GAAGH,MAAM;QAAE,GAAGD,MAAM;QAAE,aAAa;YAAEsB,MAAM;QAAS;IAAE;IACzH,MAAM,CAACC,GAAGC,EAAE,GAAGJ;IACf,IAAI,CAACG,KAAK,CAACC,GAAGT,IAAIN,UAAU,CAACO;IAC7B,MAAMS,WAAWlB,cAAcY,MAAM,CAAC,YAAY,EAAwBJ,IAAIN,UAAU;IACxF,MAAMiB,SAASxB,SAASiB;IACxB,OAAOb,OAAOS,KAAKI,OAAOQ,MAAM,EAAwB,CAACC,IAAIC;QAC3D,MAAMC,QAAQ,AAACF,GAAGG,OAAO,CAAC,kCAAkCC,GAAG,GAA+BC,GAAG,CAAC,CAACC,IAAMA,EAAEhB,IAAI;QAC/G,MAAMiB,OAAOxC,YAAYmC,OAAOP;QAChC,MAAMa,KAAKzC,YAAYmC,OAAON;QAC9B,MAAMa,UAAUzC,YAAYgC,IAAIC,KAAKxB,QAAQc;QAC7C,MAAMmB,OAAOxC,SAAS8B,IAAIO,MAAMC,IAAI;YAAEX;YAAUY;QAAQ;QAExD,IAAIX,WAAW,QAAQ;YACrBa,QAAQC,GAAG,CAACC,KAAKC,SAAS,CAACJ;YAC3B;QACF;QACA,IAAIA,SAAS,MAAM;YACjBC,QAAQC,GAAG,CAACf,WAAW,CAAC,eAAe,EAAEA,SAAS,KAAK,CAAC,GAAG;YAC3D;QACF;QACA,MAAMkB,OAAcL,KAAKL,GAAG,CAAC,CAACW,GAAGC,OAAU,CAAA;gBAAEA;gBAAM3B,MAAM0B;YAAE,CAAA;QAC3D/C,UAAU8C,MAAMjB;IAClB;AACF;AACA,eAAeZ,QAAQ"}
|
package/dist/esm/cli/peek.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { peek } from '../commands.js';
|
|
2
2
|
import { renderPeek } from '../output.js';
|
|
3
3
|
import { USAGE } from './index.js';
|
|
4
|
-
import { CONFIG, FORMAT, formatOf, parse, withDb } from './shared.js';
|
|
4
|
+
import { CONFIG, FORMAT, formatOf, parse, SCOPE, scopeOf, withDb } from './shared.js';
|
|
5
5
|
const peekCmd = (ctx)=>{
|
|
6
6
|
const usage = `usage: ${ctx.name} ${USAGE.peek}`;
|
|
7
7
|
const { values, positionals } = parse(ctx.argv, usage, {
|
|
8
|
+
...SCOPE,
|
|
8
9
|
...FORMAT,
|
|
9
10
|
...CONFIG
|
|
10
11
|
});
|
|
@@ -12,7 +13,8 @@ const peekCmd = (ctx)=>{
|
|
|
12
13
|
if (!pathArg) ctx.usageError(usage);
|
|
13
14
|
const format = formatOf(values);
|
|
14
15
|
return withDb(ctx, values.config, (db, cfg)=>{
|
|
15
|
-
const
|
|
16
|
+
const overrides = scopeOf(values);
|
|
17
|
+
const result = peek(db, cfg, pathArg, overrides);
|
|
16
18
|
console.log(format === 'json' ? JSON.stringify(result, null, 2) : renderPeek(result));
|
|
17
19
|
});
|
|
18
20
|
};
|
package/dist/esm/cli/peek.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/peek.ts"],"sourcesContent":["import { peek } from '../commands.ts';\nimport { renderPeek } from '../output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst peekCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.peek}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...FORMAT, ...CONFIG });\n const [pathArg] = positionals;\n if (!pathArg) ctx.usageError(usage);\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, (db, cfg) => {\n const result = peek(db, cfg, pathArg);\n console.log(format === 'json' ? JSON.stringify(result, null, 2) : renderPeek(result));\n });\n};\nexport default peekCmd;\n"],"names":["peek","renderPeek","USAGE","CONFIG","FORMAT","formatOf","parse","withDb","peekCmd","ctx","usage","name","values","positionals","argv","pathArg","usageError","format","config","db","cfg","result","console","log","JSON","stringify"],"mappings":"AAAA,SAASA,IAAI,QAAQ,iBAAiB;AACtC,SAASC,UAAU,QAAQ,eAAe;AAC1C,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,MAAM,QAAQ,cAAc;
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/peek.ts"],"sourcesContent":["import { peek } from '../commands.ts';\nimport { renderPeek } from '../output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst peekCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.peek}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...FORMAT, ...CONFIG });\n const [pathArg] = positionals;\n if (!pathArg) ctx.usageError(usage);\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, (db, cfg) => {\n const overrides = scopeOf(values);\n const result = peek(db, cfg, pathArg, overrides);\n console.log(format === 'json' ? JSON.stringify(result, null, 2) : renderPeek(result));\n });\n};\nexport default peekCmd;\n"],"names":["peek","renderPeek","USAGE","CONFIG","FORMAT","formatOf","parse","SCOPE","scopeOf","withDb","peekCmd","ctx","usage","name","values","positionals","argv","pathArg","usageError","format","config","db","cfg","overrides","result","console","log","JSON","stringify"],"mappings":"AAAA,SAASA,IAAI,QAAQ,iBAAiB;AACtC,SAASC,UAAU,QAAQ,eAAe;AAC1C,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGtF,MAAMC,UAAmB,CAACC;IACxB,MAAMC,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEX,MAAMF,IAAI,EAAE;IAChD,MAAM,EAAEc,MAAM,EAAEC,WAAW,EAAE,GAAGT,MAAMK,IAAIK,IAAI,EAAEJ,OAAO;QAAE,GAAGL,KAAK;QAAE,GAAGH,MAAM;QAAE,GAAGD,MAAM;IAAC;IACxF,MAAM,CAACc,QAAQ,GAAGF;IAClB,IAAI,CAACE,SAASN,IAAIO,UAAU,CAACN;IAC7B,MAAMO,SAASd,SAASS;IACxB,OAAOL,OAAOE,KAAKG,OAAOM,MAAM,EAAwB,CAACC,IAAIC;QAC3D,MAAMC,YAAYf,QAAQM;QAC1B,MAAMU,SAASxB,KAAKqB,IAAIC,KAAKL,SAASM;QACtCE,QAAQC,GAAG,CAACP,WAAW,SAASQ,KAAKC,SAAS,CAACJ,QAAQ,MAAM,KAAKvB,WAAWuB;IAC/E;AACF;AACA,eAAed,QAAQ"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { relatedNotes } from '../commands.js';
|
|
2
|
+
import { printRows } from '../output.js';
|
|
3
|
+
import { USAGE } from './index.js';
|
|
4
|
+
import { CONFIG, FORMAT, formatOf, parse, parseK, SCOPE, scopeOf, withDb } from './shared.js';
|
|
5
|
+
const RELATED_DEFAULT_K = 5;
|
|
6
|
+
const relatedCmd = (ctx)=>{
|
|
7
|
+
var _parseK;
|
|
8
|
+
const usage = `usage: ${ctx.name} ${USAGE.related}`;
|
|
9
|
+
const { values, positionals } = parse(ctx.argv, usage, {
|
|
10
|
+
...SCOPE,
|
|
11
|
+
...FORMAT,
|
|
12
|
+
...CONFIG,
|
|
13
|
+
k: {
|
|
14
|
+
type: 'string'
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
const [pathArg] = positionals;
|
|
18
|
+
if (!pathArg) ctx.usageError(usage);
|
|
19
|
+
const k = (_parseK = parseK(values.k, ctx.usageError)) !== null && _parseK !== void 0 ? _parseK : RELATED_DEFAULT_K;
|
|
20
|
+
const format = formatOf(values);
|
|
21
|
+
return withDb(ctx, values.config, async (db, cfg)=>{
|
|
22
|
+
const overrides = scopeOf(values);
|
|
23
|
+
printRows(await relatedNotes(db, cfg, pathArg, overrides, k), format);
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
export default relatedCmd;
|