sensemaking 0.7.2 → 0.8.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 +61 -41
- package/dist/cjs/cli/check.js +386 -0
- package/dist/cjs/cli/check.js.map +1 -0
- package/dist/cjs/{commands → cli}/find.js +3 -4
- package/dist/cjs/cli/find.js.map +1 -0
- package/dist/cjs/cli/index.js.map +1 -0
- package/dist/cjs/{commands → cli}/init.js +3 -0
- package/dist/cjs/cli/init.js.map +1 -0
- package/dist/cjs/{commands → cli}/map.js +2 -2
- package/dist/cjs/cli/map.js.map +1 -0
- package/dist/cjs/{commands → cli}/named.d.cts +1 -1
- package/dist/cjs/{commands → cli}/named.d.ts +1 -1
- package/dist/cjs/cli/named.js +209 -0
- package/dist/cjs/cli/named.js.map +1 -0
- package/dist/cjs/{commands → cli}/peek.js +2 -2
- package/dist/cjs/cli/peek.js.map +1 -0
- package/dist/cjs/cli/query.js.map +1 -0
- package/dist/cjs/cli/rebuild.js.map +1 -0
- package/dist/cjs/{commands → cli}/shared.d.cts +1 -0
- package/dist/{esm/commands → cjs/cli}/shared.d.ts +1 -0
- package/dist/cjs/{commands → cli}/shared.js +9 -0
- package/dist/cjs/cli/shared.js.map +1 -0
- package/dist/cjs/{commands → cli}/status.js +7 -1
- package/dist/cjs/cli/status.js.map +1 -0
- package/dist/cjs/cli/watch.js.map +1 -0
- package/dist/cjs/cli.js +22 -17
- package/dist/cjs/cli.js.map +1 -1
- package/dist/{esm/verbs.d.ts → cjs/commands.d.cts} +5 -4
- package/dist/cjs/{verbs.d.cts → commands.d.ts} +5 -4
- package/dist/cjs/{verbs.js → commands.js} +246 -21
- package/dist/cjs/commands.js.map +1 -0
- package/dist/cjs/config.d.cts +7 -1
- package/dist/cjs/config.d.ts +7 -1
- package/dist/cjs/config.js +75 -24
- package/dist/cjs/config.js.map +1 -1
- package/dist/cjs/db.d.cts +1 -1
- package/dist/cjs/db.d.ts +1 -1
- package/dist/cjs/db.js +88 -17
- 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.js +7 -1
- package/dist/cjs/features/embed.js.map +1 -1
- package/dist/cjs/features/links.js +201 -24
- package/dist/cjs/features/links.js.map +1 -1
- package/dist/cjs/features/rank.js +8 -1
- package/dist/cjs/features/rank.js.map +1 -1
- package/dist/cjs/features/types.d.cts +10 -3
- package/dist/cjs/features/types.d.ts +10 -3
- package/dist/cjs/index.d.cts +3 -3
- package/dist/cjs/index.d.ts +3 -3
- package/dist/cjs/index.js +4 -4
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/output.d.cts +1 -0
- package/dist/cjs/output.d.ts +1 -0
- package/dist/cjs/output.js +2 -1
- package/dist/cjs/output.js.map +1 -1
- package/dist/cjs/progress.d.cts +5 -0
- package/dist/cjs/progress.d.ts +5 -0
- package/dist/cjs/progress.js +54 -0
- package/dist/cjs/progress.js.map +1 -0
- package/dist/cjs/scan.d.cts +1 -0
- package/dist/cjs/scan.d.ts +1 -0
- package/dist/cjs/scan.js +3 -2
- package/dist/cjs/scan.js.map +1 -1
- package/dist/esm/{commands → cli}/check.js +43 -3
- package/dist/esm/cli/check.js.map +1 -0
- package/dist/esm/{commands → cli}/find.js +3 -4
- package/dist/esm/cli/find.js.map +1 -0
- package/dist/esm/cli/index.js.map +1 -0
- package/dist/esm/{commands → cli}/init.js +3 -0
- package/dist/esm/cli/init.js.map +1 -0
- package/dist/esm/{commands → cli}/map.js +1 -1
- package/dist/esm/cli/map.js.map +1 -0
- package/dist/esm/{commands → cli}/named.d.ts +1 -1
- package/dist/esm/cli/named.js +33 -0
- package/dist/esm/cli/named.js.map +1 -0
- package/dist/esm/{commands → cli}/peek.js +1 -1
- package/dist/esm/cli/peek.js.map +1 -0
- package/dist/esm/cli/query.js.map +1 -0
- package/dist/esm/cli/rebuild.js.map +1 -0
- package/dist/{cjs/commands → esm/cli}/shared.d.ts +1 -0
- package/dist/esm/{commands → cli}/shared.js +9 -0
- package/dist/esm/cli/shared.js.map +1 -0
- package/dist/esm/{commands → cli}/status.js +7 -1
- package/dist/esm/cli/status.js.map +1 -0
- package/dist/esm/cli/types.js.map +1 -0
- package/dist/esm/cli/watch.js.map +1 -0
- package/dist/esm/cli.js +8 -6
- package/dist/esm/cli.js.map +1 -1
- package/dist/{cjs/verbs.d.ts → esm/commands.d.ts} +5 -4
- package/dist/esm/{verbs.js → commands.js} +165 -21
- package/dist/esm/commands.js.map +1 -0
- package/dist/esm/config.d.ts +7 -1
- package/dist/esm/config.js +38 -4
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/db.d.ts +1 -1
- package/dist/esm/db.js +78 -16
- 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.js +6 -0
- package/dist/esm/features/embed.js.map +1 -1
- package/dist/esm/features/links.js +130 -20
- package/dist/esm/features/links.js.map +1 -1
- package/dist/esm/features/rank.js +8 -1
- package/dist/esm/features/rank.js.map +1 -1
- package/dist/esm/features/types.d.ts +10 -3
- package/dist/esm/features/types.js.map +1 -1
- package/dist/esm/index.d.ts +3 -3
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/output.d.ts +1 -0
- package/dist/esm/output.js +2 -1
- package/dist/esm/output.js.map +1 -1
- package/dist/esm/progress.d.ts +5 -0
- package/dist/esm/progress.js +44 -0
- package/dist/esm/progress.js.map +1 -0
- package/dist/esm/scan.d.ts +1 -0
- package/dist/esm/scan.js +5 -2
- package/dist/esm/scan.js.map +1 -1
- package/package.json +6 -2
- package/schema.json +19 -4
- package/skills/sense/EXAMPLES.md +9 -7
- package/skills/sense/SKILL.md +43 -27
- package/skills/sense-setup/SKILL.md +16 -2
- package/dist/cjs/commands/check.js +0 -143
- package/dist/cjs/commands/check.js.map +0 -1
- package/dist/cjs/commands/find.js.map +0 -1
- package/dist/cjs/commands/index.js.map +0 -1
- package/dist/cjs/commands/init.js.map +0 -1
- package/dist/cjs/commands/map.js.map +0 -1
- package/dist/cjs/commands/named.js +0 -23
- package/dist/cjs/commands/named.js.map +0 -1
- package/dist/cjs/commands/peek.js.map +0 -1
- package/dist/cjs/commands/query.js.map +0 -1
- package/dist/cjs/commands/rebuild.js.map +0 -1
- package/dist/cjs/commands/shared.js.map +0 -1
- package/dist/cjs/commands/status.js.map +0 -1
- package/dist/cjs/commands/watch.js.map +0 -1
- package/dist/cjs/verbs.js.map +0 -1
- package/dist/esm/commands/check.js.map +0 -1
- package/dist/esm/commands/find.js.map +0 -1
- package/dist/esm/commands/index.js.map +0 -1
- package/dist/esm/commands/init.js.map +0 -1
- package/dist/esm/commands/map.js.map +0 -1
- package/dist/esm/commands/named.js +0 -12
- package/dist/esm/commands/named.js.map +0 -1
- package/dist/esm/commands/peek.js.map +0 -1
- package/dist/esm/commands/query.js.map +0 -1
- package/dist/esm/commands/rebuild.js.map +0 -1
- package/dist/esm/commands/shared.js.map +0 -1
- package/dist/esm/commands/status.js.map +0 -1
- package/dist/esm/commands/types.js.map +0 -1
- package/dist/esm/commands/watch.js.map +0 -1
- package/dist/esm/verbs.js.map +0 -1
- /package/dist/cjs/{commands → cli}/check.d.cts +0 -0
- /package/dist/cjs/{commands → cli}/check.d.ts +0 -0
- /package/dist/cjs/{commands → cli}/find.d.cts +0 -0
- /package/dist/cjs/{commands → cli}/find.d.ts +0 -0
- /package/dist/cjs/{commands → cli}/index.d.cts +0 -0
- /package/dist/cjs/{commands → cli}/index.d.ts +0 -0
- /package/dist/cjs/{commands → cli}/index.js +0 -0
- /package/dist/cjs/{commands → cli}/init.d.cts +0 -0
- /package/dist/cjs/{commands → cli}/init.d.ts +0 -0
- /package/dist/cjs/{commands → cli}/map.d.cts +0 -0
- /package/dist/cjs/{commands → cli}/map.d.ts +0 -0
- /package/dist/cjs/{commands → cli}/peek.d.cts +0 -0
- /package/dist/cjs/{commands → cli}/peek.d.ts +0 -0
- /package/dist/cjs/{commands → cli}/query.d.cts +0 -0
- /package/dist/cjs/{commands → cli}/query.d.ts +0 -0
- /package/dist/cjs/{commands → cli}/query.js +0 -0
- /package/dist/cjs/{commands → cli}/rebuild.d.cts +0 -0
- /package/dist/cjs/{commands → cli}/rebuild.d.ts +0 -0
- /package/dist/cjs/{commands → cli}/rebuild.js +0 -0
- /package/dist/cjs/{commands → cli}/status.d.cts +0 -0
- /package/dist/cjs/{commands → cli}/status.d.ts +0 -0
- /package/dist/cjs/{commands → cli}/types.d.cts +0 -0
- /package/dist/cjs/{commands → cli}/types.d.ts +0 -0
- /package/dist/cjs/{commands → cli}/types.js +0 -0
- /package/dist/cjs/{commands → cli}/types.js.map +0 -0
- /package/dist/cjs/{commands → cli}/watch.d.cts +0 -0
- /package/dist/cjs/{commands → cli}/watch.d.ts +0 -0
- /package/dist/cjs/{commands → cli}/watch.js +0 -0
- /package/dist/esm/{commands → cli}/check.d.ts +0 -0
- /package/dist/esm/{commands → cli}/find.d.ts +0 -0
- /package/dist/esm/{commands → cli}/index.d.ts +0 -0
- /package/dist/esm/{commands → cli}/index.js +0 -0
- /package/dist/esm/{commands → cli}/init.d.ts +0 -0
- /package/dist/esm/{commands → cli}/map.d.ts +0 -0
- /package/dist/esm/{commands → cli}/peek.d.ts +0 -0
- /package/dist/esm/{commands → cli}/query.d.ts +0 -0
- /package/dist/esm/{commands → cli}/query.js +0 -0
- /package/dist/esm/{commands → cli}/rebuild.d.ts +0 -0
- /package/dist/esm/{commands → cli}/rebuild.js +0 -0
- /package/dist/esm/{commands → cli}/status.d.ts +0 -0
- /package/dist/esm/{commands → cli}/types.d.ts +0 -0
- /package/dist/esm/{commands → cli}/types.js +0 -0
- /package/dist/esm/{commands → cli}/watch.d.ts +0 -0
- /package/dist/esm/{commands → cli}/watch.js +0 -0
package/dist/cjs/index.js
CHANGED
|
@@ -24,7 +24,7 @@ _export(exports, {
|
|
|
24
24
|
return _errorsts.SenseError;
|
|
25
25
|
},
|
|
26
26
|
get find () {
|
|
27
|
-
return
|
|
27
|
+
return _commandsts.find;
|
|
28
28
|
},
|
|
29
29
|
get initConfig () {
|
|
30
30
|
return _configts.initConfig;
|
|
@@ -33,7 +33,7 @@ _export(exports, {
|
|
|
33
33
|
return _configts.loadConfig;
|
|
34
34
|
},
|
|
35
35
|
get mapTree () {
|
|
36
|
-
return
|
|
36
|
+
return _commandsts.mapTree;
|
|
37
37
|
},
|
|
38
38
|
get migrateConfig () {
|
|
39
39
|
return _configts.migrateConfig;
|
|
@@ -42,7 +42,7 @@ _export(exports, {
|
|
|
42
42
|
return _dbts.open;
|
|
43
43
|
},
|
|
44
44
|
get peek () {
|
|
45
|
-
return
|
|
45
|
+
return _commandsts.peek;
|
|
46
46
|
},
|
|
47
47
|
get printRows () {
|
|
48
48
|
return _outputts.printRows;
|
|
@@ -54,10 +54,10 @@ _export(exports, {
|
|
|
54
54
|
return _watchts.runWatch;
|
|
55
55
|
}
|
|
56
56
|
});
|
|
57
|
+
var _commandsts = require("./commands.js");
|
|
57
58
|
var _configts = require("./config.js");
|
|
58
59
|
var _dbts = require("./db.js");
|
|
59
60
|
var _errorsts = require("./errors.js");
|
|
60
61
|
var _outputts = require("./output.js");
|
|
61
|
-
var _verbsts = require("./verbs.js");
|
|
62
62
|
var _watchts = require("./watch.js");
|
|
63
63
|
/* 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/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/index.ts"],"sourcesContent":["// Public library API. Deliberately small: every export is a stability promise;\n// internals (feature registry, graph, scan, meta) stay module-private.\n\nexport type { Config, EmbedConfig, FeatureName, ResolvedConfig } from './config.ts';\nexport { CONFIG_FILENAME, initConfig, loadConfig, migrateConfig, STATE_DIR, SUPPORTED_CONFIG_VERSION } from './config.ts';\
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/index.ts"],"sourcesContent":["// Public library API. Deliberately small: every export is a stability promise;\n// internals (feature registry, graph, scan, meta) stay module-private.\n\nexport type { FindOptions, Peek, TreeMap } from './commands.ts';\nexport { find, mapTree, peek } from './commands.ts';\nexport type { Config, EmbedConfig, FeatureName, ResolvedConfig, SavedFind } from './config.ts';\nexport { CONFIG_FILENAME, initConfig, loadConfig, migrateConfig, STATE_DIR, SUPPORTED_CONFIG_VERSION } from './config.ts';\nexport type { OpenResult } from './db.ts';\nexport { open, rebuild } from './db.ts';\nexport type { SenseErrorCode } from './errors.ts';\nexport { SenseError } from './errors.ts';\nexport type { Row } from './output.ts';\nexport { printRows } from './output.ts';\n\nexport type { WatchEvent, WatchOptions } from './watch.ts';\nexport { runWatch } from './watch.ts';\n"],"names":["CONFIG_FILENAME","STATE_DIR","SUPPORTED_CONFIG_VERSION","SenseError","find","initConfig","loadConfig","mapTree","migrateConfig","open","peek","printRows","rebuild","runWatch"],"mappings":"AAAA,+EAA+E;AAC/E,uEAAuE;;;;;;;;;;;;QAK9DA;eAAAA,yBAAe;;QAAyCC;eAAAA,mBAAS;;QAAEC;eAAAA,kCAAwB;;QAI3FC;eAAAA,oBAAU;;QANVC;eAAAA,gBAAI;;QAEaC;eAAAA,oBAAU;;QAAEC;eAAAA,oBAAU;;QAFjCC;eAAAA,mBAAO;;QAE4BC;eAAAA,uBAAa;;QAEtDC;eAAAA,UAAI;;QAJWC;eAAAA,gBAAI;;QAQnBC;eAAAA,mBAAS;;QAJHC;eAAAA,aAAO;;QAObC;eAAAA,iBAAQ;;;0BAXmB;wBAEwE;oBAE9E;wBAEH;wBAED;uBAGD"}
|
package/dist/cjs/output.d.cts
CHANGED
package/dist/cjs/output.d.ts
CHANGED
package/dist/cjs/output.js
CHANGED
|
@@ -146,7 +146,7 @@ function renderRows(rows, format) {
|
|
|
146
146
|
}).join(' ')
|
|
147
147
|
].concat(_to_consumable_array(cells.map(formatRow))).join('\n');
|
|
148
148
|
}
|
|
149
|
-
// Text renderers for the layer
|
|
149
|
+
// Text renderers for the layer commands; cli.ts prints what these return.
|
|
150
150
|
function featuresLine(features) {
|
|
151
151
|
var off = features.off.length > 0 ? " \xb7 off: ".concat(features.off.map(function(name) {
|
|
152
152
|
return "".concat(name, " (features.").concat(name, ")");
|
|
@@ -211,6 +211,7 @@ function renderPeek(result) {
|
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
|
+
if (result.sectionsTotal > result.sections.length) lines.push(" (+".concat(result.sectionsTotal - result.sections.length, " more sections -- sections table has all of them)"));
|
|
214
215
|
} else if (result.off.includes('sections')) lines.push('', 'sections: off (features.sections)');
|
|
215
216
|
if (result.off.includes('links')) {
|
|
216
217
|
lines.push('', 'links: off (features.links)');
|
package/dist/cjs/output.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/output.ts"],"sourcesContent":["// rows -> table (default) | json\n\nexport type Row = Record<string, unknown>;\n\n// Warned about on stderr (keeps --format json stdout machine-readable), never truncated.\nconst OVERSIZE_BYTES = 50_000;\n\n// Flatten embedded newlines so they can't break table column alignment; JSON output is left alone.\nfunction cell(value: unknown): string {\n return String(value ?? '').replace(/\\s*\\n\\s*/g, ' ');\n}\n\nexport function printRows(rows: Row[], format: 'table' | 'json'): void {\n const rendered = renderRows(rows, format);\n console.log(rendered);\n if (rendered.length > OVERSIZE_BYTES) {\n console.warn(`warning: result is ${Math.round(rendered.length / 1000)} KB across ${rows.length} row(s); consider a LIMIT, fewer columns, or snippet() instead of whole values`);\n }\n}\n\n// Table output is for reading; a row wider than the terminal wraps into an unreadable\n// block (a `find` header measured 330 chars once `summary` is present, which drove one\n// user to pipe --format json through a script for every interactive query). Widest\n// columns give up space first, down to a floor, and only as far as the terminal needs.\n// --format json is never truncated: it is the machine-readable surface.\nconst MIN_COLUMN = 12;\nconst TRUNCATED = '…';\n\nfunction fitWidths(widths: number[], limit: number): number[] {\n const gaps = (widths.length - 1) * 2;\n const fitted = [...widths];\n for (;;) {\n const total = fitted.reduce((a, b) => a + b, 0) + gaps;\n if (total <= limit) return fitted;\n const widest = fitted.indexOf(Math.max(...fitted));\n if (fitted[widest] <= MIN_COLUMN) return fitted;\n fitted[widest] = Math.max(MIN_COLUMN, fitted[widest] - Math.max(1, total - limit));\n }\n}\n\nfunction renderRows(rows: Row[], format: 'table' | 'json', width = process.stdout.columns): string {\n if (format === 'json') return JSON.stringify(rows, null, 2);\n if (rows.length === 0) return '(0 rows)';\n\n const columns = Object.keys(rows[0]);\n const cells = rows.map((row) => columns.map((col) => cell(row[col])));\n const natural = columns.map((col, i) => Math.max(col.length, ...cells.map((row) => row[i].length)));\n const widths = width && width > MIN_COLUMN ? fitWidths(natural, width) : natural;\n\n const clip = (value: string, w: number) => (value.length <= w ? value.padEnd(w) : `${value.slice(0, w - 1)}${TRUNCATED}`);\n const formatRow = (values: string[]) =>\n values\n .map((value, i) => clip(value, widths[i]))\n .join(' ')\n .trimEnd();\n\n return [formatRow(columns), widths.map((w) => '-'.repeat(w)).join(' '), ...cells.map(formatRow)].join('\\n');\n}\n\n// Text renderers for the layer verbs; cli.ts prints what these return.\n\nfunction featuresLine(features: { on: string[]; off: string[] }): string {\n const off = features.off.length > 0 ? ` · off: ${features.off.map((name) => `${name} (features.${name})`).join(', ')}` : '';\n return `features: ${features.on.join(', ')}${off}`;\n}\n\nexport function renderMap(result: { docs: { count: number; bytes: number }; fields: Row[]; fieldsTotal: number; features: { on: string[]; off: string[] }; hubs: Row[]; recent: Row[] }): string {\n const parts = [`docs: ${result.docs.count} (${Math.round(result.docs.bytes / 1024)} KB)`, `${featuresLine(result.features)}\\n`, renderRows(result.fields, 'table')];\n if (result.fieldsTotal > result.fields.length) parts.push(`(+${result.fieldsTotal - result.fields.length} more fields)`);\n if (result.hubs.length > 0) parts.push('\\nhubs (by link rank):', renderRows(result.hubs, 'table'));\n else if (result.features.off.includes('rank')) parts.push('\\nhubs: off (features.rank)');\n parts.push('\\nrecent:', renderRows(result.recent, 'table'));\n return parts.join('\\n');\n}\n\nexport function renderPeek(result: { path: string; tokens: number; frontmatter: Row; sections: Row[]; outbound: string[]; backlinks: string[]; unresolved: string[]; outboundTotal: number; backlinksTotal: number; unresolvedTotal: number; off: string[] }): string {\n const lines = [`${result.path} (~${result.tokens} tokens)`];\n for (const [key, value] of Object.entries(result.frontmatter)) lines.push(` ${key}: ${value}`);\n if (result.sections.length > 0) {\n lines.push('', 'sections:');\n for (const s of result.sections) lines.push(` ${'#'.repeat(s.level as number)} ${s.heading} [L${s.start_line}-${s.end_line}, ~${s.tokens}t]`);\n } else if (result.off.includes('sections')) lines.push('', 'sections: off (features.sections)');\n if (result.off.includes('links')) {\n lines.push('', 'links: off (features.links)');\n return lines.join('\\n');\n }\n const linkLine = (label: string, shown: string[], total: number) => {\n if (total > 0) lines.push(`${label} (${total}): ${shown.join(', ')}${total > shown.length ? `, +${total - shown.length} more` : ''}`);\n };\n if (result.outboundTotal + result.unresolvedTotal + result.backlinksTotal > 0) lines.push('');\n linkLine('links out', result.outbound, result.outboundTotal);\n linkLine('unresolved', result.unresolved, result.unresolvedTotal);\n linkLine('backlinks', result.backlinks, result.backlinksTotal);\n return lines.join('\\n');\n}\n"],"names":["printRows","renderMap","renderPeek","OVERSIZE_BYTES","cell","value","String","replace","rows","format","rendered","renderRows","console","log","length","warn","Math","round","MIN_COLUMN","TRUNCATED","fitWidths","widths","limit","gaps","fitted","total","reduce","a","b","widest","indexOf","max","width","process","stdout","columns","JSON","stringify","Object","keys","cells","map","row","col","natural","i","clip","w","padEnd","slice","formatRow","values","join","trimEnd","repeat","featuresLine","features","off","name","on","result","parts","docs","count","bytes","fields","fieldsTotal","push","hubs","includes","recent","lines","path","tokens","entries","frontmatter","key","sections","s","level","heading","start_line","end_line","linkLine","label","shown","outboundTotal","unresolvedTotal","backlinksTotal","outbound","unresolved","backlinks"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/output.ts"],"sourcesContent":["// rows -> table (default) | json\n\nexport type Row = Record<string, unknown>;\n\n// Warned about on stderr (keeps --format json stdout machine-readable), never truncated.\nconst OVERSIZE_BYTES = 50_000;\n\n// Flatten embedded newlines so they can't break table column alignment; JSON output is left alone.\nfunction cell(value: unknown): string {\n return String(value ?? '').replace(/\\s*\\n\\s*/g, ' ');\n}\n\nexport function printRows(rows: Row[], format: 'table' | 'json'): void {\n const rendered = renderRows(rows, format);\n console.log(rendered);\n if (rendered.length > OVERSIZE_BYTES) {\n console.warn(`warning: result is ${Math.round(rendered.length / 1000)} KB across ${rows.length} row(s); consider a LIMIT, fewer columns, or snippet() instead of whole values`);\n }\n}\n\n// Table output is for reading; a row wider than the terminal wraps into an unreadable\n// block (a `find` header measured 330 chars once `summary` is present, which drove one\n// user to pipe --format json through a script for every interactive query). Widest\n// columns give up space first, down to a floor, and only as far as the terminal needs.\n// --format json is never truncated: it is the machine-readable surface.\nconst MIN_COLUMN = 12;\nconst TRUNCATED = '…';\n\nfunction fitWidths(widths: number[], limit: number): number[] {\n const gaps = (widths.length - 1) * 2;\n const fitted = [...widths];\n for (;;) {\n const total = fitted.reduce((a, b) => a + b, 0) + gaps;\n if (total <= limit) return fitted;\n const widest = fitted.indexOf(Math.max(...fitted));\n if (fitted[widest] <= MIN_COLUMN) return fitted;\n fitted[widest] = Math.max(MIN_COLUMN, fitted[widest] - Math.max(1, total - limit));\n }\n}\n\nfunction renderRows(rows: Row[], format: 'table' | 'json', width = process.stdout.columns): string {\n if (format === 'json') return JSON.stringify(rows, null, 2);\n if (rows.length === 0) return '(0 rows)';\n\n const columns = Object.keys(rows[0]);\n const cells = rows.map((row) => columns.map((col) => cell(row[col])));\n const natural = columns.map((col, i) => Math.max(col.length, ...cells.map((row) => row[i].length)));\n const widths = width && width > MIN_COLUMN ? fitWidths(natural, width) : natural;\n\n const clip = (value: string, w: number) => (value.length <= w ? value.padEnd(w) : `${value.slice(0, w - 1)}${TRUNCATED}`);\n const formatRow = (values: string[]) =>\n values\n .map((value, i) => clip(value, widths[i]))\n .join(' ')\n .trimEnd();\n\n return [formatRow(columns), widths.map((w) => '-'.repeat(w)).join(' '), ...cells.map(formatRow)].join('\\n');\n}\n\n// Text renderers for the layer commands; cli.ts prints what these return.\n\nfunction featuresLine(features: { on: string[]; off: string[] }): string {\n const off = features.off.length > 0 ? ` · off: ${features.off.map((name) => `${name} (features.${name})`).join(', ')}` : '';\n return `features: ${features.on.join(', ')}${off}`;\n}\n\nexport function renderMap(result: { docs: { count: number; bytes: number }; fields: Row[]; fieldsTotal: number; features: { on: string[]; off: string[] }; hubs: Row[]; recent: Row[] }): string {\n const parts = [`docs: ${result.docs.count} (${Math.round(result.docs.bytes / 1024)} KB)`, `${featuresLine(result.features)}\\n`, renderRows(result.fields, 'table')];\n if (result.fieldsTotal > result.fields.length) parts.push(`(+${result.fieldsTotal - result.fields.length} more fields)`);\n if (result.hubs.length > 0) parts.push('\\nhubs (by link rank):', renderRows(result.hubs, 'table'));\n else if (result.features.off.includes('rank')) parts.push('\\nhubs: off (features.rank)');\n parts.push('\\nrecent:', renderRows(result.recent, 'table'));\n return parts.join('\\n');\n}\n\nexport function renderPeek(result: { path: string; tokens: number; frontmatter: Row; sections: Row[]; outbound: string[]; backlinks: string[]; unresolved: string[]; sectionsTotal: number; outboundTotal: number; backlinksTotal: number; unresolvedTotal: number; off: string[] }): string {\n const lines = [`${result.path} (~${result.tokens} tokens)`];\n for (const [key, value] of Object.entries(result.frontmatter)) lines.push(` ${key}: ${value}`);\n if (result.sections.length > 0) {\n lines.push('', 'sections:');\n for (const s of result.sections) lines.push(` ${'#'.repeat(s.level as number)} ${s.heading} [L${s.start_line}-${s.end_line}, ~${s.tokens}t]`);\n if (result.sectionsTotal > result.sections.length) lines.push(` (+${result.sectionsTotal - result.sections.length} more sections -- sections table has all of them)`);\n } else if (result.off.includes('sections')) lines.push('', 'sections: off (features.sections)');\n if (result.off.includes('links')) {\n lines.push('', 'links: off (features.links)');\n return lines.join('\\n');\n }\n const linkLine = (label: string, shown: string[], total: number) => {\n if (total > 0) lines.push(`${label} (${total}): ${shown.join(', ')}${total > shown.length ? `, +${total - shown.length} more` : ''}`);\n };\n if (result.outboundTotal + result.unresolvedTotal + result.backlinksTotal > 0) lines.push('');\n linkLine('links out', result.outbound, result.outboundTotal);\n linkLine('unresolved', result.unresolved, result.unresolvedTotal);\n linkLine('backlinks', result.backlinks, result.backlinksTotal);\n return lines.join('\\n');\n}\n"],"names":["printRows","renderMap","renderPeek","OVERSIZE_BYTES","cell","value","String","replace","rows","format","rendered","renderRows","console","log","length","warn","Math","round","MIN_COLUMN","TRUNCATED","fitWidths","widths","limit","gaps","fitted","total","reduce","a","b","widest","indexOf","max","width","process","stdout","columns","JSON","stringify","Object","keys","cells","map","row","col","natural","i","clip","w","padEnd","slice","formatRow","values","join","trimEnd","repeat","featuresLine","features","off","name","on","result","parts","docs","count","bytes","fields","fieldsTotal","push","hubs","includes","recent","lines","path","tokens","entries","frontmatter","key","sections","s","level","heading","start_line","end_line","sectionsTotal","linkLine","label","shown","outboundTotal","unresolvedTotal","backlinksTotal","outbound","unresolved","backlinks"],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "progress", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return progress;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
// Long-work progress on stderr only: stdout stays the parseable answer, so progress can
|
|
12
|
+
// never corrupt --format json (the same channel warnings already use). TTY-aware: a human
|
|
13
|
+
// terminal gets one self-overwriting line; a non-TTY consumer (agent, pipe, CI) gets at
|
|
14
|
+
// most a few append-only lines -- an agent transcript gains lines, not redraw frames.
|
|
15
|
+
var NON_TTY_MILESTONES = 4;
|
|
16
|
+
function progress(label, total) {
|
|
17
|
+
var threshold = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 200;
|
|
18
|
+
if (total < threshold) return {
|
|
19
|
+
tick: function tick() {},
|
|
20
|
+
finish: function finish() {}
|
|
21
|
+
};
|
|
22
|
+
var started = Date.now();
|
|
23
|
+
var isTTY = process.stderr.isTTY === true;
|
|
24
|
+
var lastShown = 0;
|
|
25
|
+
var wrote = false;
|
|
26
|
+
var line = function line(done) {
|
|
27
|
+
var elapsed = (Date.now() - started) / 1000;
|
|
28
|
+
// Estimate from observed rate, only once there is a rate to observe.
|
|
29
|
+
var eta = done > 0 && done < total ? ", ~".concat(Math.max(1, Math.round(elapsed / done * (total - done))), "s left") : '';
|
|
30
|
+
return "".concat(label, ": ").concat(done, "/").concat(total).concat(eta);
|
|
31
|
+
};
|
|
32
|
+
return {
|
|
33
|
+
tick: function tick(done) {
|
|
34
|
+
if (isTTY) {
|
|
35
|
+
process.stderr.write("\r".concat(line(done)));
|
|
36
|
+
wrote = true;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
// Sparse milestones: first tick, then every 1/NON_TTY_MILESTONES of the total.
|
|
40
|
+
if (done === lastShown) return;
|
|
41
|
+
if (lastShown === 0 || done - lastShown >= total / NON_TTY_MILESTONES) {
|
|
42
|
+
process.stderr.write("".concat(line(done), "\n"));
|
|
43
|
+
lastShown = done;
|
|
44
|
+
wrote = true;
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
finish: function finish() {
|
|
48
|
+
if (!wrote) return;
|
|
49
|
+
if (isTTY) process.stderr.write("\r".concat(line(total), "\n"));
|
|
50
|
+
else if (lastShown < total) process.stderr.write("".concat(line(total), "\n"));
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/* 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/progress.ts"],"sourcesContent":["// Long-work progress on stderr only: stdout stays the parseable answer, so progress can\n// never corrupt --format json (the same channel warnings already use). TTY-aware: a human\n// terminal gets one self-overwriting line; a non-TTY consumer (agent, pipe, CI) gets at\n// most a few append-only lines -- an agent transcript gains lines, not redraw frames.\n\nconst NON_TTY_MILESTONES = 4;\n\nexport interface Progress {\n tick(done: number): void;\n finish(): void;\n}\n\n// `total` known upfront; `label` names the work (\"embedding notes\", \"reparsing files\").\n// Silent entirely below `threshold` -- short work needs no narration.\nexport function progress(label: string, total: number, threshold = 200): Progress {\n if (total < threshold) return { tick() {}, finish() {} };\n\n const started = Date.now();\n const isTTY = process.stderr.isTTY === true;\n let lastShown = 0;\n let wrote = false;\n\n const line = (done: number) => {\n const elapsed = (Date.now() - started) / 1000;\n // Estimate from observed rate, only once there is a rate to observe.\n const eta = done > 0 && done < total ? `, ~${Math.max(1, Math.round((elapsed / done) * (total - done)))}s left` : '';\n return `${label}: ${done}/${total}${eta}`;\n };\n\n return {\n tick(done: number) {\n if (isTTY) {\n process.stderr.write(`\\r${line(done)}`);\n wrote = true;\n return;\n }\n // Sparse milestones: first tick, then every 1/NON_TTY_MILESTONES of the total.\n if (done === lastShown) return;\n if (lastShown === 0 || done - lastShown >= total / NON_TTY_MILESTONES) {\n process.stderr.write(`${line(done)}\\n`);\n lastShown = done;\n wrote = true;\n }\n },\n finish() {\n if (!wrote) return;\n if (isTTY) process.stderr.write(`\\r${line(total)}\\n`);\n else if (lastShown < total) process.stderr.write(`${line(total)}\\n`);\n },\n };\n}\n"],"names":["progress","NON_TTY_MILESTONES","label","total","threshold","tick","finish","started","Date","now","isTTY","process","stderr","lastShown","wrote","line","done","elapsed","eta","Math","max","round","write"],"mappings":";;;;+BAcgBA;;;eAAAA;;;AAdhB,wFAAwF;AACxF,0FAA0F;AAC1F,wFAAwF;AACxF,sFAAsF;AAEtF,IAAMC,qBAAqB;AASpB,SAASD,SAASE,KAAa,EAAEC,KAAa;QAAEC,YAAAA,iEAAY;IACjE,IAAID,QAAQC,WAAW,OAAO;QAAEC,MAAAA,SAAAA,QAAQ;QAAGC,QAAAA,SAAAA,UAAU;IAAE;IAEvD,IAAMC,UAAUC,KAAKC,GAAG;IACxB,IAAMC,QAAQC,QAAQC,MAAM,CAACF,KAAK,KAAK;IACvC,IAAIG,YAAY;IAChB,IAAIC,QAAQ;IAEZ,IAAMC,OAAO,cAACC;QACZ,IAAMC,UAAU,AAACT,CAAAA,KAAKC,GAAG,KAAKF,OAAM,IAAK;QACzC,qEAAqE;QACrE,IAAMW,MAAMF,OAAO,KAAKA,OAAOb,QAAQ,AAAC,MAAgE,OAA3DgB,KAAKC,GAAG,CAAC,GAAGD,KAAKE,KAAK,CAAC,AAACJ,UAAUD,OAASb,CAAAA,QAAQa,IAAG,KAAK,YAAU;QAClH,OAAO,AAAC,GAAYA,OAAVd,OAAM,MAAYC,OAARa,MAAK,KAAWE,OAARf,OAAY,OAAJe;IACtC;IAEA,OAAO;QACLb,MAAAA,SAAAA,KAAKW,IAAY;YACf,IAAIN,OAAO;gBACTC,QAAQC,MAAM,CAACU,KAAK,CAAC,AAAC,KAAe,OAAXP,KAAKC;gBAC/BF,QAAQ;gBACR;YACF;YACA,+EAA+E;YAC/E,IAAIE,SAASH,WAAW;YACxB,IAAIA,cAAc,KAAKG,OAAOH,aAAaV,QAAQF,oBAAoB;gBACrEU,QAAQC,MAAM,CAACU,KAAK,CAAC,AAAC,GAAa,OAAXP,KAAKC,OAAM;gBACnCH,YAAYG;gBACZF,QAAQ;YACV;QACF;QACAR,QAAAA,SAAAA;YACE,IAAI,CAACQ,OAAO;YACZ,IAAIJ,OAAOC,QAAQC,MAAM,CAACU,KAAK,CAAC,AAAC,KAAgB,OAAZP,KAAKZ,QAAO;iBAC5C,IAAIU,YAAYV,OAAOQ,QAAQC,MAAM,CAACU,KAAK,CAAC,AAAC,GAAc,OAAZP,KAAKZ,QAAO;QAClE;IACF;AACF"}
|
package/dist/cjs/scan.d.cts
CHANGED
package/dist/cjs/scan.d.ts
CHANGED
package/dist/cjs/scan.js
CHANGED
|
@@ -9,6 +9,9 @@ function _export(target, all) {
|
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
11
|
_export(exports, {
|
|
12
|
+
get RESERVED_COLUMNS () {
|
|
13
|
+
return RESERVED_COLUMNS;
|
|
14
|
+
},
|
|
12
15
|
get listFiles () {
|
|
13
16
|
return listFiles;
|
|
14
17
|
},
|
|
@@ -30,8 +33,6 @@ function _type_of(obj) {
|
|
|
30
33
|
"@swc/helpers - typeof";
|
|
31
34
|
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
32
35
|
}
|
|
33
|
-
// Filesystem -> rows. Pure data in, data + warnings out; db.ts does the SQL.
|
|
34
|
-
// Reserved: colliding with these would clash with the `frontmatter` table's own columns or the other tables (`content`, `links`, `sections`).
|
|
35
36
|
var RESERVED_COLUMNS = new Set([
|
|
36
37
|
'path',
|
|
37
38
|
'_mtime',
|
package/dist/cjs/scan.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/scan.ts"],"sourcesContent":["import { readFileSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport fastGlob from 'fast-glob';\nimport removeMarkdown from 'remove-markdown';\nimport { parseDocument } from 'yaml';\nimport type { Config } from './config.ts';\nimport type { Feature } from './features/types.ts';\n\n// Filesystem -> rows. Pure data in, data + warnings out; db.ts does the SQL.\n\n// Reserved: colliding with these would clash with the `frontmatter` table's own columns or the other tables (`content`, `links`, `sections`).\nconst RESERVED_COLUMNS = new Set(['path', '_mtime', '_size', '_rank', 'content', 'links', 'sections']);\n\nfunction normalizeText(value: unknown): string {\n if (value === null || value === undefined) return '';\n return String(value).replace(/\\s+/g, ' ').trim();\n}\n\n// Markdown is stripped at index time so snippets read as clean prose (also improves matching, e.g. `**bold**` indexes as `bold`).\n// remove-markdown doesn't cover Obsidian wikilinks or table scaffolding, so those are handled first/after.\nfunction stripText(value: string): string {\n const withoutWikilinks = value.replace(/\\[\\[([^\\]|]+)\\|([^\\]]+)\\]\\]/g, '$2').replace(/\\[\\[([^\\]]+)\\]\\]/g, '$1');\n const withoutMarkdown = removeMarkdown(withoutWikilinks);\n const withoutTables = withoutMarkdown.replace(/^\\s*\\|?[-\\s|:]+\\|\\s*$/gm, '').replace(/\\|/g, ' ');\n return normalizeText(withoutTables);\n}\n\nexport interface FileStat {\n relPath: string;\n absPath: string;\n mtimeMs: number;\n size: number;\n}\n\nexport function listFiles(cfg: Config, baseDir: string): FileStat[] {\n const relPaths = fastGlob.sync(cfg.scan.include, { cwd: baseDir }).sort();\n return relPaths.map((relPath) => {\n const absPath = join(baseDir, relPath);\n const st = statSync(absPath);\n return { relPath, absPath, mtimeMs: st.mtimeMs, size: st.size };\n });\n}\n\nexport interface ParsedDoc {\n relPath: string;\n mtimeMs: number;\n size: number;\n data: Record<string, string | number | bigint | null>;\n // title/summary are duplicated from frontmatter so bm25() can weight them above the body text.\n search: { title: string; summary: string; text: string };\n // Per-feature extraction results, keyed by feature name; features store them at reconcile.\n extracted: Record<string, unknown>;\n}\n\n// SQLite storage classes follow the YAML scalar: strings -> TEXT, booleans and whole\n// numbers -> INTEGER, fractions -> REAL, everything else (lists, maps) -> JSON TEXT.\n// Booleans have no SQLite type of their own; 1/0 is the convention, so `WHERE flag = 1`\n// matches and `WHERE flag = 'true'` cannot -- `map` prints the observed type per field so\n// that mismatch is visible rather than a silent zero-row answer.\nfunction mapValue(value: unknown): string | number | bigint | null {\n if (value === null || value === undefined) return null;\n if (typeof value === 'boolean') return BigInt(value ? 1 : 0);\n if (typeof value === 'number') return Number.isSafeInteger(value) ? BigInt(value) : value;\n if (typeof value === 'string') return value;\n return JSON.stringify(value);\n}\n\n// The delimiter split is all this package used gray-matter for.\nfunction splitFrontmatter(raw: string): { fm: string | null; body: string } {\n const open = raw.match(/^---\\r?\\n/);\n if (!open) return { fm: null, body: raw };\n const rest = raw.slice(open[0].length);\n const close = rest.match(/^---\\r?(\\n|$)/m);\n if (!close || close.index === undefined) return { fm: null, body: raw };\n return { fm: rest.slice(0, close.index), body: rest.slice(close.index + close[0].length) };\n}\n\n// Lenient by design: parseDocument collects syntax errors as data and still yields values,\n// so Obsidian-style frontmatter (e.g. an alias starting with @) survives with a warning.\nfunction parseFrontmatter(relPath: string, fm: string, warnings: string[]): Record<string, unknown> {\n const doc = parseDocument(fm);\n if (doc.errors.length > 0) {\n warnings.push(`warning: ${relPath} frontmatter has ${doc.errors.length} syntax error(s) (${doc.errors[0].message.split('\\n')[0]}); parsed leniently`);\n }\n let data: unknown;\n try {\n data = doc.toJS();\n } catch (err) {\n warnings.push(`warning: ${relPath} has unparseable frontmatter (${(err as Error).message.split('\\n')[0]}); indexing without it`);\n return {};\n }\n if (data === null || data === undefined) return {};\n if (typeof data !== 'object' || Array.isArray(data)) {\n warnings.push(`warning: ${relPath} frontmatter is not a key-value mapping; ignoring it`);\n return {};\n }\n return data as Record<string, unknown>;\n}\n\nexport function parseFile(file: FileStat, extractors: Feature[] = []): { doc: ParsedDoc; warnings: string[] } {\n const raw = readFileSync(file.absPath, 'utf8');\n const warnings: string[] = [];\n\n const { fm, body: content } = splitFrontmatter(raw);\n const data = fm === null ? {} : parseFrontmatter(file.relPath, fm, warnings);\n const mapped: Record<string, string | number | bigint | null> = {};\n\n for (const key of Object.keys(data)) {\n if (RESERVED_COLUMNS.has(key)) {\n warnings.push(`warning: ${file.relPath} has a frontmatter key named \"${key}\", which is reserved; ignoring it`);\n continue;\n }\n mapped[key] = mapValue(data[key]);\n }\n\n // title/summary are plain YAML strings -- whitespace-collapse only;\n // the prose gets the full markdown strip.\n const search = { title: normalizeText(data.title), summary: normalizeText(data.summary), text: stripText(content) };\n\n return {\n doc: {\n relPath: file.relPath,\n mtimeMs: file.mtimeMs,\n size: file.size,\n data: mapped,\n search,\n extracted: Object.fromEntries(extractors.filter((f) => f.extract).map((f) => [f.name, f.extract?.(raw, content, search)])),\n },\n warnings,\n };\n}\n"],"names":["listFiles","parseFile","RESERVED_COLUMNS","Set","normalizeText","value","undefined","String","replace","trim","stripText","withoutWikilinks","withoutMarkdown","removeMarkdown","withoutTables","cfg","baseDir","relPaths","fastGlob","sync","scan","include","cwd","sort","map","relPath","absPath","join","st","statSync","mtimeMs","size","mapValue","BigInt","Number","isSafeInteger","JSON","stringify","splitFrontmatter","raw","open","match","fm","body","rest","slice","length","close","index","parseFrontmatter","warnings","doc","parseDocument","errors","push","message","split","data","toJS","err","Array","isArray","file","extractors","readFileSync","content","mapped","Object","keys","key","has","search","title","summary","text","extracted","fromEntries","filter","f","extract","name"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/scan.ts"],"sourcesContent":["import { readFileSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport fastGlob from 'fast-glob';\nimport removeMarkdown from 'remove-markdown';\nimport { parseDocument } from 'yaml';\nimport type { Config } from './config.ts';\nimport type { Feature } from './features/types.ts';\n\n// Filesystem -> rows. Pure data in, data + warnings out; db.ts does the SQL.\n\n// Reserved: colliding with these would clash with the `frontmatter` table's own columns or\n// the other tables (`content`, `links`, `sections`). Exported so db.ts's frontmatter upsert\n// can tell a feature-owned column (e.g. rank's `_rank`) apart from a parsed frontmatter\n// column and leave the former alone on reparse.\nexport const RESERVED_COLUMNS = new Set(['path', '_mtime', '_size', '_rank', 'content', 'links', 'sections']);\n\nfunction normalizeText(value: unknown): string {\n if (value === null || value === undefined) return '';\n return String(value).replace(/\\s+/g, ' ').trim();\n}\n\n// Markdown is stripped at index time so snippets read as clean prose (also improves matching, e.g. `**bold**` indexes as `bold`).\n// remove-markdown doesn't cover Obsidian wikilinks or table scaffolding, so those are handled first/after.\nfunction stripText(value: string): string {\n const withoutWikilinks = value.replace(/\\[\\[([^\\]|]+)\\|([^\\]]+)\\]\\]/g, '$2').replace(/\\[\\[([^\\]]+)\\]\\]/g, '$1');\n const withoutMarkdown = removeMarkdown(withoutWikilinks);\n const withoutTables = withoutMarkdown.replace(/^\\s*\\|?[-\\s|:]+\\|\\s*$/gm, '').replace(/\\|/g, ' ');\n return normalizeText(withoutTables);\n}\n\nexport interface FileStat {\n relPath: string;\n absPath: string;\n mtimeMs: number;\n size: number;\n}\n\nexport function listFiles(cfg: Config, baseDir: string): FileStat[] {\n const relPaths = fastGlob.sync(cfg.scan.include, { cwd: baseDir }).sort();\n return relPaths.map((relPath) => {\n const absPath = join(baseDir, relPath);\n const st = statSync(absPath);\n return { relPath, absPath, mtimeMs: st.mtimeMs, size: st.size };\n });\n}\n\nexport interface ParsedDoc {\n relPath: string;\n mtimeMs: number;\n size: number;\n data: Record<string, string | number | bigint | null>;\n // title/summary are duplicated from frontmatter so bm25() can weight them above the body text.\n search: { title: string; summary: string; text: string };\n // Per-feature extraction results, keyed by feature name; features store them at reconcile.\n extracted: Record<string, unknown>;\n}\n\n// SQLite storage classes follow the YAML scalar: strings -> TEXT, booleans and whole\n// numbers -> INTEGER, fractions -> REAL, everything else (lists, maps) -> JSON TEXT.\n// Booleans have no SQLite type of their own; 1/0 is the convention, so `WHERE flag = 1`\n// matches and `WHERE flag = 'true'` cannot -- `map` prints the observed type per field so\n// that mismatch is visible rather than a silent zero-row answer.\nfunction mapValue(value: unknown): string | number | bigint | null {\n if (value === null || value === undefined) return null;\n if (typeof value === 'boolean') return BigInt(value ? 1 : 0);\n if (typeof value === 'number') return Number.isSafeInteger(value) ? BigInt(value) : value;\n if (typeof value === 'string') return value;\n return JSON.stringify(value);\n}\n\n// The delimiter split is all this package used gray-matter for.\nfunction splitFrontmatter(raw: string): { fm: string | null; body: string } {\n const open = raw.match(/^---\\r?\\n/);\n if (!open) return { fm: null, body: raw };\n const rest = raw.slice(open[0].length);\n const close = rest.match(/^---\\r?(\\n|$)/m);\n if (!close || close.index === undefined) return { fm: null, body: raw };\n return { fm: rest.slice(0, close.index), body: rest.slice(close.index + close[0].length) };\n}\n\n// Lenient by design: parseDocument collects syntax errors as data and still yields values,\n// so Obsidian-style frontmatter (e.g. an alias starting with @) survives with a warning.\nfunction parseFrontmatter(relPath: string, fm: string, warnings: string[]): Record<string, unknown> {\n const doc = parseDocument(fm);\n if (doc.errors.length > 0) {\n warnings.push(`warning: ${relPath} frontmatter has ${doc.errors.length} syntax error(s) (${doc.errors[0].message.split('\\n')[0]}); parsed leniently`);\n }\n let data: unknown;\n try {\n data = doc.toJS();\n } catch (err) {\n warnings.push(`warning: ${relPath} has unparseable frontmatter (${(err as Error).message.split('\\n')[0]}); indexing without it`);\n return {};\n }\n if (data === null || data === undefined) return {};\n if (typeof data !== 'object' || Array.isArray(data)) {\n warnings.push(`warning: ${relPath} frontmatter is not a key-value mapping; ignoring it`);\n return {};\n }\n return data as Record<string, unknown>;\n}\n\nexport function parseFile(file: FileStat, extractors: Feature[] = []): { doc: ParsedDoc; warnings: string[] } {\n const raw = readFileSync(file.absPath, 'utf8');\n const warnings: string[] = [];\n\n const { fm, body: content } = splitFrontmatter(raw);\n const data = fm === null ? {} : parseFrontmatter(file.relPath, fm, warnings);\n const mapped: Record<string, string | number | bigint | null> = {};\n\n for (const key of Object.keys(data)) {\n if (RESERVED_COLUMNS.has(key)) {\n warnings.push(`warning: ${file.relPath} has a frontmatter key named \"${key}\", which is reserved; ignoring it`);\n continue;\n }\n mapped[key] = mapValue(data[key]);\n }\n\n // title/summary are plain YAML strings -- whitespace-collapse only;\n // the prose gets the full markdown strip.\n const search = { title: normalizeText(data.title), summary: normalizeText(data.summary), text: stripText(content) };\n\n return {\n doc: {\n relPath: file.relPath,\n mtimeMs: file.mtimeMs,\n size: file.size,\n data: mapped,\n search,\n extracted: Object.fromEntries(extractors.filter((f) => f.extract).map((f) => [f.name, f.extract?.(raw, content, search)])),\n },\n warnings,\n };\n}\n"],"names":["RESERVED_COLUMNS","listFiles","parseFile","Set","normalizeText","value","undefined","String","replace","trim","stripText","withoutWikilinks","withoutMarkdown","removeMarkdown","withoutTables","cfg","baseDir","relPaths","fastGlob","sync","scan","include","cwd","sort","map","relPath","absPath","join","st","statSync","mtimeMs","size","mapValue","BigInt","Number","isSafeInteger","JSON","stringify","splitFrontmatter","raw","open","match","fm","body","rest","slice","length","close","index","parseFrontmatter","warnings","doc","parseDocument","errors","push","message","split","data","toJS","err","Array","isArray","file","extractors","readFileSync","content","mapped","Object","keys","key","has","search","title","summary","text","extracted","fromEntries","filter","f","extract","name"],"mappings":"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"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { find } from '../commands.js';
|
|
2
|
+
import { featureEnabled } from '../config.js';
|
|
1
3
|
import { open } from '../db.js';
|
|
2
4
|
import { printRows } from '../output.js';
|
|
3
5
|
import { printWarnings } from './shared.js';
|
|
@@ -6,17 +8,55 @@ import { printWarnings } from './shared.js';
|
|
|
6
8
|
// column reading as "nothing tagged yet" for hours. Preparing each query catches syntax and
|
|
7
9
|
// unknown-column errors without executing it; queries that take no parameters are also run
|
|
8
10
|
// for a row count. Parameterised queries are validated but not counted: inventing arguments
|
|
9
|
-
// would report a count for a query nobody ran.
|
|
10
|
-
|
|
11
|
+
// would report a count for a query nobody ran. Saved finds run lexically with k=1 -- that
|
|
12
|
+
// validates the `where` fragment and the FTS5 terms against the real schema, the same
|
|
13
|
+
// breakage class prepare() catches for SQL strings -- but never semantically (a --semantic
|
|
14
|
+
// pass costs model time and, on api trees, network); `semantic: true` is only checked for
|
|
15
|
+
// a features.embed to run against.
|
|
16
|
+
const check = async (ctx)=>{
|
|
11
17
|
var _cfg_queries;
|
|
12
18
|
const cfg = ctx.resolveConfig();
|
|
13
19
|
const { db, warnings } = open(cfg);
|
|
14
20
|
printWarnings(warnings);
|
|
15
21
|
const rows = [];
|
|
16
22
|
let failed = 0;
|
|
17
|
-
for (const [name,
|
|
23
|
+
for (const [name, entry] of Object.entries((_cfg_queries = cfg.queries) !== null && _cfg_queries !== void 0 ? _cfg_queries : {})){
|
|
18
24
|
var _sql_match;
|
|
19
25
|
var _cfg_checks;
|
|
26
|
+
if (typeof entry !== 'string') {
|
|
27
|
+
if (entry.semantic && !featureEnabled(cfg, 'embed')) {
|
|
28
|
+
failed++;
|
|
29
|
+
rows.push({
|
|
30
|
+
query: name,
|
|
31
|
+
params: '—',
|
|
32
|
+
rows: '—',
|
|
33
|
+
status: 'FAILED: semantic requested but features.embed is off'
|
|
34
|
+
});
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const count = (await find(db, cfg, entry.find, {
|
|
39
|
+
k: 1,
|
|
40
|
+
where: entry.where
|
|
41
|
+
})).length;
|
|
42
|
+
rows.push({
|
|
43
|
+
query: name,
|
|
44
|
+
params: '—',
|
|
45
|
+
rows: '—',
|
|
46
|
+
status: count === 0 ? 'ok, but matches 0 notes (lexical probe)' : entry.semantic ? 'ok (lexical probe; semantic not run)' : 'ok (probe run with k=1)'
|
|
47
|
+
});
|
|
48
|
+
} catch (err) {
|
|
49
|
+
failed++;
|
|
50
|
+
rows.push({
|
|
51
|
+
query: name,
|
|
52
|
+
params: '—',
|
|
53
|
+
rows: '—',
|
|
54
|
+
status: `FAILED: ${err.message}`
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const sql = entry;
|
|
20
60
|
const params = ((_sql_match = sql.match(/\?/g)) !== null && _sql_match !== void 0 ? _sql_match : []).length;
|
|
21
61
|
const expectEmpty = ((_cfg_checks = cfg.checks) === null || _cfg_checks === void 0 ? void 0 : _cfg_checks[name]) === 'empty';
|
|
22
62
|
try {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/check.ts"],"sourcesContent":["import { find } from '../commands.ts';\nimport { featureEnabled } from '../config.ts';\nimport { open } from '../db.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } from '../output.ts';\nimport { printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// A saved query that returns zero rows looks identical to a true empty result, so a broken\n// one can sit unnoticed -- one field report had `WHERE flag = 'true'` against a numeric\n// column reading as \"nothing tagged yet\" for hours. Preparing each query catches syntax and\n// unknown-column errors without executing it; queries that take no parameters are also run\n// for a row count. Parameterised queries are validated but not counted: inventing arguments\n// would report a count for a query nobody ran. Saved finds run lexically with k=1 -- that\n// validates the `where` fragment and the FTS5 terms against the real schema, the same\n// breakage class prepare() catches for SQL strings -- but never semantically (a --semantic\n// pass costs model time and, on api trees, network); `semantic: true` is only checked for\n// a features.embed to run against.\nconst check: Command = async (ctx) => {\n const cfg = ctx.resolveConfig();\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 !== 'string') {\n if (entry.semantic && !featureEnabled(cfg, 'embed')) {\n failed++;\n rows.push({ query: name, params: '—', rows: '—', status: 'FAILED: semantic requested but features.embed is off' });\n continue;\n }\n try {\n const count = (await find(db, cfg, entry.find, { k: 1, where: entry.where })).length;\n rows.push({ query: name, params: '—', rows: '—', status: count === 0 ? 'ok, but matches 0 notes (lexical probe)' : entry.semantic ? 'ok (lexical probe; semantic not run)' : '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;\n const params = (sql.match(/\\?/g) ?? []).length;\n const expectEmpty = cfg.checks?.[name] === 'empty';\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 if (expectEmpty) {\n // An invariant query: rows are violations, so 0 is the pass, anything else fails.\n if (count > 0) failed++;\n rows.push({ query: name, params, rows: count, status: count === 0 ? 'ok (empty, as asserted)' : `FAILED: expected empty, returned ${count} row(s)` });\n } else {\n rows.push({ query: name, params, rows: count, status: count === 0 ? 'ok, but returns 0 rows' : 'ok' });\n }\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, ctx.format);\n if (failed > 0) process.exit(1);\n};\nexport default check;\n"],"names":["find","featureEnabled","open","printRows","printWarnings","check","ctx","cfg","resolveConfig","db","warnings","rows","failed","name","entry","Object","entries","queries","sql","semantic","push","query","params","status","count","k","where","length","err","message","match","expectEmpty","checks","statement","prepare","all","close","console","log","format","process","exit"],"mappings":"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"}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
+
import { find } from '../commands.js';
|
|
1
2
|
import { printRows } from '../output.js';
|
|
2
|
-
import {
|
|
3
|
-
import { withDb } from './shared.js';
|
|
3
|
+
import { parseK, withDb } from './shared.js';
|
|
4
4
|
const findCmd = async (ctx)=>{
|
|
5
5
|
const [terms] = ctx.rest;
|
|
6
6
|
if (!terms) ctx.usageError(`usage: ${ctx.name} find "<terms>" [--where "<sql>"] [--k n] [--semantic]`);
|
|
7
|
-
const k =
|
|
8
|
-
if (ctx.values.k !== undefined && !Number.isInteger(k)) ctx.usageError(`--k expects an integer, got "${ctx.values.k}"`);
|
|
7
|
+
const k = parseK(ctx);
|
|
9
8
|
await withDb(ctx, async (db, cfg)=>printRows(await find(db, cfg, terms, {
|
|
10
9
|
k,
|
|
11
10
|
where: ctx.values.where,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/find.ts"],"sourcesContent":["import { find } from '../commands.ts';\nimport { printRows } from '../output.ts';\nimport { parseK, 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 = parseK(ctx);\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":["find","printRows","parseK","withDb","findCmd","ctx","terms","rest","usageError","name","k","db","cfg","where","values","semantic","format"],"mappings":"AAAA,SAASA,IAAI,QAAQ,iBAAiB;AACtC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,MAAM,EAAEC,MAAM,QAAQ,cAAc;AAG7C,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,IAAIR,OAAOG;IACjB,MAAMF,OAAOE,KAAK,OAAOM,IAAIC,MAAQX,UAAU,MAAMD,KAAKW,IAAIC,KAAKN,OAAO;YAAEI;YAAGG,OAAOR,IAAIS,MAAM,CAACD,KAAK;YAAEE,UAAUV,IAAIS,MAAM,CAACC,QAAQ;QAAC,IAAIV,IAAIW,MAAM;AACtJ;AACA,eAAeZ,QAAQ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/index.ts"],"sourcesContent":["import type { Command } from './types.ts';\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 named\n// query 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 query: () => import('./query.ts'),\n find: () => import('./find.ts'),\n map: () => import('./map.ts'),\n peek: () => import('./peek.ts'),\n};\n\nexport type { Command, Ctx } from './types.ts';\n"],"names":["COMMANDS","init","watch","status","check","rebuild","query","find","map","peek"],"mappings":"AAEA,0FAA0F;AAC1F,0FAA0F;AAC1F,yCAAyC;AACzC,OAAO,MAAMA,WAAgE;IAC3EC,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,OAAO,IAAM,MAAM,CAAC;IACpBC,MAAM,IAAM,MAAM,CAAC;IACnBC,KAAK,IAAM,MAAM,CAAC;IAClBC,MAAM,IAAM,MAAM,CAAC;AACrB,EAAE"}
|
|
@@ -3,5 +3,8 @@ const init = (ctx)=>{
|
|
|
3
3
|
const configPath = initConfig(process.cwd());
|
|
4
4
|
console.log(`created ${configPath}`);
|
|
5
5
|
console.log(`query away: ${ctx.name} query "SELECT path FROM frontmatter LIMIT 10"`);
|
|
6
|
+
// The decisions a new tree faces -- features, frontmatter conventions, note size -- are not
|
|
7
|
+
// in this output; name both places that hold them, since an agent may have neither.
|
|
8
|
+
console.log('features and tree design: the sense-setup skill, or schema.json');
|
|
6
9
|
};
|
|
7
10
|
export default init;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/init.ts"],"sourcesContent":["import { initConfig } from '../config.ts';\nimport type { Command } from './types.ts';\n\nconst init: Command = (ctx) => {\n const configPath = initConfig(process.cwd());\n console.log(`created ${configPath}`);\n console.log(`query away: ${ctx.name} query \"SELECT path FROM frontmatter LIMIT 10\"`);\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","init","ctx","configPath","process","cwd","console","log","name"],"mappings":"AAAA,SAASA,UAAU,QAAQ,eAAe;AAG1C,MAAMC,OAAgB,CAACC;IACrB,MAAMC,aAAaH,WAAWI,QAAQC,GAAG;IACzCC,QAAQC,GAAG,CAAC,CAAC,QAAQ,EAAEJ,YAAY;IACnCG,QAAQC,GAAG,CAAC,CAAC,YAAY,EAAEL,IAAIM,IAAI,CAAC,8CAA8C,CAAC;IACnF,4FAA4F;IAC5F,oFAAoF;IACpFF,QAAQC,GAAG,CAAC;AACd;AACA,eAAeN,KAAK"}
|
|
@@ -0,0 +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 { 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":["mapTree","renderMap","withDb","map","ctx","db","cfg","result","console","log","format","JSON","stringify"],"mappings":"AAAA,SAASA,OAAO,QAAQ,iBAAiB;AACzC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,MAAM,QAAQ,cAAc;AAGrC,MAAMC,MAAe,CAACC,MACpBF,OAAOE,KAAK,CAACC,IAAIC;QACf,MAAMC,SAASP,QAAQK,IAAIC;QAC3BE,QAAQC,GAAG,CAACL,IAAIM,MAAM,KAAK,SAASC,KAAKC,SAAS,CAACL,QAAQ,MAAM,KAAKN,UAAUM;IAClF;AACF,eAAeJ,IAAI"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Ctx } from './types.js';
|
|
2
|
-
export default function named(ctx: Ctx, queryName: string, params: string[]): void
|
|
2
|
+
export default function named(ctx: Ctx, queryName: string, params: string[]): Promise<void>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { find } from '../commands.js';
|
|
2
|
+
import { printRows } from '../output.js';
|
|
3
|
+
import { parseK, runSql, withDb } from './shared.js';
|
|
4
|
+
// Fallback when the first positional is not a command: a named query from config, either a
|
|
5
|
+
// SQL string (run as-is) or a saved find (run through the `find` command's own machinery).
|
|
6
|
+
export default async function named(ctx, queryName, params) {
|
|
7
|
+
var _parseK, _ctx_values_where;
|
|
8
|
+
const cfg = ctx.resolveConfig();
|
|
9
|
+
const entry = cfg.queries[queryName];
|
|
10
|
+
if (entry === undefined) {
|
|
11
|
+
console.error(`unknown query: "${queryName}"`);
|
|
12
|
+
console.error(`valid queries: ${Object.keys(cfg.queries).sort().join(', ')}`);
|
|
13
|
+
process.exit(2);
|
|
14
|
+
}
|
|
15
|
+
if (typeof entry === 'string') {
|
|
16
|
+
runSql(cfg, entry, params, ctx.format, `query "${queryName}"`);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
// A saved find's terms are fixed in config; there is nowhere for a positional to bind.
|
|
20
|
+
if (params.length > 0) {
|
|
21
|
+
ctx.usageError(`"${queryName}" is a saved find and takes no positional parameters; edit its "find" in sense.config.json, or use "${ctx.name} find" directly`);
|
|
22
|
+
}
|
|
23
|
+
const k = (_parseK = parseK(ctx)) !== null && _parseK !== void 0 ? _parseK : entry.k;
|
|
24
|
+
const where = (_ctx_values_where = ctx.values.where) !== null && _ctx_values_where !== void 0 ? _ctx_values_where : entry.where;
|
|
25
|
+
// --semantic upgrades a saved find the same way --where/--k override; absent means the
|
|
26
|
+
// saved value (the flag has no default, so absent is distinguishable from false).
|
|
27
|
+
const semantic = ctx.values.semantic === true || entry.semantic;
|
|
28
|
+
await withDb(ctx, async (db, resolvedCfg)=>printRows(await find(db, resolvedCfg, entry.find, {
|
|
29
|
+
k,
|
|
30
|
+
where,
|
|
31
|
+
semantic
|
|
32
|
+
}), ctx.format));
|
|
33
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/named.ts"],"sourcesContent":["import { find } from '../commands.ts';\nimport { printRows } from '../output.ts';\nimport { parseK, runSql, withDb } from './shared.ts';\nimport type { Ctx } from './types.ts';\n\n// Fallback when the first positional is not a command: a named query from config, either a\n// SQL string (run as-is) or a saved find (run through the `find` command's own machinery).\nexport default async function named(ctx: Ctx, queryName: string, params: string[]): Promise<void> {\n const cfg = ctx.resolveConfig();\n const entry = cfg.queries[queryName];\n if (entry === undefined) {\n console.error(`unknown query: \"${queryName}\"`);\n console.error(`valid queries: ${Object.keys(cfg.queries).sort().join(', ')}`);\n process.exit(2);\n }\n\n if (typeof entry === 'string') {\n runSql(cfg, entry, params, ctx.format, `query \"${queryName}\"`);\n return;\n }\n\n // A saved find's terms are fixed in config; there is nowhere for a positional to bind.\n if (params.length > 0) {\n ctx.usageError(`\"${queryName}\" is a saved find and takes no positional parameters; edit its \"find\" in sense.config.json, or use \"${ctx.name} find\" directly`);\n }\n const k = parseK(ctx) ?? entry.k;\n const where = ctx.values.where ?? entry.where;\n // --semantic upgrades a saved find the same way --where/--k override; absent means the\n // saved value (the flag has no default, so absent is distinguishable from false).\n const semantic = ctx.values.semantic === true || entry.semantic;\n await withDb(ctx, async (db, resolvedCfg) => printRows(await find(db, resolvedCfg, entry.find, { k, where, semantic }), ctx.format));\n}\n"],"names":["find","printRows","parseK","runSql","withDb","named","ctx","queryName","params","cfg","resolveConfig","entry","queries","undefined","console","error","Object","keys","sort","join","process","exit","format","length","usageError","name","k","where","values","semantic","db","resolvedCfg"],"mappings":"AAAA,SAASA,IAAI,QAAQ,iBAAiB;AACtC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,MAAM,EAAEC,MAAM,EAAEC,MAAM,QAAQ,cAAc;AAGrD,2FAA2F;AAC3F,2FAA2F;AAC3F,eAAe,eAAeC,MAAMC,GAAQ,EAAEC,SAAiB,EAAEC,MAAgB;QAkBrEN,SACII;IAlBd,MAAMG,MAAMH,IAAII,aAAa;IAC7B,MAAMC,QAAQF,IAAIG,OAAO,CAACL,UAAU;IACpC,IAAII,UAAUE,WAAW;QACvBC,QAAQC,KAAK,CAAC,CAAC,gBAAgB,EAAER,UAAU,CAAC,CAAC;QAC7CO,QAAQC,KAAK,CAAC,CAAC,eAAe,EAAEC,OAAOC,IAAI,CAACR,IAAIG,OAAO,EAAEM,IAAI,GAAGC,IAAI,CAAC,OAAO;QAC5EC,QAAQC,IAAI,CAAC;IACf;IAEA,IAAI,OAAOV,UAAU,UAAU;QAC7BR,OAAOM,KAAKE,OAAOH,QAAQF,IAAIgB,MAAM,EAAE,CAAC,OAAO,EAAEf,UAAU,CAAC,CAAC;QAC7D;IACF;IAEA,uFAAuF;IACvF,IAAIC,OAAOe,MAAM,GAAG,GAAG;QACrBjB,IAAIkB,UAAU,CAAC,CAAC,CAAC,EAAEjB,UAAU,oGAAoG,EAAED,IAAImB,IAAI,CAAC,eAAe,CAAC;IAC9J;IACA,MAAMC,KAAIxB,UAAAA,OAAOI,kBAAPJ,qBAAAA,UAAeS,MAAMe,CAAC;IAChC,MAAMC,SAAQrB,oBAAAA,IAAIsB,MAAM,CAACD,KAAK,cAAhBrB,+BAAAA,oBAAoBK,MAAMgB,KAAK;IAC7C,uFAAuF;IACvF,kFAAkF;IAClF,MAAME,WAAWvB,IAAIsB,MAAM,CAACC,QAAQ,KAAK,QAAQlB,MAAMkB,QAAQ;IAC/D,MAAMzB,OAAOE,KAAK,OAAOwB,IAAIC,cAAgB9B,UAAU,MAAMD,KAAK8B,IAAIC,aAAapB,MAAMX,IAAI,EAAE;YAAE0B;YAAGC;YAAOE;QAAS,IAAIvB,IAAIgB,MAAM;AACpI"}
|
|
@@ -0,0 +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 { 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":["peek","renderPeek","withDb","peekCmd","ctx","pathArg","rest","usageError","name","db","cfg","result","console","log","format","JSON","stringify"],"mappings":"AAAA,SAASA,IAAI,QAAQ,iBAAiB;AACtC,SAASC,UAAU,QAAQ,eAAe;AAC1C,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,SAASX,KAAKS,IAAIC,KAAKL;QAC7BO,QAAQC,GAAG,CAACT,IAAIU,MAAM,KAAK,SAASC,KAAKC,SAAS,CAACL,QAAQ,MAAM,KAAKV,WAAWU;IACnF;AACF;AACA,eAAeR,QAAQ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/query.ts"],"sourcesContent":["import { runSql } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst query: Command = (ctx) => {\n const [sql, ...params] = ctx.rest;\n if (!sql) ctx.usageError(`usage: ${ctx.name} query \"<sql>\" [params...]`);\n runSql(ctx.resolveConfig(), sql, params, ctx.format, 'ad-hoc query');\n};\nexport default query;\n"],"names":["runSql","query","ctx","sql","params","rest","usageError","name","resolveConfig","format"],"mappings":"AAAA,SAASA,MAAM,QAAQ,cAAc;AAGrC,MAAMC,QAAiB,CAACC;IACtB,MAAM,CAACC,KAAK,GAAGC,OAAO,GAAGF,IAAIG,IAAI;IACjC,IAAI,CAACF,KAAKD,IAAII,UAAU,CAAC,CAAC,OAAO,EAAEJ,IAAIK,IAAI,CAAC,0BAA0B,CAAC;IACvEP,OAAOE,IAAIM,aAAa,IAAIL,KAAKC,QAAQF,IAAIO,MAAM,EAAE;AACvD;AACA,eAAeR,MAAM"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/rebuild.ts"],"sourcesContent":["import { docCount, rebuild } from '../db.ts';\nimport { printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst rebuildCmd: Command = (ctx) => {\n const result = rebuild(ctx.resolveConfig());\n printWarnings(result.warnings);\n console.log(`rebuilt: ${docCount(result.db)} docs`);\n result.db.close();\n};\nexport default rebuildCmd;\n"],"names":["docCount","rebuild","printWarnings","rebuildCmd","ctx","result","resolveConfig","warnings","console","log","db","close"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,OAAO,QAAQ,WAAW;AAC7C,SAASC,aAAa,QAAQ,cAAc;AAG5C,MAAMC,aAAsB,CAACC;IAC3B,MAAMC,SAASJ,QAAQG,IAAIE,aAAa;IACxCJ,cAAcG,OAAOE,QAAQ;IAC7BC,QAAQC,GAAG,CAAC,CAAC,SAAS,EAAET,SAASK,OAAOK,EAAE,EAAE,KAAK,CAAC;IAClDL,OAAOK,EAAE,CAACC,KAAK;AACjB;AACA,eAAeR,WAAW"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ResolvedConfig } from '../config.js';
|
|
2
2
|
import type { OpenResult } from '../db.js';
|
|
3
3
|
import type { Ctx } from './types.js';
|
|
4
|
+
export declare function parseK(ctx: Ctx): number | undefined;
|
|
4
5
|
export declare function printWarnings(warnings: string[]): void;
|
|
5
6
|
export declare function withDb(ctx: Ctx, fn: (db: OpenResult['db'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void>;
|
|
6
7
|
export declare function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: 'table' | 'json', label: string): void;
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { open } from '../db.js';
|
|
2
2
|
import { printRows } from '../output.js';
|
|
3
3
|
import { searchError } from '../search-error.js';
|
|
4
|
+
// --k must be a positive integer: SQLite reads a bound LIMIT of -1 as "unlimited" and 0 as
|
|
5
|
+
// "nothing", and parseInt would silently truncate "5.9" -- all three are caller mistakes
|
|
6
|
+
// worth a usage error, matching the config-level SavedFind validation.
|
|
7
|
+
export function parseK(ctx) {
|
|
8
|
+
if (ctx.values.k === undefined) return undefined;
|
|
9
|
+
const k = Number(ctx.values.k);
|
|
10
|
+
if (!Number.isInteger(k) || k <= 0) ctx.usageError(`--k expects a positive integer, got "${ctx.values.k}"`);
|
|
11
|
+
return k;
|
|
12
|
+
}
|
|
4
13
|
// Shared open-query-close envelope for commands that touch the tree.
|
|
5
14
|
export function printWarnings(warnings) {
|
|
6
15
|
for (const w of warnings)console.warn(w);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/shared.ts"],"sourcesContent":["import type { ResolvedConfig } from '../config.ts';\nimport type { OpenResult } from '../db.ts';\nimport { open } from '../db.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } from '../output.ts';\nimport { searchError } from '../search-error.ts';\nimport type { Ctx } from './types.ts';\n\n// --k must be a positive integer: SQLite reads a bound LIMIT of -1 as \"unlimited\" and 0 as\n// \"nothing\", and parseInt would silently truncate \"5.9\" -- all three are caller mistakes\n// worth a usage error, matching the config-level SavedFind validation.\nexport function parseK(ctx: Ctx): number | undefined {\n if (ctx.values.k === undefined) return undefined;\n const k = Number(ctx.values.k);\n if (!Number.isInteger(k) || k <= 0) ctx.usageError(`--k expects a positive integer, got \"${ctx.values.k}\"`);\n return k;\n}\n\n// Shared open-query-close envelope for commands that touch the tree.\n\nexport function printWarnings(warnings: string[]): void {\n for (const w of warnings) console.warn(w);\n}\n\nexport async function withDb(ctx: Ctx, fn: (db: OpenResult['db'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void> {\n const cfg = ctx.resolveConfig();\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n try {\n await fn(db, cfg);\n } finally {\n db.close();\n }\n}\n\n// An unbound `?` silently binds NULL, so mismatched param counts fail loudly instead.\nexport function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: 'table' | 'json', label: string): void {\n const placeholderCount = (sql.match(/\\?/g) ?? []).length;\n if (params.length !== placeholderCount) {\n console.error(`${label} expects ${placeholderCount} parameter(s), got ${params.length}`);\n process.exit(2);\n }\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n let rows: Row[];\n try {\n rows = db.prepare(sql).all(...params) as Row[];\n } catch (err) {\n db.close();\n // A saved query or ad-hoc SQL can carry `content MATCH ?` too, so the same FTS5\n // punctuation trap applies -- the bound parameters are the search terms there. SQL\n // without MATCH gets its error verbatim; search advice on a plain typo would mislead.\n if (/\\bMATCH\\b/i.test(sql)) throw searchError(err as Error, params.join(' '));\n throw err;\n }\n printRows(rows, format);\n db.close();\n}\n"],"names":["open","printRows","searchError","parseK","ctx","values","k","undefined","Number","isInteger","usageError","printWarnings","warnings","w","console","warn","withDb","fn","cfg","resolveConfig","db","close","runSql","sql","params","format","label","placeholderCount","match","length","error","process","exit","rows","prepare","all","err","test","join"],"mappings":"AAEA,SAASA,IAAI,QAAQ,WAAW;AAEhC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,WAAW,QAAQ,qBAAqB;AAGjD,2FAA2F;AAC3F,yFAAyF;AACzF,uEAAuE;AACvE,OAAO,SAASC,OAAOC,GAAQ;IAC7B,IAAIA,IAAIC,MAAM,CAACC,CAAC,KAAKC,WAAW,OAAOA;IACvC,MAAMD,IAAIE,OAAOJ,IAAIC,MAAM,CAACC,CAAC;IAC7B,IAAI,CAACE,OAAOC,SAAS,CAACH,MAAMA,KAAK,GAAGF,IAAIM,UAAU,CAAC,CAAC,qCAAqC,EAAEN,IAAIC,MAAM,CAACC,CAAC,CAAC,CAAC,CAAC;IAC1G,OAAOA;AACT;AAEA,qEAAqE;AAErE,OAAO,SAASK,cAAcC,QAAkB;IAC9C,KAAK,MAAMC,KAAKD,SAAUE,QAAQC,IAAI,CAACF;AACzC;AAEA,OAAO,eAAeG,OAAOZ,GAAQ,EAAEa,EAAuE;IAC5G,MAAMC,MAAMd,IAAIe,aAAa;IAC7B,MAAM,EAAEC,EAAE,EAAER,QAAQ,EAAE,GAAGZ,KAAKkB;IAC9BP,cAAcC;IACd,IAAI;QACF,MAAMK,GAAGG,IAAIF;IACf,SAAU;QACRE,GAAGC,KAAK;IACV;AACF;AAEA,sFAAsF;AACtF,OAAO,SAASC,OAAOJ,GAAmB,EAAEK,GAAW,EAAEC,MAAgB,EAAEC,MAAwB,EAAEC,KAAa;QACtFH;IAA1B,MAAMI,mBAAmB,EAACJ,aAAAA,IAAIK,KAAK,CAAC,oBAAVL,wBAAAA,aAAoB,EAAE,EAAEM,MAAM;IACxD,IAAIL,OAAOK,MAAM,KAAKF,kBAAkB;QACtCb,QAAQgB,KAAK,CAAC,GAAGJ,MAAM,SAAS,EAAEC,iBAAiB,mBAAmB,EAAEH,OAAOK,MAAM,EAAE;QACvFE,QAAQC,IAAI,CAAC;IACf;IACA,MAAM,EAAEZ,EAAE,EAAER,QAAQ,EAAE,GAAGZ,KAAKkB;IAC9BP,cAAcC;IACd,IAAIqB;IACJ,IAAI;QACFA,OAAOb,GAAGc,OAAO,CAACX,KAAKY,GAAG,IAAIX;IAChC,EAAE,OAAOY,KAAK;QACZhB,GAAGC,KAAK;QACR,gFAAgF;QAChF,mFAAmF;QACnF,sFAAsF;QACtF,IAAI,aAAagB,IAAI,CAACd,MAAM,MAAMrB,YAAYkC,KAAcZ,OAAOc,IAAI,CAAC;QACxE,MAAMF;IACR;IACAnC,UAAUgC,MAAMR;IAChBL,GAAGC,KAAK;AACV"}
|
|
@@ -22,6 +22,10 @@ const status = (ctx)=>{
|
|
|
22
22
|
const e = embedConfig(cfg);
|
|
23
23
|
const vectors = e ? vectorState(db) : null;
|
|
24
24
|
const heartbeat = getMeta(db, 'watch_heartbeat');
|
|
25
|
+
// Derived at open() (F): 3x the largest reconcile this cache has ever held its write
|
|
26
|
+
// transaction for, floored at 30s -- read back from the connection rather than
|
|
27
|
+
// recomputed here, so this always reports what open() actually set.
|
|
28
|
+
const busyTimeoutMs = db.prepare('PRAGMA busy_timeout').get().timeout;
|
|
25
29
|
const result = {
|
|
26
30
|
db: dbPath,
|
|
27
31
|
docs: docCount(db),
|
|
@@ -33,7 +37,8 @@ const status = (ctx)=>{
|
|
|
33
37
|
...vectors !== null && vectors !== void 0 ? vectors : {}
|
|
34
38
|
} : null,
|
|
35
39
|
findDefaultWhere: (_ref = (_cfg_defaults = cfg.defaults) === null || _cfg_defaults === void 0 ? void 0 : (_cfg_defaults_find = _cfg_defaults.find) === null || _cfg_defaults_find === void 0 ? void 0 : _cfg_defaults_find.where) !== null && _ref !== void 0 ? _ref : null,
|
|
36
|
-
watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null
|
|
40
|
+
watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null,
|
|
41
|
+
busyTimeoutMs
|
|
37
42
|
};
|
|
38
43
|
if (ctx.format === 'json') {
|
|
39
44
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -45,6 +50,7 @@ const status = (ctx)=>{
|
|
|
45
50
|
if (e) console.log(`embed: ${e.type} ${e.model}${vectors ? ` (vectors: ${vectors.embedded} embedded, ${vectors.pending} pending — embedded on first --semantic query)` : ''}`);
|
|
46
51
|
if (result.findDefaultWhere) console.log(`find default scope: ${result.findDefaultWhere} (--where replaces it)`);
|
|
47
52
|
console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: no watcher' : `watcher: last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);
|
|
53
|
+
console.log(`busy_timeout: ${result.busyTimeoutMs}ms (derived: 3x the largest reconcile this cache has recorded, floored at 30000ms)`);
|
|
48
54
|
}
|
|
49
55
|
db.close();
|
|
50
56
|
};
|