bantamkit-mcp 0.29.1 → 0.29.2
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/dist/docread.d.ts +82 -8
- package/dist/docread.js +348 -96
- package/dist/mcp/pyargs.d.ts +19 -0
- package/dist/mcp/pyargs.js +12 -1
- package/dist/mcp/server.js +128 -34
- package/dist/memory/cli.js +43 -1
- package/dist/memory/factfile.d.ts +13 -1
- package/dist/memory/factfile.js +7 -17
- package/dist/memory/pyfs.d.ts +20 -12
- package/dist/memory/pyfs.js +21 -51
- package/dist/memory/store.d.ts +43 -0
- package/dist/memory/store.js +61 -3
- package/dist/pysem.d.ts +81 -0
- package/dist/pysem.js +126 -0
- package/dist/skillaudit.js +31 -38
- package/package.json +1 -1
package/dist/docread.d.ts
CHANGED
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
* (`utf8Scan`).
|
|
35
35
|
*/
|
|
36
36
|
import { BantamError } from './errors.js';
|
|
37
|
+
import { cmpCodepoint, pyRepr, pyStrip } from './pysem.js';
|
|
37
38
|
export declare const NS_S = "{http://schemas.openxmlformats.org/spreadsheetml/2006/main}";
|
|
38
39
|
export declare const NS_W = "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}";
|
|
39
40
|
export declare const NS_R = "{http://schemas.openxmlformats.org/officeDocument/2006/relationships}";
|
|
@@ -52,19 +53,15 @@ export declare const OMIT_UNMAPPED = "unmapped-text";
|
|
|
52
53
|
export declare const OMIT_UNREAD_TAIL = "unread-tail";
|
|
53
54
|
export declare const OMIT_SIZE_CAP = "size-cap";
|
|
54
55
|
export declare const OMIT_UNPLACED_CELL = "unplaced-cell";
|
|
56
|
+
export declare const OMIT_DUPLICATE_CELL = "duplicate-cell";
|
|
55
57
|
/** Extraction failed. The message names what was seen, never just the format's own error. */
|
|
56
58
|
export declare class DocumentReadError extends BantamError {
|
|
57
59
|
}
|
|
58
|
-
|
|
59
|
-
export declare function pyStrip(s: string): string;
|
|
60
|
+
export { cmpCodepoint, pyRepr, pyStrip };
|
|
60
61
|
/** `str.split()` with no argument: runs of whitespace, no empty fields. */
|
|
61
62
|
export declare function pySplit(s: string): string[];
|
|
62
63
|
/** `str.splitlines()`: Python's line boundaries, terminators dropped. */
|
|
63
64
|
export declare function pySplitlines(s: string): string[];
|
|
64
|
-
/** `sorted()` on strings: by code point, which is not what `Array.sort` does above U+FFFF. */
|
|
65
|
-
export declare function cmpCodepoint(a: string, b: string): number;
|
|
66
|
-
/** `repr(str)`. */
|
|
67
|
-
export declare function pyRepr(s: string): string;
|
|
68
65
|
/** `repr(bytes)`. */
|
|
69
66
|
export declare function bytesRepr(buf: Uint8Array): string;
|
|
70
67
|
export interface Utf8Scan {
|
|
@@ -190,6 +187,35 @@ export declare class BadZipFile extends Error {
|
|
|
190
187
|
constructor(message: string);
|
|
191
188
|
}
|
|
192
189
|
export declare function crc32(buf: Uint8Array): number;
|
|
190
|
+
/**
|
|
191
|
+
* How much ONE MEMBER of a zip this reader will decompress and parse. The ceiling on the
|
|
192
|
+
* PARSE, which is a different door from `XLSX_MAX_TEXT_BYTES`: that one bounds the text a
|
|
193
|
+
* workbook renders, and it never stands in front of this, because `readMember` decompresses
|
|
194
|
+
* the member whole and `parsePart` builds a tree from it before the first row is rendered.
|
|
195
|
+
*
|
|
196
|
+
* MEASURED 2026-09-06 on this machine, through `docread.extract` on THIS runtime at the
|
|
197
|
+
* shipped constants, on a sheet of N `<row><c t="inlineStr"><is><t>x</t></is></c></row>`
|
|
198
|
+
* deflated by `deflateRawSync`, peak RSS from `process.resourceUsage().maxRSS`:
|
|
199
|
+
* 400,000 rows are 58,378 bytes on disk, declare 19,600,112, and took RSS from 102.2 MB to
|
|
200
|
+
* 1,039.3 MB in 1,019 ms with NO omission; 1,000,000 rows are 143,939 bytes, declare
|
|
201
|
+
* 49,000,112, and took it from 158.6 MB to 2,290.8 MB in 2,667 ms. Linear and unbounded —
|
|
202
|
+
* the memory is the `XmlElement` tree, not the text, so a budget over the rendering could
|
|
203
|
+
* not see it. The reference measured the same shape at 342.2 MB and 838.8 MB through
|
|
204
|
+
* `tracemalloc`; the numbers are not comparable (one counts a Python allocator, the other a
|
|
205
|
+
* whole process) and the SHAPE is what both of them state.
|
|
206
|
+
*
|
|
207
|
+
* 16 MiB, the number `TEXT_MAX_BYTES` states, because "how much of a file this reader reads"
|
|
208
|
+
* is one number — but under its OWN NAME, because it bounds a member of a container and not a
|
|
209
|
+
* file on a disk, and a bar that varies one must not be varying the other. The reference
|
|
210
|
+
* measured the corpus behind the figure: 25 OOXML/ODF packages under the goal's roots, the
|
|
211
|
+
* largest single XML member among them 4,283,286 bytes, 3.9x under this.
|
|
212
|
+
*
|
|
213
|
+
* A REFUSAL and not a truncation, which is the one place this module departs from
|
|
214
|
+
* "disclose, never truncate": half an XML document is not a smaller XML document, and a tree
|
|
215
|
+
* built from a severed member would carry text that is not what the file says. So the reader
|
|
216
|
+
* stops and names the member, the number the file declares and its own ceiling.
|
|
217
|
+
*/
|
|
218
|
+
export declare const ZIP_MEMBER_MAX_BYTES: number;
|
|
193
219
|
/** `zipfile.ZipFile` read-only: the central directory, and `read(name)` with a CRC check. */
|
|
194
220
|
export declare class ZipReader {
|
|
195
221
|
private readonly data;
|
|
@@ -209,6 +235,8 @@ export declare class ZipReader {
|
|
|
209
235
|
isDir: boolean;
|
|
210
236
|
}[];
|
|
211
237
|
has(name: string): boolean;
|
|
238
|
+
/** `getinfo(name).file_size`: what the central directory DECLARES, before any inflate. */
|
|
239
|
+
declaredSize(name: string): number;
|
|
212
240
|
/** `ZipFile.read(name)`; a missing member is a `KeyError` — here `RangeError`, see `readMember`. */
|
|
213
241
|
read(name: string): Buffer;
|
|
214
242
|
}
|
|
@@ -293,6 +321,32 @@ export declare const XLSX_MAX_COLUMNS = 16384;
|
|
|
293
321
|
*/
|
|
294
322
|
export declare const UNPLACED_SHAPE = "the column of a cell whose reference is not letters then digits";
|
|
295
323
|
export declare const UNPLACED_RANGE = "the column of a cell past XFD, the last column the format has";
|
|
324
|
+
export declare const DUPLICATE_CELL = "the text of a cell a later cell in the same row and column replaced";
|
|
325
|
+
/**
|
|
326
|
+
* How much text ONE WORKBOOK may materialise, all sheets together. `XLSX_MAX_COLUMNS` bounds a
|
|
327
|
+
* ROW and nothing bounded the document, which is a ceiling with a hole in it: the width is
|
|
328
|
+
* bought a row at a time. MEASURED 2026-09-06 on both runtimes: 20,000 rows each holding one
|
|
329
|
+
* `XFD1` cell deflate to 53,967 bytes and materialise 327,680,000 bytes in ~9 s — 6,072x, out
|
|
330
|
+
* of a file small enough to mail.
|
|
331
|
+
*
|
|
332
|
+
* 16 MiB, the same figure `TEXT_MAX_BYTES` carries and for the same kind of reason, but under
|
|
333
|
+
* its OWN NAME because the two bound different things: bytes read off a disk there, bytes
|
|
334
|
+
* rendered out of a container here, and a bar that varies one must not be varying the other.
|
|
335
|
+
* MEASURED 2026-09-06 over the goal's roots: 15 `.xlsx`, the largest 8,664,227 bytes on disk,
|
|
336
|
+
* and the largest RENDERING among them 754,520 bytes — 22x under this budget, so no real
|
|
337
|
+
* workbook on this machine meets it.
|
|
338
|
+
*
|
|
339
|
+
* It bounds the RENDERING and nothing else. The sentence that stood here said it bounded the
|
|
340
|
+
* rendering "because the file is already bounded", and that was FALSE for the whole life of
|
|
341
|
+
* this constant: `readMember` decompressed a member whole and `parsePart` built a tree from
|
|
342
|
+
* it, both before the first row was rendered and both outside this budget, so 58,378 bytes on
|
|
343
|
+
* disk took RSS to 1,039.3 MB with no omission and this ceiling never saw it (review round 5,
|
|
344
|
+
* H1). What bounds the file is `ZIP_MEMBER_MAX_BYTES`, one door earlier; this bounds what
|
|
345
|
+
* comes out of it. The shortfall is disclosed as `OMIT_SIZE_CAP` counting the rows no sheet
|
|
346
|
+
* rendered: a row is what a caller addresses, and a byte count of text that was never built
|
|
347
|
+
* would be a number this reader cannot honestly produce.
|
|
348
|
+
*/
|
|
349
|
+
export declare const XLSX_MAX_TEXT_BYTES: number;
|
|
296
350
|
/**
|
|
297
351
|
* `B7` -> `[1, '']`. The cell's own reference decides its column; XML order is a fallback.
|
|
298
352
|
*
|
|
@@ -320,8 +374,22 @@ export declare const UNPLACED_RANGE = "the column of a cell past XFD, the last c
|
|
|
320
374
|
* spends asking for more.
|
|
321
375
|
*/
|
|
322
376
|
export declare function columnIndex(ref: string | undefined, fallback: number): [number, string];
|
|
323
|
-
|
|
324
|
-
|
|
377
|
+
/**
|
|
378
|
+
* Every declared sheet, under ONE `XLSX_MAX_TEXT_BYTES` budget for the whole workbook.
|
|
379
|
+
*
|
|
380
|
+
* The budget is the document's, so it is made here and not in `sheetRows`, and the shortfall
|
|
381
|
+
* is disclosed at the document's grain for the same reason — it is not a fact about the sheet
|
|
382
|
+
* the budget happened to run out on. The cap is stated BEFORE the media tally, because the
|
|
383
|
+
* media a reader met is a count of what it met underneath the cap.
|
|
384
|
+
*
|
|
385
|
+
* `opened` is the reader `sniff` already had to build to decide this file is an OOXML package
|
|
386
|
+
* (entries (a)/(j)): before it was handed down, one `extract` read the whole archive off disk
|
|
387
|
+
* TWICE. It is a parameter and never a field, so its lifetime is this call — a reader kept
|
|
388
|
+
* across calls would answer from bytes no longer on disk, which is exactly what the document
|
|
389
|
+
* cache one layer up is keyed on (realpath, size, mtime_ns) to avoid.
|
|
390
|
+
*/
|
|
391
|
+
export declare function extractXlsx(path: string, opened?: ZipReader | null): Document;
|
|
392
|
+
export declare function extractDocx(path: string, opened?: ZipReader | null): Document;
|
|
325
393
|
/** `html.unescape`. */
|
|
326
394
|
export declare function unescape(s: string): string;
|
|
327
395
|
/** Rendered rows of one HTML fragment. A pure function of the string: no I/O, no host. */
|
|
@@ -349,6 +417,12 @@ export declare function a2bUu(line: Uint8Array): Buffer;
|
|
|
349
417
|
*/
|
|
350
418
|
export declare function decodeUu(encoded: Buffer): Buffer;
|
|
351
419
|
export declare function extractMhtml(path: string): Document;
|
|
420
|
+
/**
|
|
421
|
+
* Markup to rows, up to `TEXT_MAX_BYTES` of it, saying how much it did not read.
|
|
422
|
+
*
|
|
423
|
+
* BOUNDED, entry (k): this did `readFileSync(path)`, so a 1 GB `.html` was materialised whole
|
|
424
|
+
* where a 1 GB `.txt` had stopped at the cap and counted the rest since J10.
|
|
425
|
+
*/
|
|
352
426
|
export declare function extractHtml(path: string): Document;
|
|
353
427
|
export declare function extractText(path: string): Document;
|
|
354
428
|
/** Dispatch on what the file IS. Anything unreadable raises, naming the container. */
|