sensemaking 0.8.0 → 0.9.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 +48 -39
- package/dist/cjs/cli/check.js +24 -43
- package/dist/cjs/cli/check.js.map +1 -1
- package/dist/cjs/cli/index.js +2 -2
- package/dist/cjs/cli/index.js.map +1 -1
- package/dist/cjs/cli/named.js +18 -8
- package/dist/cjs/cli/named.js.map +1 -1
- package/dist/cjs/cli/search.d.cts +3 -0
- package/dist/cjs/cli/search.d.ts +3 -0
- package/dist/cjs/cli/{find.js → search.js} +7 -5
- package/dist/cjs/cli/search.js.map +1 -0
- package/dist/cjs/cli/shared.js.map +1 -1
- package/dist/cjs/cli/status.js +29 -12
- package/dist/cjs/cli/status.js.map +1 -1
- package/dist/cjs/cli/types.d.cts +3 -1
- package/dist/cjs/cli/types.d.ts +3 -1
- package/dist/cjs/cli.js +25 -5
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/commands.d.cts +11 -2
- package/dist/cjs/commands.d.ts +11 -2
- package/dist/cjs/commands.js +86 -21
- package/dist/cjs/commands.js.map +1 -1
- package/dist/cjs/config.d.cts +41 -14
- package/dist/cjs/config.d.ts +41 -14
- package/dist/cjs/config.js +448 -160
- 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 +208 -62
- 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 +12 -2
- package/dist/cjs/features/embed.js.map +1 -1
- package/dist/cjs/features/types.d.cts +2 -1
- package/dist/cjs/features/types.d.ts +2 -1
- package/dist/cjs/index.d.cts +3 -3
- package/dist/cjs/index.d.ts +3 -3
- package/dist/cjs/index.js +6 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/output.d.cts +15 -0
- package/dist/cjs/output.d.ts +15 -0
- package/dist/cjs/output.js +26 -5
- package/dist/cjs/output.js.map +1 -1
- package/dist/cjs/scan.d.cts +3 -0
- package/dist/cjs/scan.d.ts +3 -0
- package/dist/cjs/scan.js +84 -4
- package/dist/cjs/scan.js.map +1 -1
- package/dist/esm/cli/check.js +20 -41
- package/dist/esm/cli/check.js.map +1 -1
- package/dist/esm/cli/index.js +1 -1
- package/dist/esm/cli/index.js.map +1 -1
- package/dist/esm/cli/named.js +17 -9
- package/dist/esm/cli/named.js.map +1 -1
- package/dist/esm/cli/search.d.ts +3 -0
- package/dist/esm/cli/search.js +16 -0
- package/dist/esm/cli/search.js.map +1 -0
- package/dist/esm/cli/shared.js +1 -1
- package/dist/esm/cli/shared.js.map +1 -1
- package/dist/esm/cli/status.js +10 -10
- package/dist/esm/cli/status.js.map +1 -1
- package/dist/esm/cli/types.d.ts +3 -1
- package/dist/esm/cli/types.js.map +1 -1
- package/dist/esm/cli.js +20 -4
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/commands.d.ts +11 -2
- package/dist/esm/commands.js +76 -24
- package/dist/esm/commands.js.map +1 -1
- package/dist/esm/config.d.ts +41 -14
- package/dist/esm/config.js +354 -114
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/db.d.ts +1 -1
- package/dist/esm/db.js +53 -6
- 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 +12 -2
- package/dist/esm/features/embed.js.map +1 -1
- package/dist/esm/features/types.d.ts +2 -1
- 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 +15 -0
- package/dist/esm/output.js +19 -5
- package/dist/esm/output.js.map +1 -1
- package/dist/esm/scan.d.ts +3 -0
- package/dist/esm/scan.js +32 -4
- package/dist/esm/scan.js.map +1 -1
- package/package.json +9 -3
- package/schema.json +74 -54
- package/skills/sense/EXAMPLES.md +8 -6
- package/skills/sense/SKILL.md +51 -48
- package/skills/sense-setup/EXAMPLES.md +121 -0
- package/skills/sense-setup/SKILL.md +71 -66
- package/dist/cjs/cli/find.d.cts +0 -3
- package/dist/cjs/cli/find.d.ts +0 -3
- package/dist/cjs/cli/find.js.map +0 -1
- package/dist/esm/cli/find.d.ts +0 -3
- package/dist/esm/cli/find.js +0 -14
- package/dist/esm/cli/find.js.map +0 -1
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 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":"AAAA,iCAAiC;;;;;;;;;;;;QAYjBA;eAAAA;;QAsDAC;eAAAA;;QASAC;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAvEhB,yFAAyF;AACzF,IAAMC,iBAAiB;AAEvB,mGAAmG;AACnG,SAASC,KAAKC,KAAc;IAC1B,OAAOC,OAAOD,kBAAAA,mBAAAA,QAAS,IAAIE,OAAO,CAAC,aAAa;AAClD;AAEO,SAASP,UAAUQ,IAAW,EAAEC,MAAwB;IAC7D,IAAMC,WAAWC,WAAWH,MAAMC;IAClCG,QAAQC,GAAG,CAACH;IACZ,IAAIA,SAASI,MAAM,GAAGX,gBAAgB;QACpCS,QAAQG,IAAI,CAAC,AAAC,sBAAqEP,OAAhDQ,KAAKC,KAAK,CAACP,SAASI,MAAM,GAAG,OAAM,eAAyB,OAAZN,KAAKM,MAAM,EAAC;IACjG;AACF;AAEA,sFAAsF;AACtF,uFAAuF;AACvF,mFAAmF;AACnF,uFAAuF;AACvF,wEAAwE;AACxE,IAAMI,aAAa;AACnB,IAAMC,YAAY;AAElB,SAASC,UAAUC,MAAgB,EAAEC,KAAa;IAChD,IAAMC,OAAO,AAACF,CAAAA,OAAOP,MAAM,GAAG,CAAA,IAAK;IACnC,IAAMU,SAAU,qBAAGH;IACnB,OAAS;YAGuBL;QAF9B,IAAMS,QAAQD,OAAOE,MAAM,CAAC,SAACC,GAAGC;mBAAMD,IAAIC;WAAG,KAAKL;QAClD,IAAIE,SAASH,OAAO,OAAOE;QAC3B,IAAMK,SAASL,OAAOM,OAAO,CAACd,CAAAA,QAAAA,MAAKe,GAAG,OAARf,OAAS,qBAAGQ;QAC1C,IAAIA,MAAM,CAACK,OAAO,IAAIX,YAAY,OAAOM;QACzCA,MAAM,CAACK,OAAO,GAAGb,KAAKe,GAAG,CAACb,YAAYM,MAAM,CAACK,OAAO,GAAGb,KAAKe,GAAG,CAAC,GAAGN,QAAQH;IAC7E;AACF;AAEA,SAASX,WAAWH,IAAW,EAAEC,MAAwB;QAAEuB,QAAAA,iEAAQC,QAAQC,MAAM,CAACC,OAAO;QAM/CnB;IALxC,IAAIP,WAAW,QAAQ,OAAO2B,KAAKC,SAAS,CAAC7B,MAAM,MAAM;IACzD,IAAIA,KAAKM,MAAM,KAAK,GAAG,OAAO;IAE9B,IAAMqB,UAAUG,OAAOC,IAAI,CAAC/B,IAAI,CAAC,EAAE;IACnC,IAAMgC,QAAQhC,KAAKiC,GAAG,CAAC,SAACC;eAAQP,QAAQM,GAAG,CAAC,SAACE;mBAAQvC,KAAKsC,GAAG,CAACC,IAAI;;;IAClE,IAAMC,UAAUT,QAAQM,GAAG,CAAC,SAACE,KAAKE;eAAM7B,CAAAA,QAAAA,MAAKe,GAAG,OAARf,OAAAA;YAAS2B,IAAI7B,MAAM;SAAuC,CAA1DE,OAAqB,qBAAGwB,MAAMC,GAAG,CAAC,SAACC;mBAAQA,GAAG,CAACG,EAAE,CAAC/B,MAAM;;;IAChG,IAAMO,SAASW,SAASA,QAAQd,aAAaE,UAAUwB,SAASZ,SAASY;IAEzE,IAAME,OAAO,cAACzC,OAAe0C;eAAe1C,MAAMS,MAAM,IAAIiC,IAAI1C,MAAM2C,MAAM,CAACD,KAAK,AAAC,GAA0B5B,OAAxBd,MAAM4C,KAAK,CAAC,GAAGF,IAAI,IAAe,OAAV5B;;IAC7G,IAAM+B,YAAY,mBAACC;eACjBA,OACGV,GAAG,CAAC,SAACpC,OAAOwC;mBAAMC,KAAKzC,OAAOgB,MAAM,CAACwB,EAAE;WACvCO,IAAI,CAAC,MACLC,OAAO;;IAEZ,OAAO;QAACH,UAAUf;QAAUd,OAAOoB,GAAG,CAAC,SAACM;mBAAM,IAAIO,MAAM,CAACP;WAAIK,IAAI,CAAC;KAA+B,CAA1F,OAAkE,qBAAGZ,MAAMC,GAAG,CAACS,aAAYE,IAAI,CAAC;AACzG;AAEA,0EAA0E;AAE1E,SAASG,aAAaC,QAAyC;IAC7D,IAAMC,MAAMD,SAASC,GAAG,CAAC3C,MAAM,GAAG,IAAI,AAAC,cAA8E,OAApE0C,SAASC,GAAG,CAAChB,GAAG,CAAC,SAACiB;eAAS,AAAC,GAAoBA,OAAlBA,MAAK,eAAkB,OAALA,MAAK;OAAIN,IAAI,CAAC,SAAU;IACzH,OAAO,AAAC,aAAqCK,OAAzBD,SAASG,EAAE,CAACP,IAAI,CAAC,OAAY,OAAJK;AAC/C;AAEO,SAASxD,UAAU2D,MAA6J;IACrL,IAAMC,QAAQ;QAAE,SAA8B7C,OAAtB4C,OAAOE,IAAI,CAACC,KAAK,EAAC,MAAyC,OAArC/C,KAAKC,KAAK,CAAC2C,OAAOE,IAAI,CAACE,KAAK,GAAG,OAAM;QAAQ,GAAgC,OAA9BT,aAAaK,OAAOJ,QAAQ,GAAE;QAAK7C,WAAWiD,OAAOK,MAAM,EAAE;KAAS;IACnK,IAAIL,OAAOM,WAAW,GAAGN,OAAOK,MAAM,CAACnD,MAAM,EAAE+C,MAAMM,IAAI,CAAC,AAAC,KAA8C,OAA1CP,OAAOM,WAAW,GAAGN,OAAOK,MAAM,CAACnD,MAAM,EAAC;IACzG,IAAI8C,OAAOQ,IAAI,CAACtD,MAAM,GAAG,GAAG+C,MAAMM,IAAI,CAAC,0BAA0BxD,WAAWiD,OAAOQ,IAAI,EAAE;SACpF,IAAIR,OAAOJ,QAAQ,CAACC,GAAG,CAACY,QAAQ,CAAC,SAASR,MAAMM,IAAI,CAAC;IAC1DN,MAAMM,IAAI,CAAC,aAAaxD,WAAWiD,OAAOU,MAAM,EAAE;IAClD,OAAOT,MAAMT,IAAI,CAAC;AACpB;AAEO,SAASlD,WAAW0D,MAAwP;IACjR,IAAMW,QAAQ;QAAE,GAAoBX,OAAlBA,OAAOY,IAAI,EAAC,QAAoB,OAAdZ,OAAOa,MAAM,EAAC;KAAU;QACvD,kCAAA,2BAAA;;QAAL,QAAK,YAAsBnC,OAAOoC,OAAO,CAACd,OAAOe,WAAW,sBAAvD,SAAA,6BAAA,QAAA,yBAAA;YAAA,mCAAA,iBAAOC,sBAAKvE;YAA8CkE,MAAMJ,IAAI,CAAC,AAAC,KAAY9D,OAARuE,KAAI,MAAU,OAANvE;;;QAAlF;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IACL,IAAIuD,OAAOiB,QAAQ,CAAC/D,MAAM,GAAG,GAAG;QAC9ByD,MAAMJ,IAAI,CAAC,IAAI;YACV,mCAAA,4BAAA;;YAAL,QAAK,aAAWP,OAAOiB,QAAQ,qBAA1B,UAAA,8BAAA,SAAA,0BAAA;gBAAA,IAAMC,IAAN;gBAA4BP,MAAMJ,IAAI,CAAC,AAAC,KAAqCW,OAAjC,IAAIxB,MAAM,CAACwB,EAAEC,KAAK,GAAY,KAAmBD,OAAhBA,EAAEE,OAAO,EAAC,QAAsBF,OAAhBA,EAAEG,UAAU,EAAC,KAAmBH,OAAhBA,EAAEI,QAAQ,EAAC,OAAc,OAATJ,EAAEL,MAAM,EAAC;;;YAAtI;YAAA;;;qBAAA,8BAAA;oBAAA;;;oBAAA;0BAAA;;;;QACL,IAAIb,OAAOuB,aAAa,GAAGvB,OAAOiB,QAAQ,CAAC/D,MAAM,EAAEyD,MAAMJ,IAAI,CAAC,AAAC,OAAoD,OAA9CP,OAAOuB,aAAa,GAAGvB,OAAOiB,QAAQ,CAAC/D,MAAM,EAAC;IACrH,OAAO,IAAI8C,OAAOH,GAAG,CAACY,QAAQ,CAAC,aAAaE,MAAMJ,IAAI,CAAC,IAAI;IAC3D,IAAIP,OAAOH,GAAG,CAACY,QAAQ,CAAC,UAAU;QAChCE,MAAMJ,IAAI,CAAC,IAAI;QACf,OAAOI,MAAMnB,IAAI,CAAC;IACpB;IACA,IAAMgC,WAAW,kBAACC,OAAeC,OAAiB7D;QAChD,IAAIA,QAAQ,GAAG8C,MAAMJ,IAAI,CAAC,AAAC,GAAY1C,OAAV4D,OAAM,MAAeC,OAAX7D,OAAM,OAAwBA,OAAnB6D,MAAMlC,IAAI,CAAC,OAAsE,OAA9D3B,QAAQ6D,MAAMxE,MAAM,GAAG,AAAC,MAA0B,OAArBW,QAAQ6D,MAAMxE,MAAM,EAAC,WAAS;IAClI;IACA,IAAI8C,OAAO2B,aAAa,GAAG3B,OAAO4B,eAAe,GAAG5B,OAAO6B,cAAc,GAAG,GAAGlB,MAAMJ,IAAI,CAAC;IAC1FiB,SAAS,aAAaxB,OAAO8B,QAAQ,EAAE9B,OAAO2B,aAAa;IAC3DH,SAAS,cAAcxB,OAAO+B,UAAU,EAAE/B,OAAO4B,eAAe;IAChEJ,SAAS,aAAaxB,OAAOgC,SAAS,EAAEhC,OAAO6B,cAAc;IAC7D,OAAOlB,MAAMnB,IAAI,CAAC;AACpB"}
|
|
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 top-level commands; cli.ts prints what these return.\n\n// `embed` is not a features-block key (it's derived from presets), so its off hint reads\n// differently from links/sections/rank's plain `features.<name>`.\nexport function featureOffHint(name: string): string {\n return name === 'embed' ? 'no preset has semantic on' : `features.${name}`;\n}\n\nexport function featuresLine(features: { on: string[]; off: string[] }): string {\n const off = features.off.length > 0 ? ` · off: ${features.off.map((name) => `${name} (${featureOffHint(name)})`).join(', ')}` : '';\n return `features: ${features.on.join(', ')}${off}`;\n}\n\nexport function presetsLines(presets: Array<{ name: string; files: number; embedded: number }>): string[] {\n return ['presets:', ...presets.map((p) => ` ${p.name}: ${p.files} file(s), ${p.embedded} embedded`)];\n}\n\nexport function renderMap(result: { docs: { count: number; bytes: number }; fields: Row[]; fieldsTotal: number; features: { on: string[]; off: string[] }; presets: Array<{ name: string; files: number; embedded: number }>; hubs: Row[]; recent: Row[] }): string {\n const parts = [`docs: ${result.docs.count} (${Math.round(result.docs.bytes / 1024)} KB)`, featuresLine(result.features), '', ...presetsLines(result.presets), '', 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 (${featureOffHint('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":["featureOffHint","featuresLine","presetsLines","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","name","features","off","on","presets","p","files","embedded","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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"}
|
package/dist/cjs/scan.d.cts
CHANGED
|
@@ -6,12 +6,15 @@ export interface FileStat {
|
|
|
6
6
|
absPath: string;
|
|
7
7
|
mtimeMs: number;
|
|
8
8
|
size: number;
|
|
9
|
+
presets: string[];
|
|
10
|
+
embed: boolean;
|
|
9
11
|
}
|
|
10
12
|
export declare function listFiles(cfg: Config, baseDir: string): FileStat[];
|
|
11
13
|
export interface ParsedDoc {
|
|
12
14
|
relPath: string;
|
|
13
15
|
mtimeMs: number;
|
|
14
16
|
size: number;
|
|
17
|
+
presets: string[];
|
|
15
18
|
data: Record<string, string | number | bigint | null>;
|
|
16
19
|
search: {
|
|
17
20
|
title: string;
|
package/dist/cjs/scan.d.ts
CHANGED
|
@@ -6,12 +6,15 @@ export interface FileStat {
|
|
|
6
6
|
absPath: string;
|
|
7
7
|
mtimeMs: number;
|
|
8
8
|
size: number;
|
|
9
|
+
presets: string[];
|
|
10
|
+
embed: boolean;
|
|
9
11
|
}
|
|
10
12
|
export declare function listFiles(cfg: Config, baseDir: string): FileStat[];
|
|
11
13
|
export interface ParsedDoc {
|
|
12
14
|
relPath: string;
|
|
13
15
|
mtimeMs: number;
|
|
14
16
|
size: number;
|
|
17
|
+
presets: string[];
|
|
15
18
|
data: Record<string, string | number | bigint | null>;
|
|
16
19
|
search: {
|
|
17
20
|
title: string;
|
package/dist/cjs/scan.js
CHANGED
|
@@ -24,15 +24,41 @@ var _nodepath = require("node:path");
|
|
|
24
24
|
var _fastglob = /*#__PURE__*/ _interop_require_default(require("fast-glob"));
|
|
25
25
|
var _removemarkdown = /*#__PURE__*/ _interop_require_default(require("remove-markdown"));
|
|
26
26
|
var _yaml = require("yaml");
|
|
27
|
+
var _configts = require("./config.js");
|
|
28
|
+
function _array_like_to_array(arr, len) {
|
|
29
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
30
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
31
|
+
return arr2;
|
|
32
|
+
}
|
|
33
|
+
function _array_without_holes(arr) {
|
|
34
|
+
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
35
|
+
}
|
|
27
36
|
function _interop_require_default(obj) {
|
|
28
37
|
return obj && obj.__esModule ? obj : {
|
|
29
38
|
default: obj
|
|
30
39
|
};
|
|
31
40
|
}
|
|
41
|
+
function _iterable_to_array(iter) {
|
|
42
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
43
|
+
}
|
|
44
|
+
function _non_iterable_spread() {
|
|
45
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
46
|
+
}
|
|
47
|
+
function _to_consumable_array(arr) {
|
|
48
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
49
|
+
}
|
|
32
50
|
function _type_of(obj) {
|
|
33
51
|
"@swc/helpers - typeof";
|
|
34
52
|
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
35
53
|
}
|
|
54
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
55
|
+
if (!o) return;
|
|
56
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
57
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
58
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
59
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
60
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
61
|
+
}
|
|
36
62
|
var RESERVED_COLUMNS = new Set([
|
|
37
63
|
'path',
|
|
38
64
|
'_mtime',
|
|
@@ -55,17 +81,70 @@ function stripText(value) {
|
|
|
55
81
|
return normalizeText(withoutTables);
|
|
56
82
|
}
|
|
57
83
|
function listFiles(cfg, baseDir) {
|
|
58
|
-
var
|
|
59
|
-
|
|
60
|
-
|
|
84
|
+
var coverage = new Map();
|
|
85
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
86
|
+
try {
|
|
87
|
+
for(var _iterator = (0, _configts.presetNames)(cfg)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
88
|
+
var name = _step.value;
|
|
89
|
+
var _preset_exclude;
|
|
90
|
+
var preset = cfg.presets[name];
|
|
91
|
+
var matched = _fastglob.default.sync(preset.include, {
|
|
92
|
+
cwd: baseDir,
|
|
93
|
+
ignore: (_preset_exclude = preset.exclude) !== null && _preset_exclude !== void 0 ? _preset_exclude : []
|
|
94
|
+
});
|
|
95
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
96
|
+
try {
|
|
97
|
+
for(var _iterator1 = matched[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
98
|
+
var relPath = _step1.value;
|
|
99
|
+
var _coverage_get;
|
|
100
|
+
var set = (_coverage_get = coverage.get(relPath)) !== null && _coverage_get !== void 0 ? _coverage_get : new Set();
|
|
101
|
+
set.add(name);
|
|
102
|
+
coverage.set(relPath, set);
|
|
103
|
+
}
|
|
104
|
+
} catch (err) {
|
|
105
|
+
_didIteratorError1 = true;
|
|
106
|
+
_iteratorError1 = err;
|
|
107
|
+
} finally{
|
|
108
|
+
try {
|
|
109
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
110
|
+
_iterator1.return();
|
|
111
|
+
}
|
|
112
|
+
} finally{
|
|
113
|
+
if (_didIteratorError1) {
|
|
114
|
+
throw _iteratorError1;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
} catch (err) {
|
|
120
|
+
_didIteratorError = true;
|
|
121
|
+
_iteratorError = err;
|
|
122
|
+
} finally{
|
|
123
|
+
try {
|
|
124
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
125
|
+
_iterator.return();
|
|
126
|
+
}
|
|
127
|
+
} finally{
|
|
128
|
+
if (_didIteratorError) {
|
|
129
|
+
throw _iteratorError;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
var relPaths = _to_consumable_array(coverage.keys()).sort();
|
|
61
134
|
return relPaths.map(function(relPath) {
|
|
62
135
|
var absPath = (0, _nodepath.join)(baseDir, relPath);
|
|
63
136
|
var st = (0, _nodefs.statSync)(absPath);
|
|
137
|
+
var presets = _to_consumable_array(coverage.get(relPath)).sort();
|
|
138
|
+
var embed = presets.some(function(name) {
|
|
139
|
+
return (0, _configts.presetSemanticEnabled)(cfg, name);
|
|
140
|
+
});
|
|
64
141
|
return {
|
|
65
142
|
relPath: relPath,
|
|
66
143
|
absPath: absPath,
|
|
67
144
|
mtimeMs: st.mtimeMs,
|
|
68
|
-
size: st.size
|
|
145
|
+
size: st.size,
|
|
146
|
+
presets: presets,
|
|
147
|
+
embed: embed
|
|
69
148
|
};
|
|
70
149
|
});
|
|
71
150
|
}
|
|
@@ -163,6 +242,7 @@ function parseFile(file) {
|
|
|
163
242
|
relPath: file.relPath,
|
|
164
243
|
mtimeMs: file.mtimeMs,
|
|
165
244
|
size: file.size,
|
|
245
|
+
presets: file.presets,
|
|
166
246
|
data: mapped,
|
|
167
247
|
search: search,
|
|
168
248
|
extracted: Object.fromEntries(extractors.filter(function(f) {
|
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\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
|
+
{"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 { presetNames, presetSemanticEnabled } 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 presets: string[]; // every declared preset covering this file (>= 1; union, overlap allowed)\n embed: boolean; // true iff any covering preset has semantic !== false\n}\n\n// Presets are the file selection: each preset's include/exclude picks its files (fast-glob,\n// tsconfig-standard semantics, resolved relative to baseDir). Unlike the old layer model,\n// presets are views, not partitions -- they may overlap freely, and a file's set of covering\n// presets (not a single owner) is what indexing and embedding derive from. A preset whose\n// globs match nothing is valid. Files matched by no preset at all are simply not indexed.\nexport function listFiles(cfg: Config, baseDir: string): FileStat[] {\n const coverage = new Map<string, Set<string>>();\n for (const name of presetNames(cfg)) {\n const preset = cfg.presets[name];\n const matched = fastGlob.sync(preset.include, { cwd: baseDir, ignore: preset.exclude ?? [] });\n for (const relPath of matched) {\n const set = coverage.get(relPath) ?? new Set<string>();\n set.add(name);\n coverage.set(relPath, set);\n }\n }\n\n const relPaths = [...coverage.keys()].sort();\n return relPaths.map((relPath) => {\n const absPath = join(baseDir, relPath);\n const st = statSync(absPath);\n const presets = [...(coverage.get(relPath) as Set<string>)].sort();\n const embed = presets.some((name) => presetSemanticEnabled(cfg, name));\n return { relPath, absPath, mtimeMs: st.mtimeMs, size: st.size, presets, embed };\n });\n}\n\nexport interface ParsedDoc {\n relPath: string;\n mtimeMs: number;\n size: number;\n presets: string[];\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 presets: file.presets,\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","coverage","Map","presetNames","name","preset","presets","matched","fastGlob","sync","include","cwd","ignore","exclude","relPath","set","get","add","relPaths","keys","sort","map","absPath","join","st","statSync","embed","some","presetSemanticEnabled","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","key","has","search","title","summary","text","extracted","fromEntries","filter","f","extract"],"mappings":"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"}
|
package/dist/esm/cli/check.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { featureEnabled } from '../config.js';
|
|
1
|
+
import { search } from '../commands.js';
|
|
3
2
|
import { open } from '../db.js';
|
|
4
3
|
import { printRows } from '../output.js';
|
|
5
4
|
import { printWarnings } from './shared.js';
|
|
@@ -8,11 +7,11 @@ import { printWarnings } from './shared.js';
|
|
|
8
7
|
// column reading as "nothing tagged yet" for hours. Preparing each query catches syntax and
|
|
9
8
|
// unknown-column errors without executing it; queries that take no parameters are also run
|
|
10
9
|
// for a row count. Parameterised queries are validated but not counted: inventing arguments
|
|
11
|
-
// would report a count for a query nobody ran. Saved
|
|
12
|
-
// validates the `where` fragment
|
|
13
|
-
// breakage class prepare() catches for SQL strings -- but never
|
|
14
|
-
// pass costs model time and, on api trees, network)
|
|
15
|
-
//
|
|
10
|
+
// would report a count for a query nobody ran. Saved searches run lexically with k=1 -- that
|
|
11
|
+
// validates the `where` fragment, the FTS5 terms, and the `preset` name (resolveSearch throws
|
|
12
|
+
// on an unknown one, the same breakage class prepare() catches for SQL strings) -- but never
|
|
13
|
+
// semantically (a semantic pass costs model time and, on api trees, network). Whether a
|
|
14
|
+
// result being empty is good or bad is the reader's judgment -- there is no assertion path.
|
|
16
15
|
const check = async (ctx)=>{
|
|
17
16
|
var _cfg_queries;
|
|
18
17
|
const cfg = ctx.resolveConfig();
|
|
@@ -22,28 +21,20 @@ const check = async (ctx)=>{
|
|
|
22
21
|
let failed = 0;
|
|
23
22
|
for (const [name, entry] of Object.entries((_cfg_queries = cfg.queries) !== null && _cfg_queries !== void 0 ? _cfg_queries : {})){
|
|
24
23
|
var _sql_match;
|
|
25
|
-
|
|
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
|
-
}
|
|
24
|
+
if (typeof entry === 'object' && entry !== null && 'search' in entry) {
|
|
37
25
|
try {
|
|
38
|
-
const count = (await
|
|
26
|
+
const count = (await search(db, cfg, entry.search, {
|
|
39
27
|
k: 1,
|
|
40
|
-
where: entry.where
|
|
28
|
+
where: entry.where,
|
|
29
|
+
preset: entry.preset,
|
|
30
|
+
include: entry.include,
|
|
31
|
+
semantic: false
|
|
41
32
|
})).length;
|
|
42
33
|
rows.push({
|
|
43
34
|
query: name,
|
|
44
35
|
params: '—',
|
|
45
36
|
rows: '—',
|
|
46
|
-
status: count === 0 ? 'ok, but matches 0 notes (lexical probe)' :
|
|
37
|
+
status: count === 0 ? 'ok, but matches 0 notes (lexical probe)' : 'ok (probe run with k=1)'
|
|
47
38
|
});
|
|
48
39
|
} catch (err) {
|
|
49
40
|
failed++;
|
|
@@ -56,9 +47,8 @@ const check = async (ctx)=>{
|
|
|
56
47
|
}
|
|
57
48
|
continue;
|
|
58
49
|
}
|
|
59
|
-
const sql = entry;
|
|
50
|
+
const sql = typeof entry === 'string' ? entry : entry.sql;
|
|
60
51
|
const params = ((_sql_match = sql.match(/\?/g)) !== null && _sql_match !== void 0 ? _sql_match : []).length;
|
|
61
|
-
const expectEmpty = ((_cfg_checks = cfg.checks) === null || _cfg_checks === void 0 ? void 0 : _cfg_checks[name]) === 'empty';
|
|
62
52
|
try {
|
|
63
53
|
const statement = db.prepare(sql);
|
|
64
54
|
if (params > 0) {
|
|
@@ -71,23 +61,12 @@ const check = async (ctx)=>{
|
|
|
71
61
|
continue;
|
|
72
62
|
}
|
|
73
63
|
const count = statement.all().length;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
rows
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
rows: count,
|
|
81
|
-
status: count === 0 ? 'ok (empty, as asserted)' : `FAILED: expected empty, returned ${count} row(s)`
|
|
82
|
-
});
|
|
83
|
-
} else {
|
|
84
|
-
rows.push({
|
|
85
|
-
query: name,
|
|
86
|
-
params,
|
|
87
|
-
rows: count,
|
|
88
|
-
status: count === 0 ? 'ok, but returns 0 rows' : 'ok'
|
|
89
|
-
});
|
|
90
|
-
}
|
|
64
|
+
rows.push({
|
|
65
|
+
query: name,
|
|
66
|
+
params,
|
|
67
|
+
rows: count,
|
|
68
|
+
status: count === 0 ? 'ok, but returns 0 rows' : 'ok'
|
|
69
|
+
});
|
|
91
70
|
} catch (err) {
|
|
92
71
|
failed++;
|
|
93
72
|
rows.push({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/check.ts"],"sourcesContent":["import {
|
|
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 { printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// A saved query that returns zero rows looks identical to a true empty result, so a broken\n// one can sit unnoticed -- one field report had `WHERE flag = 'true'` against a numeric\n// column reading as \"nothing tagged yet\" for hours. Preparing each query catches syntax and\n// unknown-column errors without executing it; queries that take no parameters are also run\n// for a row count. Parameterised queries are validated but not counted: inventing arguments\n// would report a count for a query nobody ran. Saved searches run lexically with k=1 -- that\n// validates the `where` fragment, the FTS5 terms, and the `preset` name (resolveSearch throws\n// on an unknown one, the same breakage class prepare() catches for SQL strings) -- but never\n// semantically (a semantic pass costs model time and, on api trees, network). Whether a\n// result being empty is good or bad is the reader's judgment -- there is no assertion path.\nconst check: Command = async (ctx) => {\n const 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 === 'object' && entry !== null && 'search' in entry) {\n try {\n const count = (await search(db, cfg, entry.search, { k: 1, where: entry.where, preset: entry.preset, include: entry.include, semantic: false })).length;\n rows.push({ query: name, params: '—', rows: '—', status: count === 0 ? 'ok, but matches 0 notes (lexical probe)' : 'ok (probe run with k=1)' });\n } catch (err) {\n failed++;\n rows.push({ query: name, params: '—', rows: '—', status: `FAILED: ${(err as Error).message}` });\n }\n continue;\n }\n const sql = typeof entry === 'string' ? entry : entry.sql;\n const params = (sql.match(/\\?/g) ?? []).length;\n try {\n const statement = db.prepare(sql);\n if (params > 0) {\n rows.push({ query: name, params, rows: '—', status: 'ok (not run: needs parameters)' });\n continue;\n }\n const count = (statement.all() as unknown[]).length;\n rows.push({ query: name, params, rows: count, status: count === 0 ? 'ok, but returns 0 rows' : 'ok' });\n } catch (err) {\n failed++;\n rows.push({ query: name, params, rows: '—', status: `FAILED: ${(err as Error).message}` });\n }\n }\n\n db.close();\n if (rows.length === 0) {\n console.log('no saved queries in config');\n return;\n }\n printRows(rows, ctx.format);\n if (failed > 0) process.exit(1);\n};\nexport default check;\n"],"names":["search","open","printRows","printWarnings","check","ctx","cfg","resolveConfig","db","warnings","rows","failed","name","entry","Object","entries","queries","sql","count","k","where","preset","include","semantic","length","push","query","params","status","err","message","match","statement","prepare","all","close","console","log","format","process","exit"],"mappings":"AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,IAAI,QAAQ,WAAW;AAEhC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,aAAa,QAAQ,cAAc;AAG5C,2FAA2F;AAC3F,wFAAwF;AACxF,4FAA4F;AAC5F,2FAA2F;AAC3F,4FAA4F;AAC5F,6FAA6F;AAC7F,8FAA8F;AAC9F,6FAA6F;AAC7F,wFAAwF;AACxF,4FAA4F;AAC5F,MAAMC,QAAiB,OAAOC;QAOeC;IAN3C,MAAMA,MAAMD,IAAIE,aAAa;IAC7B,MAAM,EAAEC,EAAE,EAAEC,QAAQ,EAAE,GAAGR,KAAKK;IAC9BH,cAAcM;IAEd,MAAMC,OAAc,EAAE;IACtB,IAAIC,SAAS;IACb,KAAK,MAAM,CAACC,MAAMC,MAAM,IAAIC,OAAOC,OAAO,EAACT,eAAAA,IAAIU,OAAO,cAAXV,0BAAAA,eAAe,CAAC,GAAI;YAY7CW;QAXhB,IAAI,OAAOJ,UAAU,YAAYA,UAAU,QAAQ,YAAYA,OAAO;YACpE,IAAI;gBACF,MAAMK,QAAQ,AAAC,CAAA,MAAMlB,OAAOQ,IAAIF,KAAKO,MAAMb,MAAM,EAAE;oBAAEmB,GAAG;oBAAGC,OAAOP,MAAMO,KAAK;oBAAEC,QAAQR,MAAMQ,MAAM;oBAAEC,SAAST,MAAMS,OAAO;oBAAEC,UAAU;gBAAM,EAAC,EAAGC,MAAM;gBACvJd,KAAKe,IAAI,CAAC;oBAAEC,OAAOd;oBAAMe,QAAQ;oBAAKjB,MAAM;oBAAKkB,QAAQV,UAAU,IAAI,4CAA4C;gBAA0B;YAC/I,EAAE,OAAOW,KAAK;gBACZlB;gBACAD,KAAKe,IAAI,CAAC;oBAAEC,OAAOd;oBAAMe,QAAQ;oBAAKjB,MAAM;oBAAKkB,QAAQ,CAAC,QAAQ,EAAE,AAACC,IAAcC,OAAO,EAAE;gBAAC;YAC/F;YACA;QACF;QACA,MAAMb,MAAM,OAAOJ,UAAU,WAAWA,QAAQA,MAAMI,GAAG;QACzD,MAAMU,SAAS,EAACV,aAAAA,IAAIc,KAAK,CAAC,oBAAVd,wBAAAA,aAAoB,EAAE,EAAEO,MAAM;QAC9C,IAAI;YACF,MAAMQ,YAAYxB,GAAGyB,OAAO,CAAChB;YAC7B,IAAIU,SAAS,GAAG;gBACdjB,KAAKe,IAAI,CAAC;oBAAEC,OAAOd;oBAAMe;oBAAQjB,MAAM;oBAAKkB,QAAQ;gBAAiC;gBACrF;YACF;YACA,MAAMV,QAAQ,AAACc,UAAUE,GAAG,GAAiBV,MAAM;YACnDd,KAAKe,IAAI,CAAC;gBAAEC,OAAOd;gBAAMe;gBAAQjB,MAAMQ;gBAAOU,QAAQV,UAAU,IAAI,2BAA2B;YAAK;QACtG,EAAE,OAAOW,KAAK;YACZlB;YACAD,KAAKe,IAAI,CAAC;gBAAEC,OAAOd;gBAAMe;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;IACAnC,UAAUQ,MAAML,IAAIiC,MAAM;IAC1B,IAAI3B,SAAS,GAAG4B,QAAQC,IAAI,CAAC;AAC/B;AACA,eAAepC,MAAM"}
|
package/dist/esm/cli/index.js
CHANGED
|
@@ -8,7 +8,7 @@ export const COMMANDS = {
|
|
|
8
8
|
check: ()=>import('./check.js'),
|
|
9
9
|
rebuild: ()=>import('./rebuild.js'),
|
|
10
10
|
query: ()=>import('./query.js'),
|
|
11
|
-
|
|
11
|
+
search: ()=>import('./search.js'),
|
|
12
12
|
map: ()=>import('./map.js'),
|
|
13
13
|
peek: ()=>import('./peek.js')
|
|
14
14
|
};
|
|
@@ -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// 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
|
|
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 search: () => import('./search.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","search","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,QAAQ,IAAM,MAAM,CAAC;IACrBC,KAAK,IAAM,MAAM,CAAC;IAClBC,MAAM,IAAM,MAAM,CAAC;AACrB,EAAE"}
|
package/dist/esm/cli/named.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { search } from '../commands.js';
|
|
2
2
|
import { printRows } from '../output.js';
|
|
3
3
|
import { parseK, runSql, withDb } from './shared.js';
|
|
4
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
|
|
5
|
+
// SQL string (run as-is) or a saved search (run through the `search` command's own machinery).
|
|
6
6
|
export default async function named(ctx, queryName, params) {
|
|
7
|
-
var _parseK, _ctx_values_where;
|
|
7
|
+
var _parseK, _ctx_values_where, _ctx_values_preset, _ctx_values_include;
|
|
8
8
|
const cfg = ctx.resolveConfig();
|
|
9
9
|
const entry = cfg.queries[queryName];
|
|
10
10
|
if (entry === undefined) {
|
|
@@ -16,18 +16,26 @@ export default async function named(ctx, queryName, params) {
|
|
|
16
16
|
runSql(cfg, entry, params, ctx.format, `query "${queryName}"`);
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
if ('sql' in entry) {
|
|
20
|
+
runSql(cfg, entry.sql, params, ctx.format, `query "${queryName}"`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
// A saved search's text is fixed in config; there is nowhere for a positional to bind.
|
|
20
24
|
if (params.length > 0) {
|
|
21
|
-
ctx.usageError(`"${queryName}" is a saved
|
|
25
|
+
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`);
|
|
22
26
|
}
|
|
23
27
|
const k = (_parseK = parseK(ctx)) !== null && _parseK !== void 0 ? _parseK : entry.k;
|
|
24
28
|
const where = (_ctx_values_where = ctx.values.where) !== null && _ctx_values_where !== void 0 ? _ctx_values_where : entry.where;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
const preset = (_ctx_values_preset = ctx.values.preset) !== null && _ctx_values_preset !== void 0 ? _ctx_values_preset : entry.preset;
|
|
30
|
+
const include = (_ctx_values_include = ctx.values.include) !== null && _ctx_values_include !== void 0 ? _ctx_values_include : entry.include;
|
|
31
|
+
// --lexical upgrades a saved search's semantic behavior the same way --where/--k
|
|
32
|
+
// override; absent means the saved value (the flag has no default false override).
|
|
33
|
+
const semantic = ctx.values.lexical ? false : entry.semantic;
|
|
34
|
+
await withDb(ctx, async (db, resolvedCfg)=>printRows(await search(db, resolvedCfg, entry.search, {
|
|
29
35
|
k,
|
|
30
36
|
where,
|
|
37
|
+
preset,
|
|
38
|
+
include,
|
|
31
39
|
semantic
|
|
32
40
|
}), ctx.format));
|
|
33
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/named.ts"],"sourcesContent":["import {
|
|
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 { 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 search (run through the `search` 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 if ('sql' in entry) {\n runSql(cfg, entry.sql, params, ctx.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(ctx) ?? entry.k;\n const where = ctx.values.where ?? entry.where;\n const preset = ctx.values.preset ?? entry.preset;\n const include = ctx.values.include ?? entry.include;\n // --lexical upgrades a saved search's semantic behavior the same way --where/--k\n // override; absent means the saved value (the flag has no default false override).\n const semantic = ctx.values.lexical ? false : entry.semantic;\n await withDb(ctx, async (db, resolvedCfg) => printRows(await search(db, resolvedCfg, entry.search, { k, where, preset, include, semantic }), ctx.format));\n}\n"],"names":["search","printRows","parseK","runSql","withDb","named","ctx","queryName","params","cfg","resolveConfig","entry","queries","undefined","console","error","Object","keys","sort","join","process","exit","format","sql","length","usageError","name","k","where","values","preset","include","semantic","lexical","db","resolvedCfg"],"mappings":"AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,MAAM,EAAEC,MAAM,EAAEC,MAAM,QAAQ,cAAc;AAGrD,2FAA2F;AAC3F,+FAA+F;AAC/F,eAAe,eAAeC,MAAMC,GAAQ,EAAEC,SAAiB,EAAEC,MAAgB;QAsBrEN,SACII,mBACCA,oBACCA;IAxBhB,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;IACA,IAAI,SAASI,OAAO;QAClBR,OAAOM,KAAKE,MAAMY,GAAG,EAAEf,QAAQF,IAAIgB,MAAM,EAAE,CAAC,OAAO,EAAEf,UAAU,CAAC,CAAC;QACjE;IACF;IAEA,uFAAuF;IACvF,IAAIC,OAAOgB,MAAM,GAAG,GAAG;QACrBlB,IAAImB,UAAU,CAAC,CAAC,CAAC,EAAElB,UAAU,wGAAwG,EAAED,IAAIoB,IAAI,CAAC,iBAAiB,CAAC;IACpK;IACA,MAAMC,KAAIzB,UAAAA,OAAOI,kBAAPJ,qBAAAA,UAAeS,MAAMgB,CAAC;IAChC,MAAMC,SAAQtB,oBAAAA,IAAIuB,MAAM,CAACD,KAAK,cAAhBtB,+BAAAA,oBAAoBK,MAAMiB,KAAK;IAC7C,MAAME,UAASxB,qBAAAA,IAAIuB,MAAM,CAACC,MAAM,cAAjBxB,gCAAAA,qBAAqBK,MAAMmB,MAAM;IAChD,MAAMC,WAAUzB,sBAAAA,IAAIuB,MAAM,CAACE,OAAO,cAAlBzB,iCAAAA,sBAAsBK,MAAMoB,OAAO;IACnD,iFAAiF;IACjF,mFAAmF;IACnF,MAAMC,WAAW1B,IAAIuB,MAAM,CAACI,OAAO,GAAG,QAAQtB,MAAMqB,QAAQ;IAC5D,MAAM5B,OAAOE,KAAK,OAAO4B,IAAIC,cAAgBlC,UAAU,MAAMD,OAAOkC,IAAIC,aAAaxB,MAAMX,MAAM,EAAE;YAAE2B;YAAGC;YAAOE;YAAQC;YAASC;QAAS,IAAI1B,IAAIgB,MAAM;AACzJ"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { search } from '../commands.js';
|
|
2
|
+
import { printRows } from '../output.js';
|
|
3
|
+
import { parseK, withDb } from './shared.js';
|
|
4
|
+
const searchCmd = async (ctx)=>{
|
|
5
|
+
const [terms] = ctx.rest;
|
|
6
|
+
if (!terms) ctx.usageError(`usage: ${ctx.name} search "<terms>" [--preset name] [--include glob ...] [--where "<sql>"] [--k n] [--lexical]`);
|
|
7
|
+
const k = parseK(ctx);
|
|
8
|
+
await withDb(ctx, async (db, cfg)=>printRows(await search(db, cfg, terms, {
|
|
9
|
+
k,
|
|
10
|
+
where: ctx.values.where,
|
|
11
|
+
preset: ctx.values.preset,
|
|
12
|
+
include: ctx.values.include,
|
|
13
|
+
semantic: ctx.values.lexical ? false : undefined
|
|
14
|
+
}), ctx.format));
|
|
15
|
+
};
|
|
16
|
+
export default searchCmd;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/search.ts"],"sourcesContent":["import { search } from '../commands.ts';\nimport { printRows } from '../output.ts';\nimport { parseK, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst searchCmd: Command = async (ctx) => {\n const [terms] = ctx.rest;\n if (!terms) ctx.usageError(`usage: ${ctx.name} search \"<terms>\" [--preset name] [--include glob ...] [--where \"<sql>\"] [--k n] [--lexical]`);\n const k = parseK(ctx);\n await withDb(ctx, async (db, cfg) => printRows(await search(db, cfg, terms, { k, where: ctx.values.where, preset: ctx.values.preset, include: ctx.values.include, semantic: ctx.values.lexical ? false : undefined }), ctx.format));\n};\nexport default searchCmd;\n"],"names":["search","printRows","parseK","withDb","searchCmd","ctx","terms","rest","usageError","name","k","db","cfg","where","values","preset","include","semantic","lexical","undefined","format"],"mappings":"AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,MAAM,EAAEC,MAAM,QAAQ,cAAc;AAG7C,MAAMC,YAAqB,OAAOC;IAChC,MAAM,CAACC,MAAM,GAAGD,IAAIE,IAAI;IACxB,IAAI,CAACD,OAAOD,IAAIG,UAAU,CAAC,CAAC,OAAO,EAAEH,IAAII,IAAI,CAAC,4FAA4F,CAAC;IAC3I,MAAMC,IAAIR,OAAOG;IACjB,MAAMF,OAAOE,KAAK,OAAOM,IAAIC,MAAQX,UAAU,MAAMD,OAAOW,IAAIC,KAAKN,OAAO;YAAEI;YAAGG,OAAOR,IAAIS,MAAM,CAACD,KAAK;YAAEE,QAAQV,IAAIS,MAAM,CAACC,MAAM;YAAEC,SAASX,IAAIS,MAAM,CAACE,OAAO;YAAEC,UAAUZ,IAAIS,MAAM,CAACI,OAAO,GAAG,QAAQC;QAAU,IAAId,IAAIe,MAAM;AACnO;AACA,eAAehB,UAAU"}
|
package/dist/esm/cli/shared.js
CHANGED
|
@@ -3,7 +3,7 @@ import { printRows } from '../output.js';
|
|
|
3
3
|
import { searchError } from '../search-error.js';
|
|
4
4
|
// --k must be a positive integer: SQLite reads a bound LIMIT of -1 as "unlimited" and 0 as
|
|
5
5
|
// "nothing", and parseInt would silently truncate "5.9" -- all three are caller mistakes
|
|
6
|
-
// worth a usage error, matching the config-level
|
|
6
|
+
// worth a usage error, matching the config-level SavedSearch validation.
|
|
7
7
|
export function parseK(ctx) {
|
|
8
8
|
if (ctx.values.k === undefined) return undefined;
|
|
9
9
|
const k = Number(ctx.values.k);
|
|
@@ -1 +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
|
|
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 SavedSearch 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,yEAAyE;AACzE,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"}
|