@xamukavila/pxpipe 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +312 -0
- package/bin/cli.js +7 -0
- package/dist/core/applicability.d.ts +31 -0
- package/dist/core/applicability.js +96 -0
- package/dist/core/atlas-gray.d.ts +26 -0
- package/dist/core/atlas-gray.js +64 -0
- package/dist/core/atlas.d.ts +34 -0
- package/dist/core/atlas.js +71 -0
- package/dist/core/baseline.d.ts +80 -0
- package/dist/core/baseline.js +101 -0
- package/dist/core/caveman.d.ts +38 -0
- package/dist/core/caveman.js +183 -0
- package/dist/core/export.d.ts +128 -0
- package/dist/core/export.js +390 -0
- package/dist/core/factsheet.d.ts +78 -0
- package/dist/core/factsheet.js +216 -0
- package/dist/core/gpt-model-profiles.d.ts +60 -0
- package/dist/core/gpt-model-profiles.js +161 -0
- package/dist/core/history.d.ts +141 -0
- package/dist/core/history.js +553 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.js +8 -0
- package/dist/core/library.d.ts +74 -0
- package/dist/core/library.js +133 -0
- package/dist/core/measurement.d.ts +22 -0
- package/dist/core/measurement.js +213 -0
- package/dist/core/openai-history.d.ts +124 -0
- package/dist/core/openai-history.js +494 -0
- package/dist/core/openai-savings.d.ts +44 -0
- package/dist/core/openai-savings.js +75 -0
- package/dist/core/openai.d.ts +24 -0
- package/dist/core/openai.js +839 -0
- package/dist/core/png.d.ts +11 -0
- package/dist/core/png.js +132 -0
- package/dist/core/proxy.d.ts +81 -0
- package/dist/core/proxy.js +730 -0
- package/dist/core/render.d.ts +188 -0
- package/dist/core/render.js +785 -0
- package/dist/core/schema-strip.d.ts +29 -0
- package/dist/core/schema-strip.js +160 -0
- package/dist/core/tracker.d.ts +154 -0
- package/dist/core/tracker.js +216 -0
- package/dist/core/transform.d.ts +362 -0
- package/dist/core/transform.js +1828 -0
- package/dist/core/types.d.ts +77 -0
- package/dist/core/types.js +8 -0
- package/dist/dashboard/fragments.d.ts +36 -0
- package/dist/dashboard/fragments.js +938 -0
- package/dist/dashboard/types.d.ts +154 -0
- package/dist/dashboard/types.js +3 -0
- package/dist/dashboard/vendor.d.ts +3 -0
- package/dist/dashboard/vendor.js +6 -0
- package/dist/dashboard.d.ts +245 -0
- package/dist/dashboard.js +1140 -0
- package/dist/export-collect.d.ts +36 -0
- package/dist/export-collect.js +59 -0
- package/dist/node.d.ts +9 -0
- package/dist/node.js +9038 -0
- package/dist/sessions.d.ts +172 -0
- package/dist/sessions.js +510 -0
- package/dist/stats.d.ts +74 -0
- package/dist/stats.js +248 -0
- package/dist/worker.d.ts +53 -0
- package/dist/worker.js +102 -0
- package/package.json +96 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text → PNG renderer. Blits atlas glyphs into a grayscale framebuffer, then PNG-encodes.
|
|
3
|
+
* Iterates by codepoint so East Asian Wide chars (2-cell advance) and surrogate pairs handled correctly.
|
|
4
|
+
* Pages capped at ~1932×1932 px: Fable/Opus 4.8 >20-image requests are held to ≤2000 px/side
|
|
5
|
+
* (REJECTED if exceeded, not silently downscaled); ≤4784 token limit binds first at 1932 px.
|
|
6
|
+
*/
|
|
7
|
+
/** Page-height ceiling. Measured (2026-07-01, count_tokens sweep, claude-sonnet-4-5 — see
|
|
8
|
+
* /tmp/pxexp/LEVER1-findings.md): the API downscales any image to fit BOTH long-edge ≤1568
|
|
9
|
+
* AND ~1.15 MP (≈1,143,750 px), then bills ≈ px/750 (≈1525 tok cap, applied per-image).
|
|
10
|
+
* The old 1932×1932 page was billed at cap but resampled 0.555× → 5×8 glyphs reached the
|
|
11
|
+
* encoder at ~2.8×4.4 px. New page shape 1568×728 = 1,141,504 px fits both bounds →
|
|
12
|
+
* WYSIWYG for the vision encoder (also satisfies ≤2000 px/side for >20-image requests). */
|
|
13
|
+
export declare const MAX_HEIGHT_PX = 728;
|
|
14
|
+
/** Char budget for the static slab (system + tools + CLAUDE.md). Matches physical page
|
|
15
|
+
* capacity at 312 cols × 90 rows so image-count estimates track real pagination. */
|
|
16
|
+
export declare const READABLE_CHARS_PER_IMAGE = 28080;
|
|
17
|
+
/** Char budget for dense content (tool output, collapsed history). 312 cols × 90 rows = 28080
|
|
18
|
+
* chars fills the 1568×728 page. NOTE: verbatim recall of imaged text is unreliable at any size. */
|
|
19
|
+
export declare const DENSE_CONTENT_CHARS_PER_IMAGE = 28080;
|
|
20
|
+
export declare const DENSE_CONTENT_COLS = 312;
|
|
21
|
+
/** Bare 5×8 cell (no padding). A/B showed 5×8 beats 7×10 on dense JSON (4/5 vs 3/5 reads, 42% fewer tokens).
|
|
22
|
+
* Revert to {cellWBonus:2, cellHBonus:2} if misread rates rise. */
|
|
23
|
+
export declare const DENSE_RENDER_STYLE: RenderStyle;
|
|
24
|
+
/** Horizontal padding (left + right each), px. Exported for transform.ts token-cost math. */
|
|
25
|
+
export declare const PAD_X = 4;
|
|
26
|
+
/** Vertical padding (top + bottom each), px. Exported for transform.ts token-cost math. */
|
|
27
|
+
export declare const PAD_Y = 4;
|
|
28
|
+
/** Production ships bare 5×8 atlas cell (reflow+grayscale+inimage instruction band
|
|
29
|
+
* brought 5×8 to 98.95% OCR accuracy on Opus 4.7, matching or beating padded cells).
|
|
30
|
+
* RenderStyle.cellWBonus/cellHBonus override per-eval only. */
|
|
31
|
+
export declare const DEFAULT_CELL_W_BONUS = 0;
|
|
32
|
+
export declare const DEFAULT_CELL_H_BONUS = 0;
|
|
33
|
+
/** Effective cell pixel dimensions. transform.ts derives image-budget math from these. */
|
|
34
|
+
export declare const CELL_W: number;
|
|
35
|
+
export declare const CELL_H: number;
|
|
36
|
+
export interface RenderedImage {
|
|
37
|
+
png: Uint8Array;
|
|
38
|
+
width: number;
|
|
39
|
+
height: number;
|
|
40
|
+
/** Input codepoints rendered (wide chars count as 1, not 2). */
|
|
41
|
+
charsRendered: number;
|
|
42
|
+
/** Codepoints absent from atlas, rendered as blank cells. Surface as telemetry. */
|
|
43
|
+
droppedChars: number;
|
|
44
|
+
/** Per-codepoint drop histogram. Empty when droppedChars === 0; never undefined. */
|
|
45
|
+
droppedCodepoints: Map<number, number>;
|
|
46
|
+
}
|
|
47
|
+
/** Optional render-time styling. All fields unset = production default 5×8 cell.
|
|
48
|
+
* Eval harness overrides per variant to A/B cell sizes and structure aids. */
|
|
49
|
+
export interface RenderStyle {
|
|
50
|
+
/** Draw faint grey grid rules onto background pixels (zero pixel cost). */
|
|
51
|
+
grid?: boolean;
|
|
52
|
+
/** Draw a vertical grid rule every N columns. 0/unset = row rules only. */
|
|
53
|
+
gridCols?: number;
|
|
54
|
+
/** Horizontal size multiplier for the ↵ newline marker. 1 = off. */
|
|
55
|
+
markerScale?: number;
|
|
56
|
+
/** Render the ↵ marker in red (switches PNG to RGB truecolor). */
|
|
57
|
+
markerRed?: boolean;
|
|
58
|
+
/** Extra blank rows above the 8px glyph (cell height = 8 + this). Unset = DEFAULT_CELL_H_BONUS. */
|
|
59
|
+
cellHBonus?: number;
|
|
60
|
+
/** Extra blank columns beside the 5px glyph (cell width = 5 + this). Negative overlaps glyphs. Unset = DEFAULT_CELL_W_BONUS. */
|
|
61
|
+
cellWBonus?: number;
|
|
62
|
+
/** Use the AA grayscale atlas (atlas-gray.ts). EVAL-ONLY; default 1-bit path is unchanged. */
|
|
63
|
+
aa?: boolean;
|
|
64
|
+
/** Cycle palette colors per glyph for per-character boundary cues. Forces RGB output. Composes with aa. */
|
|
65
|
+
colorCycle?: boolean;
|
|
66
|
+
/** Tint only the structural <user>/<assistant> boundary tags (body stays black)
|
|
67
|
+
* so speakers are scannable without recoloring content. Forces RGB. Composes with aa. */
|
|
68
|
+
colorByRole?: boolean;
|
|
69
|
+
}
|
|
70
|
+
/** Strip trailing whitespace per line and collapse 4+ consecutive \n to 3.
|
|
71
|
+
* Does NOT touch mid-line spaces or leading indent — structure is preserved. */
|
|
72
|
+
export declare function minifyForRender(text: string): string;
|
|
73
|
+
/** U+21B5 ↵ sentinel for original hard newlines in reflowed text. In full-bmp atlas via Unifont. */
|
|
74
|
+
export declare const NL_SENTINEL = "\u21B5";
|
|
75
|
+
/** Look-alike (U+23CE ⏎) for a ↵ that was ALREADY in the source content — distinct from
|
|
76
|
+
* the U+21B5 ↵ we insert for newlines. reflow() bails when its input already contains the
|
|
77
|
+
* sentinel; that's vanishingly rare for normal content but common when the content is about
|
|
78
|
+
* pxpipe itself (rendered dumps, OCR, this very transcript). {@link neutralizeSentinel}
|
|
79
|
+
* swaps pre-existing sentinels for this glyph in RENDER-PREP only, so reflow can pack
|
|
80
|
+
* newlines instead of bailing to a raw, unpacked render. Originals are preserved verbatim
|
|
81
|
+
* elsewhere (recordRecoverable / cache-stable history), and reflow()'s own round-trip
|
|
82
|
+
* contract — and its tests — are left untouched. */
|
|
83
|
+
export declare const NL_SENTINEL_LITERAL = "\u23CE";
|
|
84
|
+
export declare function neutralizeSentinel(text: string): string;
|
|
85
|
+
/** colorByRole palette, indexed by slot-1. Only the boundary TAGS are tinted;
|
|
86
|
+
* body content stays black. [<user> tags, <assistant> tags]. */
|
|
87
|
+
export declare const ROLE_PALETTE: [number, number, number][];
|
|
88
|
+
/**
|
|
89
|
+
* Slot markers for the parallel "slot string" — the structure-through mechanism
|
|
90
|
+
* that replaces the old parse-back. A slot string is a width-preserving copy of
|
|
91
|
+
* the rendered text: every structural role-tag character is swapped for one of
|
|
92
|
+
* these control codes, and every other codepoint is copied verbatim. Because the
|
|
93
|
+
* markers are width-1 (exactly like the ASCII tag chars they stand in for), the
|
|
94
|
+
* existing reflow / wrapLines / paging transforms mutate the slot string in lock-
|
|
95
|
+
* step with the text — only whitespace/newlines move, and those are slot 0 in
|
|
96
|
+
* both. The renderer then reads role attribution BY POSITION instead of trying to
|
|
97
|
+
* re-find "<user>" in flattened text (which miscolors a body that literally quotes
|
|
98
|
+
* a tag). The structure is known at serialize time and carried, never guessed.
|
|
99
|
+
*/
|
|
100
|
+
export declare const SLOT_MARK_USER: string;
|
|
101
|
+
export declare const SLOT_MARK_ASSISTANT: string;
|
|
102
|
+
/** Width-preserving slot-0 copy of body text: identical codepoints (so wrap math is
|
|
103
|
+
* unchanged) but with any literal slot-marker control char neutralized. These are rare in
|
|
104
|
+
* real content but DO occur (e.g. binary-ish tool output that gets collapsed into history),
|
|
105
|
+
* so the replacement is width- and strip-equivalent to the marker — never a space, which
|
|
106
|
+
* the minifier would strip and misalign. Guarantees body can't forge a role hue. */
|
|
107
|
+
export declare function slotCopyBody(body: string): string;
|
|
108
|
+
/** Build the slot-string segment for one role-wrapped turn, mirroring the text
|
|
109
|
+
* form `<${tag}>\n${body}\n</${tag}>`: marker chars over the open/close tags,
|
|
110
|
+
* a verbatim slot-0 copy of the body. `mark` is the role's slot marker. */
|
|
111
|
+
export declare function roleSlotSegment(tag: string, body: string, mark: string, attr?: string): string;
|
|
112
|
+
/** Minify + tab-expand + join lines with ↵ sentinel. Returns null if text already
|
|
113
|
+
* contains ↵ (caller falls back to non-reflow path; vanishingly rare in practice). */
|
|
114
|
+
export declare function reflow(text: string): string | null;
|
|
115
|
+
/** Inverse of reflow: ↵ → '\n'. dereflow(reflow(text)) === minifyForRender(text) with tabs expanded. */
|
|
116
|
+
export declare function dereflow(reflowed: string): string;
|
|
117
|
+
/** Expand \t to U+2192 → + padding to the next TAB_WIDTH stop. Visible marker lets the
|
|
118
|
+
* model distinguish indent-spaces from intentional-spaces. Wide CJK chars count as 2 cols.
|
|
119
|
+
* U+0009 is absent from the atlas (control codepoint), so without this every tab was a drop. */
|
|
120
|
+
export declare function expandTabsInLine(line: string): string;
|
|
121
|
+
/** Visual width of a line in cells. Wide CJK = 2; enlarged ↵ = markerScale. */
|
|
122
|
+
export declare function measureLineCols(line: string, markerScale?: number): number;
|
|
123
|
+
/** Always renders at full canvas width. Signature kept for transform.ts compatibility; returns cols unchanged. */
|
|
124
|
+
export declare function shrinkColsToContent(text: string, cols: number, markerScale?: number): number;
|
|
125
|
+
/**
|
|
126
|
+
* Real content-width measurement (the capability `shrinkColsToContent` historically
|
|
127
|
+
* stubbed out): the display width, in cols, of the widest line in `text`, capped at
|
|
128
|
+
* `maxCols`. Lets a renderer size a narrow canvas to short-line content (e.g. code)
|
|
129
|
+
* instead of padding every page to full width. Pure function of (text, maxCols) →
|
|
130
|
+
* deterministic width → cache-prefix-safe. Tabs are expanded so the measured width
|
|
131
|
+
* matches what the renderer actually lays out.
|
|
132
|
+
*/
|
|
133
|
+
export declare function measureContentCols(text: string, maxCols: number, markerScale?: number): number;
|
|
134
|
+
export declare function wrapLines(text: string, cols: number, markerScale?: number): string[];
|
|
135
|
+
/** Render text to a single PNG (≤ MAX_HEIGHT_PX tall). Wide glyphs occupy 2 consecutive cells. */
|
|
136
|
+
export declare function renderChunkToPng(text: string, cols?: number, style?: RenderStyle, maxHeightPx?: number, slotText?: string): Promise<RenderedImage>;
|
|
137
|
+
/** Reflow-aware variant of renderTextToPngs. Falls back to non-reflow on sentinel collision. */
|
|
138
|
+
export declare function renderTextToPngsReflow(text: string, cols?: number, style?: RenderStyle): Promise<RenderedImage[]>;
|
|
139
|
+
/** Split text into N PNGs each ≤ MAX_HEIGHT_PX tall, respecting per-image char budget. */
|
|
140
|
+
export declare function renderTextToPngsWithCharLimit(text: string, cols?: number, maxCharsPerImage?: number, style?: RenderStyle, maxHeightPx?: number, slotText?: string): Promise<RenderedImage[]>;
|
|
141
|
+
export declare function renderTextToPngs(text: string, cols?: number, style?: RenderStyle, maxHeightPx?: number, slotText?: string): Promise<RenderedImage[]>;
|
|
142
|
+
/** Pixel width of a multi-col canvas. */
|
|
143
|
+
export declare function multiColWidth(cols: number, numCols: number): number;
|
|
144
|
+
/** Largest numCols fitting within MAX_WIDTH_PX. Used to clamp over-large CLI flags. */
|
|
145
|
+
export declare function maxFittingCols(cols: number): number;
|
|
146
|
+
/** Split text into N multi-column PNGs. numCols <= 1 delegates to renderTextToPngs
|
|
147
|
+
* for byte-identical output (determinism/cache_control preserved when flag is off). */
|
|
148
|
+
export declare function renderTextToPngsMultiCol(text: string, cols?: number, numCols?: number): Promise<RenderedImage[]>;
|
|
149
|
+
/** Reflow-aware variant of renderTextToPngsMultiCol. Falls back to non-reflow on sentinel collision. */
|
|
150
|
+
export declare function renderTextToPngsReflowMultiCol(text: string, cols?: number, numCols?: number): Promise<RenderedImage[]>;
|
|
151
|
+
export interface RenderDensePagesOptions {
|
|
152
|
+
/** Wrap-width cap in cols. Default DENSE_CONTENT_COLS (384). */
|
|
153
|
+
readonly cols?: number;
|
|
154
|
+
/** Shrink the canvas to the widest actual line (default true). `false` keeps the full
|
|
155
|
+
* `cols` width — the proxy's eval-backed full-canvas / slab behavior. */
|
|
156
|
+
readonly shrink?: boolean;
|
|
157
|
+
/** Columns to pack side-by-side. `'auto'` (default) packs as many as fit the width cap;
|
|
158
|
+
* a number forces that count. Collapses to 1 when the canvas shrinks below the cap. */
|
|
159
|
+
readonly multiCol?: number | 'auto';
|
|
160
|
+
/** Reflow (minify + join hard newlines with ↵) before rendering. Default false. Callers
|
|
161
|
+
* that pre-reflow (the proxy's maybeReflow / history lockstep) pass false; `pxpipe export`
|
|
162
|
+
* passes true so short lines pack into full-width rows. */
|
|
163
|
+
readonly reflow?: boolean;
|
|
164
|
+
/** Max source chars per page. Default DENSE_CONTENT_CHARS_PER_IMAGE. */
|
|
165
|
+
readonly maxCharsPerImage?: number;
|
|
166
|
+
/** Render style. Default DENSE_RENDER_STYLE. */
|
|
167
|
+
readonly style?: RenderStyle;
|
|
168
|
+
/** Max page height in px. Default MAX_HEIGHT_PX. */
|
|
169
|
+
readonly maxHeightPx?: number;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* The single dense-page rendering decision shared by the public SDK primitive
|
|
173
|
+
* `renderTextToImages` (library.ts → `pxpipe export`) AND the proxy's `textToImageBlocks`
|
|
174
|
+
* (transform.ts): optionally reflow, measure the content width, pack as many side-by-side
|
|
175
|
+
* columns as actually fit the width cap (or honor an explicit count, collapsing the wasted
|
|
176
|
+
* divider column when the canvas shrinks), then render. Both callers route through HERE so
|
|
177
|
+
* export PNGs and proxy image blocks are produced by the exact same code and cannot drift —
|
|
178
|
+
* `shrinkColsToContent` is `measureContentCols`, so the proxy's old inline path was already
|
|
179
|
+
* identical at the default 384 cols; this makes it identical at every cols. Returns the raw
|
|
180
|
+
* rendered pages; each caller packages them (PNG files vs. base64 Anthropic ImageBlocks).
|
|
181
|
+
*
|
|
182
|
+
* History (history.ts) deliberately does NOT use this: it reflows a parallel role-slot string
|
|
183
|
+
* in lockstep with the text and renders with `colorByRole`, which code export has no concept
|
|
184
|
+
* of — wiring slots through this public surface would bloat it for one internal caller. It
|
|
185
|
+
* still shares the underlying `reflow()` + `renderTextToPngsWithCharLimit` primitives.
|
|
186
|
+
*/
|
|
187
|
+
export declare function renderDensePages(text: string, opts?: RenderDensePagesOptions): Promise<RenderedImage[]>;
|
|
188
|
+
//# sourceMappingURL=render.d.ts.map
|