token-goat 2.9.14 → 2.9.16

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.
Files changed (46) hide show
  1. package/README.md +15 -1
  2. package/dist/{token-goat-chunk-2ESBO4IN.mjs → token-goat-chunk-2IEIBVVD.mjs} +16 -9
  3. package/dist/{token-goat-chunk-RUDOKYPJ.mjs → token-goat-chunk-2PCFAQAS.mjs} +6582 -6194
  4. package/dist/{token-goat-chunk-AMYCQJX4.mjs → token-goat-chunk-3H6FQT62.mjs} +49 -256
  5. package/dist/{token-goat-chunk-PRJVGIC5.mjs → token-goat-chunk-4DC6DDIB.mjs} +7 -5
  6. package/dist/token-goat-chunk-4EXFN2AW.mjs +29 -0
  7. package/dist/{token-goat-chunk-VZYD4OZB.mjs → token-goat-chunk-5USHO7B6.mjs} +416 -4168
  8. package/dist/token-goat-chunk-63QWJ6UM.mjs +277 -0
  9. package/dist/token-goat-chunk-BFNTLGVA.mjs +4547 -0
  10. package/dist/token-goat-chunk-BGHSSJUA.mjs +102 -0
  11. package/dist/{token-goat-chunk-T2IWWTHB.mjs → token-goat-chunk-DMQ32ZSR.mjs} +35 -1142
  12. package/dist/{token-goat-chunk-DBNY4RLN.mjs → token-goat-chunk-EJCY6KHO.mjs} +5 -3
  13. package/dist/token-goat-chunk-ERTXEKB6.mjs +228 -0
  14. package/dist/{token-goat-chunk-Z6UXPYJA.mjs → token-goat-chunk-F2ARFHLJ.mjs} +1 -1
  15. package/dist/{token-goat-chunk-EG3663UT.mjs → token-goat-chunk-GIMGT34T.mjs} +4 -2
  16. package/dist/{token-goat-chunk-XVZ4MNQC.mjs → token-goat-chunk-GMXBQS6O.mjs} +360 -116
  17. package/dist/{token-goat-chunk-SAQ5PG4L.mjs → token-goat-chunk-H3DXI6VD.mjs} +8 -4
  18. package/dist/token-goat-chunk-LJL6FGDS.mjs +35 -0
  19. package/dist/{token-goat-chunk-NEI4NC54.mjs → token-goat-chunk-LKSXAMJB.mjs} +7 -2
  20. package/dist/token-goat-chunk-LMFO66YD.mjs +331 -0
  21. package/dist/{token-goat-chunk-7OGKZ7AP.mjs → token-goat-chunk-M2R4UQ3B.mjs} +5 -3
  22. package/dist/{token-goat-chunk-YHGTGG6K.mjs → token-goat-chunk-MA5BZ2KI.mjs} +68 -7
  23. package/dist/{token-goat-chunk-ASVVF4JV.mjs → token-goat-chunk-MIL62GMN.mjs} +171 -23
  24. package/dist/{token-goat-chunk-ZFM4PWXL.mjs → token-goat-chunk-NAMH252H.mjs} +10 -7
  25. package/dist/{token-goat-chunk-YTQHZJXW.mjs → token-goat-chunk-NOBZV7PM.mjs} +96 -22
  26. package/dist/{token-goat-chunk-4SDX3QP3.mjs → token-goat-chunk-NQZCSVN2.mjs} +13 -5
  27. package/dist/{token-goat-chunk-XEH6KBWW.mjs → token-goat-chunk-OCI25AXY.mjs} +4 -3
  28. package/dist/token-goat-chunk-OSUFN2FV.mjs +326 -0
  29. package/dist/{token-goat-chunk-O5WAMISC.mjs → token-goat-chunk-QMZMHQRR.mjs} +29 -18
  30. package/dist/{token-goat-chunk-POBYR64E.mjs → token-goat-chunk-R3X5TCPB.mjs} +801 -3
  31. package/dist/token-goat-chunk-RRNZMM3A.mjs +3364 -0
  32. package/dist/{token-goat-chunk-PGGDW7DZ.mjs → token-goat-chunk-ULA4WCED.mjs} +9 -6
  33. package/dist/token-goat-chunk-UMXD2M7O.mjs +975 -0
  34. package/dist/{token-goat-chunk-3XQPEJMV.mjs → token-goat-chunk-UXHDBVUR.mjs} +1 -1
  35. package/dist/{token-goat-chunk-EZNVAIR3.mjs → token-goat-chunk-VVIYEFBI.mjs} +4 -3
  36. package/dist/token-goat-chunk-XOHTFRDH.mjs +10760 -0
  37. package/dist/{token-goat-chunk-HF6H7RNK.mjs → token-goat-chunk-YPS64ACE.mjs} +13 -3
  38. package/dist/{token-goat-chunk-DAMXYVIW.mjs → token-goat-chunk-Z5VPAXTC.mjs} +2560 -820
  39. package/dist/{token-goat-chunk-XQF5J25J.mjs → token-goat-chunk-ZEHFYJ7Z.mjs} +5 -4
  40. package/dist/token-goat-hook.mjs +15 -10
  41. package/dist/token-goat.core.mjs +24 -18
  42. package/docs/cli.md +8 -6
  43. package/package.json +1 -1
  44. package/dist/token-goat-chunk-IT6O3PNN.mjs +0 -15463
  45. package/dist/token-goat-chunk-ZD4EM4LR.mjs +0 -30
  46. package/dist/token-goat-chunk-ZYNNQ36L.mjs +0 -479
@@ -11,10 +11,12 @@ import {
11
11
  decodeSource,
12
12
  extractErrorMessage,
13
13
  foldPath,
14
- normalizeDarwinSystemAlias,
15
14
  projectConfigPath,
16
15
  runGit
17
- } from "./token-goat-chunk-AMYCQJX4.mjs";
16
+ } from "./token-goat-chunk-3H6FQT62.mjs";
17
+ import {
18
+ normalizeDarwinSystemAlias
19
+ } from "./token-goat-chunk-ERTXEKB6.mjs";
18
20
  import {
19
21
  init_define_import_meta_env
20
22
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -1419,7 +1421,8 @@ var CONFIG_DEFAULTS = {
1419
1421
  image_shrink: {
1420
1422
  enabled: true,
1421
1423
  jpeg_quality: 75,
1422
- max_image_pixels: 16e6,
1424
+ // 16,000,000 used to reject a routine 24MP DSLR/phone photo outright -- the exact input this feature exists to shrink -- while the engine's own decode ceiling (MAX_DECODED_BYTES in image_engine.ts, 256MB at 4 bytes/pixel for a single frame) sits at 67,108,864px. 64,000,000 covers cameras well past 24MP (including 48MP phone sensors) with ~4.9% margin below that hard ceiling, which assertDecodableSize enforces independently of this value on every decode regardless of what this header check allows through. Measured on this engine (2026-09-17): a 24MP PNG decodes+shrinks in ~370ms, 60,000,516px in ~920ms, and 67,108,864px (the ceiling itself) in ~760ms -- all comfortably fast, so the new value is chosen for coverage headroom under the ceiling, not for decode-time cost. Decode time is not the cost that binds, though: memory is. This value is read off a header before anything is decoded, so what it really sets is how large a buffer a file's own declared dimensions may talk this hook into allocating -- at 4 bytes per pixel, raising it from 16,000,000 raised that peak from ~64MB to ~256MB, which is why it now sits flush against MAX_DECODED_BYTES rather than comfortably below it. And on the JPEG path there is no assertDecodableSize call at all: decodeJpeg hands the buffer to jpeg-js, so a JPEG decode is bounded by whatever maxResolutionInMP/maxMemoryUsageInMB that call passes -- a bound this codebase states only because decodeJpeg passes both explicitly rather than inheriting jpeg-js's own 100MP default, which is looser than the 67.1MP MAX_DECODED_BYTES allows.
1425
+ max_image_pixels: 64e6,
1423
1426
  screenshot_redirect: true,
1424
1427
  ocr_enabled: true,
1425
1428
  // Confidence is Tesseract's own 0-100 mean-word-confidence score. 65 is a deliberately
@@ -1564,7 +1567,7 @@ var CONFIG_DEFAULTS = {
1564
1567
  offline: false
1565
1568
  },
1566
1569
  mcp: {
1567
- confine_reads_to_project_root: true,
1570
+ confine_reads_to_project_root: false,
1568
1571
  allowed_roots: []
1569
1572
  },
1570
1573
  hint_stats: {
@@ -1953,6 +1956,7 @@ function invalidateConfigCache() {
1953
1956
  _cached2 = null;
1954
1957
  resetLastProjectConfigLockedKeys();
1955
1958
  }
1959
+ registerReset(invalidateConfigCache);
1956
1960
  function withoutConfigEnv(fn) {
1957
1961
  const keys = allEnvKeys();
1958
1962
  const saved = {};
@@ -0,0 +1,35 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ buildEvent,
5
+ relay,
6
+ relayInProcess
7
+ } from "./token-goat-chunk-GMXBQS6O.mjs";
8
+ import "./token-goat-chunk-UXHDBVUR.mjs";
9
+ import {
10
+ MAX_STDIN_BYTES,
11
+ readStdinJson
12
+ } from "./token-goat-chunk-UMXD2M7O.mjs";
13
+ import "./token-goat-chunk-XOHTFRDH.mjs";
14
+ import "./token-goat-chunk-5USHO7B6.mjs";
15
+ import "./token-goat-chunk-DMQ32ZSR.mjs";
16
+ import "./token-goat-chunk-3BTK54F3.mjs";
17
+ import "./token-goat-chunk-BFNTLGVA.mjs";
18
+ import "./token-goat-chunk-63QWJ6UM.mjs";
19
+ import "./token-goat-chunk-R3X5TCPB.mjs";
20
+ import "./token-goat-chunk-H3DXI6VD.mjs";
21
+ import "./token-goat-chunk-EEIDFMEM.mjs";
22
+ import "./token-goat-chunk-OSUFN2FV.mjs";
23
+ import "./token-goat-chunk-3H6FQT62.mjs";
24
+ import "./token-goat-chunk-ERTXEKB6.mjs";
25
+ import "./token-goat-chunk-Y4AFKTHK.mjs";
26
+ import "./token-goat-chunk-GMOUBOX4.mjs";
27
+ import "./token-goat-chunk-RRNZMM3A.mjs";
28
+ import "./token-goat-chunk-A37V4PBF.mjs";
29
+ export {
30
+ MAX_STDIN_BYTES,
31
+ buildEvent,
32
+ readStdinJson,
33
+ relay,
34
+ relayInProcess
35
+ };
@@ -280,7 +280,7 @@ async function extractPdfText(data, pagesSpec, layout = false) {
280
280
  for (let i = start; i <= end; i++) {
281
281
  const page = await getPageWithinDeadline(doc, i, deadline);
282
282
  const textItems = await readPageTextItems(page, MAX_PDF_TEXT_BYTES - spent, deadline);
283
- const pageText = layout ? reconstructLayout(textItems, deadline) : textItems.map((item) => item.str).join(" ");
283
+ const pageText = layout ? reconstructLayout(textItems, deadline) : joinTextItems(textItems, "\n");
284
284
  spent += pageText.length;
285
285
  pages.push(pageText.trim());
286
286
  }
@@ -306,7 +306,7 @@ async function locatePdfPages(data, pattern, opts) {
306
306
  for (; i <= end && matches.length < maxMatches; i++) {
307
307
  const page = await getPageWithinDeadline(doc, i, deadline);
308
308
  const textItems = await readPageTextItems(page, MAX_PDF_TEXT_BYTES, deadline);
309
- const pageText = textItems.map((item) => item.str).join(" ");
309
+ const pageText = joinTextItems(textItems, " ");
310
310
  const m = re.exec(pageText);
311
311
  if (m === null) continue;
312
312
  matches.push({ page: i, snippet: locateSnippet(pageText, m.index, m[0].length, context) });
@@ -315,6 +315,11 @@ async function locatePdfPages(data, pattern, opts) {
315
315
  return { matches, truncated };
316
316
  });
317
317
  }
318
+ function joinTextItems(items, eol) {
319
+ let out = "";
320
+ for (const item of items) out += item.str + (item.hasEOL ? eol : "");
321
+ return out;
322
+ }
318
323
  function locateSnippet(text, index, matchLen, context) {
319
324
  const kept = Math.min(matchLen, context);
320
325
  const pad = Math.max(0, context - kept);
@@ -0,0 +1,331 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ Database
5
+ } from "./token-goat-chunk-OSUFN2FV.mjs";
6
+ import {
7
+ displaySafeText
8
+ } from "./token-goat-chunk-ERTXEKB6.mjs";
9
+ import {
10
+ init_define_import_meta_env
11
+ } from "./token-goat-chunk-A37V4PBF.mjs";
12
+
13
+ // src/sqlite_query.ts
14
+ init_define_import_meta_env();
15
+ import * as fs from "node:fs";
16
+ var SQLITE_QUERY_ROW_CAP = 5e3;
17
+ var SQLITE_MAGIC = Buffer.from([83, 81, 76, 105, 116, 101, 32, 102, 111, 114, 109, 97, 116, 32, 51, 0]);
18
+ function readMagicBytes(filePath) {
19
+ let fd;
20
+ try {
21
+ fd = fs.openSync(filePath, "r");
22
+ } catch {
23
+ return null;
24
+ }
25
+ try {
26
+ const buf = Buffer.alloc(SQLITE_MAGIC.length);
27
+ const bytesRead = fs.readSync(fd, buf, 0, buf.length, 0);
28
+ return bytesRead === buf.length ? buf : null;
29
+ } catch {
30
+ return null;
31
+ } finally {
32
+ fs.closeSync(fd);
33
+ }
34
+ }
35
+ function isSqliteFile(filePath) {
36
+ const magic = readMagicBytes(filePath);
37
+ return magic !== null && magic.equals(SQLITE_MAGIC);
38
+ }
39
+ function openReadonlySqlite(filePath) {
40
+ if (!fs.existsSync(filePath)) {
41
+ throw new Error(`file not found: ${displaySafeText(filePath)}`);
42
+ }
43
+ if (!isSqliteFile(filePath)) {
44
+ throw new Error(`not a valid SQLite database (bad file header): ${displaySafeText(filePath)}`);
45
+ }
46
+ try {
47
+ return new Database(filePath, { readonly: true, fileMustExist: true });
48
+ } catch (e) {
49
+ const msg = e instanceof Error ? e.message : String(e);
50
+ throw new Error(`failed to open SQLite database: ${msg}`, { cause: e });
51
+ }
52
+ }
53
+ function quoteIdent(name) {
54
+ return `"${name.replace(/"/g, '""')}"`;
55
+ }
56
+ function getSqliteSchema(filePath) {
57
+ const db = openReadonlySqlite(filePath);
58
+ try {
59
+ const objects = db.prepare("SELECT name, type FROM sqlite_master WHERE type IN ('table','view') AND name NOT LIKE 'sqlite\\_%' ESCAPE '\\' ORDER BY name").all();
60
+ const tables = objects.map((o) => {
61
+ const columns = db.prepare(`PRAGMA table_info(${quoteIdent(o.name)})`).all().map(
62
+ (c) => ({
63
+ name: c.name,
64
+ type: c.type || "",
65
+ notNull: c.notnull === 1,
66
+ primaryKey: c.pk > 0,
67
+ defaultValue: c.dflt_value === null || c.dflt_value === void 0 ? null : String(c.dflt_value)
68
+ })
69
+ );
70
+ const indexes = db.prepare(`PRAGMA index_list(${quoteIdent(o.name)})`).all().map(
71
+ (idx) => {
72
+ const idxColumns = db.prepare(`PRAGMA index_info(${quoteIdent(idx.name)})`).all().map((c) => c.name);
73
+ return { name: idx.name, unique: idx.unique === 1, columns: idxColumns };
74
+ }
75
+ );
76
+ const foreignKeys = db.prepare(`PRAGMA foreign_key_list(${quoteIdent(o.name)})`).all().map((fk) => ({ table: fk.table, from: fk.from, to: fk.to }));
77
+ let rowCount;
78
+ try {
79
+ const row = db.prepare(`SELECT COUNT(*) AS c FROM ${quoteIdent(o.name)}`).get();
80
+ rowCount = row.c;
81
+ } catch {
82
+ rowCount = null;
83
+ }
84
+ return { name: o.name, kind: o.type === "view" ? "view" : "table", columns, indexes, foreignKeys, rowCount };
85
+ });
86
+ return { tables };
87
+ } finally {
88
+ db.close();
89
+ }
90
+ }
91
+ function formatSqliteSchema(result) {
92
+ if (result.tables.length === 0) return "(no tables or views found)";
93
+ return result.tables.map((t) => {
94
+ const lines = [`${t.name} (${t.kind}${t.rowCount !== null ? `, ${t.rowCount} row${t.rowCount === 1 ? "" : "s"}` : ""})`];
95
+ for (const c of t.columns) {
96
+ const flags = [c.primaryKey ? "PK" : null, c.notNull ? "NOT NULL" : null, c.defaultValue !== null ? `DEFAULT ${c.defaultValue}` : null].filter((f) => f !== null).join(" ");
97
+ lines.push(` ${displaySafeText(c.name)} ${displaySafeText(c.type || "(untyped)")}${flags ? ` ${flags}` : ""}`);
98
+ }
99
+ if (t.indexes.length > 0) {
100
+ lines.push(" indexes:");
101
+ for (const idx of t.indexes) {
102
+ lines.push(` ${displaySafeText(idx.name)}${idx.unique ? " (unique)" : ""}: ${displaySafeText(idx.columns.join(", "))}`);
103
+ }
104
+ }
105
+ if (t.foreignKeys.length > 0) {
106
+ lines.push(" foreign keys:");
107
+ for (const fk of t.foreignKeys) {
108
+ lines.push(` ${fk.from} -> ${fk.table}.${fk.to}`);
109
+ }
110
+ }
111
+ return lines.join("\n");
112
+ }).join("\n\n");
113
+ }
114
+ function getSqliteTables(filePath) {
115
+ const db = openReadonlySqlite(filePath);
116
+ try {
117
+ const objects = db.prepare(
118
+ // ESCAPE makes every `_` literal; see getSqliteSchema above. Here it costs three tables rather than one, since `%_fts_%` and `%_vec0_%` exist to hide the shadow tables FTS5 and sqlite-vec create beside a virtual table, and unescaped they also hide anything of the shape `my_ftsx_cache`.
119
+ "SELECT name, type FROM sqlite_master WHERE type IN ('table','view') AND name NOT LIKE 'sqlite\\_%' ESCAPE '\\' AND name NOT LIKE '%\\_fts\\_%' ESCAPE '\\' AND name NOT LIKE '%\\_vec0\\_%' ESCAPE '\\' ORDER BY name"
120
+ ).all();
121
+ return objects.map((o) => {
122
+ let columnCount;
123
+ try {
124
+ const cols = db.prepare(`PRAGMA table_info(${quoteIdent(o.name)})`).all();
125
+ columnCount = cols.length;
126
+ } catch {
127
+ columnCount = 0;
128
+ }
129
+ let rowCount;
130
+ try {
131
+ const row = db.prepare(`SELECT COUNT(*) AS c FROM ${quoteIdent(o.name)}`).get();
132
+ rowCount = row.c;
133
+ } catch {
134
+ rowCount = null;
135
+ }
136
+ return {
137
+ name: o.name,
138
+ kind: o.type === "view" ? "view" : "table",
139
+ rowCount,
140
+ columnCount
141
+ };
142
+ });
143
+ } finally {
144
+ db.close();
145
+ }
146
+ }
147
+ function formatSqliteTables(tables) {
148
+ if (tables.length === 0) return "(no tables or views found)";
149
+ return tables.map((t) => {
150
+ const parts = [t.kind];
151
+ if (t.rowCount !== null) {
152
+ parts.push(`${t.rowCount.toLocaleString()} row${t.rowCount === 1 ? "" : "s"}`);
153
+ }
154
+ parts.push(`${t.columnCount} col${t.columnCount === 1 ? "" : "s"}`);
155
+ return `${displaySafeText(t.name)} (${parts.join(", ")})`;
156
+ }).join("\n");
157
+ }
158
+ var FORBIDDEN_KEYWORDS = [
159
+ "INSERT",
160
+ "UPDATE",
161
+ "DELETE",
162
+ "DROP",
163
+ "ALTER",
164
+ "CREATE",
165
+ "ATTACH",
166
+ "DETACH",
167
+ "TRUNCATE",
168
+ "VACUUM",
169
+ "REINDEX",
170
+ "PRAGMA",
171
+ "BEGIN",
172
+ "COMMIT",
173
+ "ROLLBACK",
174
+ "SAVEPOINT",
175
+ "RELEASE",
176
+ "GRANT",
177
+ "REVOKE"
178
+ ];
179
+ function stripSqlLiteralsAndComments(sql) {
180
+ let out = "";
181
+ let i = 0;
182
+ const n = sql.length;
183
+ while (i < n) {
184
+ const c = sql[i];
185
+ if (c === "'" || c === '"' || c === "`") {
186
+ const quote = c;
187
+ out += " ";
188
+ i++;
189
+ while (i < n) {
190
+ if (sql[i] === quote) {
191
+ if (sql[i + 1] === quote) {
192
+ i += 2;
193
+ continue;
194
+ }
195
+ i++;
196
+ break;
197
+ }
198
+ i++;
199
+ }
200
+ continue;
201
+ }
202
+ if (c === "[") {
203
+ out += " ";
204
+ i++;
205
+ while (i < n && sql[i] !== "]") i++;
206
+ if (i < n) i++;
207
+ continue;
208
+ }
209
+ if (c === "-" && sql[i + 1] === "-") {
210
+ while (i < n && sql[i] !== "\n") i++;
211
+ continue;
212
+ }
213
+ if (c === "/" && sql[i + 1] === "*") {
214
+ i += 2;
215
+ while (i < n && !(sql[i] === "*" && sql[i + 1] === "/")) i++;
216
+ i += 2;
217
+ continue;
218
+ }
219
+ out += c;
220
+ i++;
221
+ }
222
+ return out;
223
+ }
224
+ function validateReadOnlySelect(sql) {
225
+ const stripped = stripSqlLiteralsAndComments(sql);
226
+ const trimmed = stripped.trim();
227
+ if (trimmed === "") {
228
+ throw new Error("empty query");
229
+ }
230
+ const withoutTrailingSemicolons = trimmed.replace(/;+\s*$/, "");
231
+ if (withoutTrailingSemicolons.includes(";")) {
232
+ throw new Error("multiple statements are not allowed (sqlite-query accepts exactly one read-only SELECT statement)");
233
+ }
234
+ const upper = withoutTrailingSemicolons.toUpperCase();
235
+ if (!/^(SELECT|WITH)\b/.test(upper.trimStart())) {
236
+ throw new Error("only SELECT statements are allowed (sqlite-query is read-only)");
237
+ }
238
+ for (const kw of FORBIDDEN_KEYWORDS) {
239
+ if (new RegExp(`\\b${kw}\\b`).test(upper)) {
240
+ throw new Error(`statement contains forbidden keyword '${kw}' (sqlite-query only allows read-only SELECT queries)`);
241
+ }
242
+ }
243
+ if (/\bREPLACE\b(?!\s*\()/.test(upper)) {
244
+ throw new Error("statement contains forbidden keyword 'REPLACE' (sqlite-query only allows read-only SELECT queries)");
245
+ }
246
+ }
247
+ function normalizeSqliteScalar(value) {
248
+ if (typeof value === "bigint") {
249
+ return Number.isSafeInteger(Number(value)) ? Number(value) : value.toString();
250
+ }
251
+ return value;
252
+ }
253
+ function normalizeSqliteRow(row) {
254
+ const out = {};
255
+ for (const [k, v] of Object.entries(row)) out[k] = normalizeSqliteScalar(v);
256
+ return out;
257
+ }
258
+ function runReadOnlySqliteQuery(filePath, sql, opts = {}) {
259
+ validateReadOnlySelect(sql);
260
+ const rowCap = opts.rowCap ?? SQLITE_QUERY_ROW_CAP;
261
+ const db = openReadonlySqlite(filePath);
262
+ try {
263
+ let stmt;
264
+ try {
265
+ stmt = db.prepare(sql);
266
+ } catch (e) {
267
+ const msg = e instanceof Error ? e.message : String(e);
268
+ throw new Error(`invalid SQL: ${msg}`, { cause: e });
269
+ }
270
+ if (!stmt.reader) {
271
+ throw new Error("only read-only SELECT statements are allowed (sqlite-query is read-only)");
272
+ }
273
+ stmt.safeIntegers(true);
274
+ let columns = [];
275
+ try {
276
+ columns = stmt.columns().map((c) => c.name);
277
+ } catch {
278
+ columns = [];
279
+ }
280
+ const rows = [];
281
+ let rowCapped = false;
282
+ for (const row of stmt.iterate()) {
283
+ if (rows.length >= rowCap) {
284
+ rowCapped = true;
285
+ break;
286
+ }
287
+ rows.push(normalizeSqliteRow(row));
288
+ }
289
+ return { columns, rows, rowCapped };
290
+ } finally {
291
+ db.close();
292
+ }
293
+ }
294
+ function formatSqliteCell(value) {
295
+ if (value === null || value === void 0) return "";
296
+ if (value instanceof Uint8Array) return `<blob ${value.length} bytes>`;
297
+ return String(value);
298
+ }
299
+ function formatSqliteQueryTable(result, opts = {}) {
300
+ if (result.columns.length === 0 && result.rows.length === 0) return "(no rows)";
301
+ const lines = [
302
+ result.columns.map(quoteCsvCellLocal).join(","),
303
+ ...result.rows.map((r) => result.columns.map((c) => quoteCsvCellLocal(formatSqliteCell(r[c]))).join(","))
304
+ ];
305
+ if (opts.headTruncated === true) {
306
+ lines.push("...(more rows elided; use --head to see more)");
307
+ }
308
+ if (result.rowCapped) {
309
+ lines.push(`...(result truncated at the ${SQLITE_QUERY_ROW_CAP}-row safety cap; narrow the query with WHERE/LIMIT for a complete result)`);
310
+ }
311
+ return lines.join("\n");
312
+ }
313
+ function quoteCsvCellLocal(cell) {
314
+ if (cell.includes(",") || cell.includes('"') || cell.includes("\n") || cell.includes("\r")) {
315
+ return `"${cell.replace(/"/g, '""')}"`;
316
+ }
317
+ return cell;
318
+ }
319
+
320
+ export {
321
+ SQLITE_QUERY_ROW_CAP,
322
+ isSqliteFile,
323
+ openReadonlySqlite,
324
+ getSqliteSchema,
325
+ formatSqliteSchema,
326
+ getSqliteTables,
327
+ formatSqliteTables,
328
+ validateReadOnlySelect,
329
+ runReadOnlySqliteQuery,
330
+ formatSqliteQueryTable
331
+ };
@@ -2,12 +2,14 @@ import { createRequire as __cjsRequire } from 'node:module';
2
2
  const require = __cjsRequire(import.meta.url);
3
3
  import {
4
4
  loadConfig
5
- } from "./token-goat-chunk-SAQ5PG4L.mjs";
5
+ } from "./token-goat-chunk-H3DXI6VD.mjs";
6
6
  import "./token-goat-chunk-EEIDFMEM.mjs";
7
7
  import {
8
- VERSION,
8
+ VERSION
9
+ } from "./token-goat-chunk-3H6FQT62.mjs";
10
+ import {
9
11
  displaySafeJson
10
- } from "./token-goat-chunk-AMYCQJX4.mjs";
12
+ } from "./token-goat-chunk-ERTXEKB6.mjs";
11
13
  import "./token-goat-chunk-GMOUBOX4.mjs";
12
14
  import {
13
15
  init_define_import_meta_env
@@ -10,13 +10,13 @@ import {
10
10
  import {
11
11
  createLazyModuleLoader
12
12
  } from "./token-goat-chunk-AH6QILZM.mjs";
13
+ import {
14
+ pushAll
15
+ } from "./token-goat-chunk-3H6FQT62.mjs";
13
16
  import {
14
17
  DocumentRefusedError,
15
18
  MAX_DOCUMENT_WORK_MILLIS
16
19
  } from "./token-goat-chunk-Y4AFKTHK.mjs";
17
- import {
18
- pushAll
19
- } from "./token-goat-chunk-AMYCQJX4.mjs";
20
20
  import {
21
21
  init_define_import_meta_env
22
22
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -332,7 +332,27 @@ function pushTextValue(runs, val) {
332
332
  runs.push(String(val["#text"]));
333
333
  }
334
334
  }
335
- function collectTextRuns(node, tag) {
335
+ var MATH_PARA_RE = /<m:oMathPara(?:\s[^>]*)?>([\s\S]*?)<\/m:oMathPara>/g;
336
+ var MATH_RE = /<m:oMath(?:\s[^>]*)?>([\s\S]*?)<\/m:oMath>/g;
337
+ var MATH_TEXT_RE = /<m:t(?:\s[^>]*)?>([^<]*)<\/m:t>/g;
338
+ function mathRunText(fragment) {
339
+ let out = "";
340
+ for (const m of fragment.matchAll(MATH_TEXT_RE)) out += m[1];
341
+ return out;
342
+ }
343
+ function inlineMathRuns(xml, openRun, closeRun) {
344
+ const asRun = (text) => text.length > 0 ? `${openRun}${text}${closeRun}` : "";
345
+ const withParas = xml.replace(MATH_PARA_RE, (_whole, inner) => {
346
+ const lines = [];
347
+ for (const m of inner.matchAll(MATH_RE)) {
348
+ const text = mathRunText(m[1]);
349
+ if (text.length > 0) lines.push(text);
350
+ }
351
+ return asRun(lines.length > 0 ? lines.join(" ") : mathRunText(inner));
352
+ });
353
+ return withParas.replace(MATH_RE, (_whole, inner) => asRun(mathRunText(inner)));
354
+ }
355
+ function collectTextRuns(node, tag, skipInside = []) {
336
356
  const runs = [];
337
357
  function walk(n) {
338
358
  if (Array.isArray(n)) {
@@ -342,6 +362,7 @@ function collectTextRuns(node, tag) {
342
362
  if (n !== null && typeof n === "object") {
343
363
  const obj = n;
344
364
  for (const [key, val] of Object.entries(obj)) {
365
+ if (skipInside.includes(key)) continue;
345
366
  if (key === tag) {
346
367
  pushTextValue(runs, val);
347
368
  } else if (val !== null && typeof val === "object") {
@@ -353,7 +374,23 @@ function collectTextRuns(node, tag) {
353
374
  walk(node);
354
375
  return runs;
355
376
  }
356
- function collectElements(node, tag) {
377
+ function dropAlternateContentFallbacks(node) {
378
+ if (Array.isArray(node)) {
379
+ node.forEach(dropAlternateContentFallbacks);
380
+ return;
381
+ }
382
+ if (node === null || typeof node !== "object") return;
383
+ for (const [key, val] of Object.entries(node)) {
384
+ if (key === "mc:AlternateContent") {
385
+ for (const alt of Array.isArray(val) ? val : [val]) {
386
+ if (alt !== null && typeof alt === "object" && "mc:Choice" in alt && "mc:Fallback" in alt) delete alt["mc:Fallback"];
387
+ }
388
+ }
389
+ if (val !== null && typeof val === "object") dropAlternateContentFallbacks(val);
390
+ }
391
+ }
392
+ function collectElements(node, tag, opts = {}) {
393
+ const skip = opts.skipInside;
357
394
  const out = [];
358
395
  function walk(n) {
359
396
  if (Array.isArray(n)) {
@@ -363,9 +400,17 @@ function collectElements(node, tag) {
363
400
  if (n !== null && typeof n === "object") {
364
401
  const obj = n;
365
402
  for (const [key, val] of Object.entries(obj)) {
403
+ if (skip !== void 0 && skip.includes(key)) continue;
366
404
  if (key === tag) {
367
- if (Array.isArray(val)) pushAll(out, val);
368
- else out.push(val);
405
+ if (opts.includeNested !== true) {
406
+ if (Array.isArray(val)) pushAll(out, val);
407
+ else out.push(val);
408
+ continue;
409
+ }
410
+ for (const item of Array.isArray(val) ? val : [val]) {
411
+ out.push(item);
412
+ if (item !== null && typeof item === "object") walk(item);
413
+ }
369
414
  } else if (val !== null && typeof val === "object") {
370
415
  walk(val);
371
416
  }
@@ -375,6 +420,19 @@ function collectElements(node, tag) {
375
420
  walk(node);
376
421
  return out;
377
422
  }
423
+ function collectParagraphTexts(node, paragraphTag, runTag, skipInside = [], breakTag) {
424
+ const paragraphs = collectElements(node, paragraphTag, { skipInside });
425
+ if (paragraphs.length === 0) {
426
+ const whole = joinParagraphRuns(node, runTag, skipInside, breakTag);
427
+ return whole.length > 0 ? [whole] : [];
428
+ }
429
+ return paragraphs.map((p) => joinParagraphRuns(p, runTag, skipInside, breakTag));
430
+ }
431
+ function joinParagraphRuns(node, runTag, skipInside, breakTag) {
432
+ const runs = collectTextRuns(node, runTag, skipInside);
433
+ const broken = breakTag !== void 0 && collectElements(node, breakTag, { skipInside }).length > 0;
434
+ return runs.join(broken ? " " : "");
435
+ }
378
436
  function sortNumberedParts(paths, pattern) {
379
437
  return paths.map((p) => {
380
438
  const m = pattern.exec(p);
@@ -390,7 +448,10 @@ export {
390
448
  ooxmlPartBudget,
391
449
  decodeZipEntry,
392
450
  parseOoxmlPart,
451
+ inlineMathRuns,
393
452
  collectTextRuns,
453
+ dropAlternateContentFallbacks,
394
454
  collectElements,
455
+ collectParagraphTexts,
395
456
  sortNumberedParts
396
457
  };