agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
72 lines • 3.31 kB
TypeScript
/**
* zipStore — a real `.zip` file, STORED (no compression), in ~150 lines and
* zero dependencies.
*
* ## Why store-only is the honest choice here
*
* This writer exists for ONE payload: a bug-report bundle, which is JSON and
* text. Deflate would shrink it well — and would cost this library either a
* dependency (a zlib binding in a package that has none) or `node:zlib` (which
* makes the export Node-only, when building the bundle in a browser is exactly
* the flow the consent manifest is for). Store-only keeps the export
* environment-neutral and the writer small enough to read in one sitting.
*
* The trade is stated rather than hidden: **a stored bundle is roughly the sum
* of its files.** A 9 MB recording produces a ~9 MB zip. Every unzip tool reads
* it — `unzip`, Finder, Explorer, `zipfile.ZipFile`, `jar` — because method 0
* is the oldest thing in the format. If a bundle is too big to attach, the
* answer is to send fewer conversations (which the manifest's trim hints name),
* not to compress harder; that is the same answer a deflated bundle would give
* one doubling later.
*
* ## What it writes, exactly
*
* One local file header + data per entry, then one central-directory header per
* entry, then the end-of-central-directory record — the classic three-part
* layout from APPNOTE.TXT, no data descriptors, no zip64, no archive comment.
* Names are UTF-8 with the language-encoding flag (bit 11) set, so a non-ASCII
* name is not mojibake on a reader that honours the flag.
*
* ## What it refuses
*
* A path that would escape the extraction directory (`/leading`, `..`, a drive
* letter, a backslash) is refused BY NAME rather than written — a bug-report
* bundle is opened by a maintainer on their own machine, and "zip slip" is the
* one way a report could hurt the person reading it. Duplicate names, empty
* names, an entry over 4 GB and more than 65,535 entries are refused too: those
* are the boundaries of the non-zip64 format, and writing past them silently
* produces a file that fails to open.
*
* @example
* ```ts
* const bytes = zipStore([
* { name: 'manifest.json', data: new TextEncoder().encode('{}') },
* ]);
* ```
*
* @internal Not a public export. `exportBugReport` is the door.
*/
/** One file in the archive. Directories are implied by `/` in a name. */
export interface ZipEntry {
/** Path inside the archive, `/`-separated and relative (`docs/a.json`). */
readonly name: string;
/** The bytes. Text is the caller's `TextEncoder` output. */
readonly data: Uint8Array;
}
export interface ZipStoreOptions {
/**
* Timestamp stamped on every entry. Default: now. Passing one makes the
* output byte-for-byte deterministic, which is what makes a zip testable.
* DOS timestamps start in 1980; anything earlier is clamped to it.
*/
readonly modified?: Date;
}
/**
* Build a stored (uncompressed) zip archive.
*
* @throws TypeError naming the offending entry when a name is unsafe or
* duplicated, or when the archive would exceed the non-zip64 limits.
*/
export declare function zipStore(entries: readonly ZipEntry[], options?: ZipStoreOptions): Uint8Array;
export declare function crc32(bytes: Uint8Array): number;
//# sourceMappingURL=zip.d.ts.map