token-goat 2.9.28 → 2.9.30
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 +36 -40
- package/SECURITY.md +28 -10
- package/THIRD_PARTY_NOTICES.md +40 -3
- package/dist/native/linux-arm64/tg-hook +0 -0
- package/dist/native/linux-x64/tg-hook +0 -0
- package/dist/ort-wasm-simd-threaded.mjs +59 -0
- package/dist/token-goat-chunk-3CHUNJ2O.mjs +53 -0
- package/dist/token-goat-chunk-3Z5S4KGM.mjs +918 -0
- package/dist/token-goat-chunk-4FVIAHSI.mjs +211 -0
- package/dist/{token-goat-chunk-66LODAUT.mjs → token-goat-chunk-4JJS54TR.mjs} +4 -3
- package/dist/token-goat-chunk-4LCCNRTG.mjs +313 -0
- package/dist/token-goat-chunk-54K3EUV3.mjs +35 -0
- package/dist/token-goat-chunk-56EIMS3E.mjs +159 -0
- package/dist/token-goat-chunk-5BCIJXMO.mjs +609 -0
- package/dist/token-goat-chunk-5KDMCMF2.mjs +362 -0
- package/dist/token-goat-chunk-5RG5SBL6.mjs +221 -0
- package/dist/{token-goat-chunk-RRNZMM3A.mjs → token-goat-chunk-5Y6ZYL6U.mjs} +21 -2
- package/dist/{token-goat-chunk-NILVK7XM.mjs → token-goat-chunk-64FBPDTK.mjs} +12 -6
- package/dist/{token-goat-chunk-LEG3JNJ6.mjs → token-goat-chunk-664RTTUV.mjs} +31 -15
- package/dist/token-goat-chunk-67TQJ76B.mjs +57 -0
- package/dist/token-goat-chunk-6QMAS7AB.mjs +42 -0
- package/dist/token-goat-chunk-7BXSNBY5.mjs +253 -0
- package/dist/{token-goat-chunk-F7QZRIWM.mjs → token-goat-chunk-7F2UBPD3.mjs} +42 -35
- package/dist/{token-goat-chunk-CC2PYJM7.mjs → token-goat-chunk-7IN2MKDS.mjs} +718 -595
- package/dist/token-goat-chunk-7NADEDKJ.mjs +124 -0
- package/dist/{token-goat-chunk-6SGLIPQB.mjs → token-goat-chunk-A3CK6N5Z.mjs} +621 -72
- package/dist/{token-goat-chunk-HXNAC4ZF.mjs → token-goat-chunk-AFLYLHDH.mjs} +48 -33
- package/dist/token-goat-chunk-AM5V6GSX.mjs +367 -0
- package/dist/{token-goat-chunk-I7CB3X4K.mjs → token-goat-chunk-APGZXSPS.mjs} +44 -148
- package/dist/{token-goat-chunk-BJBRGPBX.mjs → token-goat-chunk-ARDNEC2U.mjs} +11 -7
- package/dist/token-goat-chunk-ATCPY7EQ.mjs +134 -0
- package/dist/token-goat-chunk-B2RZZCSS.mjs +354 -0
- package/dist/{token-goat-chunk-QM76S6YS.mjs → token-goat-chunk-B45VMIIH.mjs} +6 -5
- package/dist/token-goat-chunk-BPGCUMR7.mjs +30 -0
- package/dist/{token-goat-chunk-GGLEE35R.mjs → token-goat-chunk-C63JQV5K.mjs} +49 -10
- package/dist/{token-goat-chunk-RJH64KQH.mjs → token-goat-chunk-COBQGL5S.mjs} +2661 -2440
- package/dist/token-goat-chunk-COTXZHTS.mjs +39 -0
- package/dist/token-goat-chunk-CYCEYAEO.mjs +265 -0
- package/dist/token-goat-chunk-CZ3LUXYZ.mjs +4115 -0
- package/dist/token-goat-chunk-DZX2YDPT.mjs +15 -0
- package/dist/token-goat-chunk-E3OQX2XT.mjs +824 -0
- package/dist/token-goat-chunk-EFHMMIGP.mjs +68 -0
- package/dist/token-goat-chunk-ETBHVDB6.mjs +328 -0
- package/dist/token-goat-chunk-EVMZJ27Z.mjs +147 -0
- package/dist/token-goat-chunk-EXKGNHEG.mjs +2096 -0
- package/dist/{token-goat-chunk-6Z5ULNE5.mjs → token-goat-chunk-FBNQNSJK.mjs} +2490 -4957
- package/dist/{token-goat-chunk-NMTKNYGF.mjs → token-goat-chunk-FNFBKLRD.mjs} +74 -9
- package/dist/{token-goat-chunk-XI2VFAV6.mjs → token-goat-chunk-FZ3NEW5O.mjs} +33 -19
- package/dist/token-goat-chunk-G5PJ7AGM.mjs +36 -0
- package/dist/{token-goat-chunk-VE27HPIF.mjs → token-goat-chunk-GFBSN7BD.mjs} +30 -398
- package/dist/{token-goat-chunk-L45ZQRT7.mjs → token-goat-chunk-GOLEOXZP.mjs} +780 -786
- package/dist/token-goat-chunk-H2K3QP6H.mjs +24 -0
- package/dist/token-goat-chunk-H2PHHGM5.mjs +188 -0
- package/dist/token-goat-chunk-HAVAOB3S.mjs +87 -0
- package/dist/token-goat-chunk-HG45AF2B.mjs +2228 -0
- package/dist/{token-goat-chunk-CBMY2FGI.mjs → token-goat-chunk-HOJLCGDP.mjs} +17113 -15554
- package/dist/{token-goat-chunk-HUDC5GS5.mjs → token-goat-chunk-HYBFA5X3.mjs} +120 -19
- package/dist/token-goat-chunk-IVALLT3S.mjs +48 -0
- package/dist/token-goat-chunk-IVE6U7KV.mjs +53 -0
- package/dist/{token-goat-chunk-UBUKHVYW.mjs → token-goat-chunk-IVKIZWAB.mjs} +3 -3
- package/dist/{token-goat-chunk-4JMWPWCS.mjs → token-goat-chunk-JB6QN6VF.mjs} +6 -4
- package/dist/{token-goat-chunk-Q4S3UQGO.mjs → token-goat-chunk-JDHE26RP.mjs} +10 -3
- package/dist/{token-goat-chunk-7R2XYKC5.mjs → token-goat-chunk-JDU3EXSU.mjs} +14 -10
- package/dist/token-goat-chunk-JDWCRD6M.mjs +253 -0
- package/dist/{token-goat-chunk-XBESNWEX.mjs → token-goat-chunk-JN4XMLSD.mjs} +7 -4
- package/dist/token-goat-chunk-JTQQGXZH.mjs +733 -0
- package/dist/token-goat-chunk-KKUFXAPD.mjs +25 -0
- package/dist/token-goat-chunk-KQNZDCBD.mjs +47 -0
- package/dist/{token-goat-chunk-4RN64ZND.mjs → token-goat-chunk-KWPNJBDH.mjs} +28 -3
- package/dist/token-goat-chunk-LOBGHXPB.mjs +242 -0
- package/dist/token-goat-chunk-MKPF4CL5.mjs +37 -0
- package/dist/token-goat-chunk-MNWKPRAL.mjs +13 -0
- package/dist/{token-goat-chunk-YWSP6IU7.mjs → token-goat-chunk-N2NMER56.mjs} +25 -15
- package/dist/token-goat-chunk-NYKZLXMK.mjs +218 -0
- package/dist/token-goat-chunk-OJBNYTJP.mjs +3087 -0
- package/dist/token-goat-chunk-P4QMM4WK.mjs +295 -0
- package/dist/token-goat-chunk-PD5VKH46.mjs +184 -0
- package/dist/token-goat-chunk-PEPTHRFF.mjs +129 -0
- package/dist/{token-goat-chunk-VWZKZPSR.mjs → token-goat-chunk-PU7V3FD6.mjs} +8752 -11098
- package/dist/token-goat-chunk-PY533T7F.mjs +46 -0
- package/dist/token-goat-chunk-Q5VTGRH7.mjs +761 -0
- package/dist/{token-goat-chunk-IHKZ3QNA.mjs → token-goat-chunk-QCLDAQTS.mjs} +33 -19
- package/dist/{token-goat-chunk-LKSXAMJB.mjs → token-goat-chunk-QSBRTGM2.mjs} +9 -2
- package/dist/{token-goat-chunk-4STDIGYC.mjs → token-goat-chunk-RC35RBUL.mjs} +7 -5
- package/dist/{token-goat-chunk-D5ICEPSB.mjs → token-goat-chunk-RHXKCZX3.mjs} +887 -507
- package/dist/{token-goat-chunk-RSS3TLXU.mjs → token-goat-chunk-RZRTDST7.mjs} +17 -7
- package/dist/{token-goat-chunk-MAMQPC43.mjs → token-goat-chunk-SJHWVNDQ.mjs} +15 -21
- package/dist/token-goat-chunk-SMVRN2HU.mjs +188 -0
- package/dist/{token-goat-chunk-EL7M26WP.mjs → token-goat-chunk-SQSSNQPE.mjs} +2100 -1442
- package/dist/{token-goat-chunk-OZRSREKR.mjs → token-goat-chunk-T4FK7VOV.mjs} +3 -3
- package/dist/token-goat-chunk-U4N3BN2W.mjs +92 -0
- package/dist/token-goat-chunk-UA5V6P3P.mjs +122 -0
- package/dist/{token-goat-chunk-XKY4VKJ4.mjs → token-goat-chunk-UQ5UK2T7.mjs} +15 -4
- package/dist/token-goat-chunk-USILZ3T3.mjs +53 -0
- package/dist/token-goat-chunk-VES7EL7O.mjs +205 -0
- package/dist/{token-goat-chunk-M56BWPBN.mjs → token-goat-chunk-VL3YIFHZ.mjs} +550 -49
- package/dist/{token-goat-chunk-IZXKVT4A.mjs → token-goat-chunk-VPBBTSJR.mjs} +362 -128
- package/dist/{token-goat-chunk-F2ARFHLJ.mjs → token-goat-chunk-W3QCJS6G.mjs} +10 -2
- package/dist/{token-goat-chunk-FSTWAOW6.mjs → token-goat-chunk-WY3L4DVT.mjs} +11 -5
- package/dist/{token-goat-chunk-OSUFN2FV.mjs → token-goat-chunk-XB5KKOCG.mjs} +5 -25
- package/dist/token-goat-chunk-XKI4SEMX.mjs +66 -0
- package/dist/token-goat-chunk-XU4P6Z24.mjs +133 -0
- package/dist/{token-goat-chunk-6CCQDAYY.mjs → token-goat-chunk-Y776AENC.mjs} +138 -33
- package/dist/token-goat-chunk-YARZFCZS.mjs +359 -0
- package/dist/{token-goat-chunk-EEIDFMEM.mjs → token-goat-chunk-YZAAZU2S.mjs} +12 -3
- package/dist/{token-goat-chunk-E3K3BTEQ.mjs → token-goat-chunk-Z44YO3QZ.mjs} +12 -6
- package/dist/token-goat-chunk-Z57YODA2.mjs +35 -0
- package/dist/{token-goat-chunk-DA43OE7L.mjs → token-goat-chunk-ZCDTCVIS.mjs} +49 -30
- package/dist/token-goat-chunk-ZEJVMUQH.mjs +48 -0
- package/dist/{token-goat-chunk-BGHSSJUA.mjs → token-goat-chunk-ZFOBKUWH.mjs} +1 -1
- package/dist/token-goat-chunk-ZMBL6UVV.mjs +110 -0
- package/dist/{token-goat-chunk-SJEKA7Y2.mjs → token-goat-chunk-ZQSJMO2R.mjs} +381 -201
- package/dist/token-goat-hook-client.cjs +539 -0
- package/dist/token-goat-hook-client.mjs +26 -0
- package/dist/token-goat-hook.mjs +48 -28
- package/dist/token-goat.core.mjs +10 -45
- package/docs/C4_RUNTIME_ARCHITECTURE.md +3 -3
- package/docs/cli.md +82 -47
- package/docs/install.md +58 -23
- package/docs/security.md +7 -7
- package/package.json +17 -7
- package/scripts/verify-native-dist.mjs +386 -0
- package/dist/token-goat-chunk-4JJBFT7V.mjs +0 -20
- package/dist/token-goat-chunk-5NNYIUGV.mjs +0 -143
- package/dist/token-goat-chunk-6DQNNFJ6.mjs +0 -294
- package/dist/token-goat-chunk-7MAFDRVR.mjs +0 -47
- package/dist/token-goat-chunk-BCN2YQC6.mjs +0 -32
- package/dist/token-goat-chunk-D7GHQKQD.mjs +0 -30
- package/dist/token-goat-chunk-GMOUBOX4.mjs +0 -386
- package/dist/token-goat-chunk-IFORDBGC.mjs +0 -192
- package/dist/token-goat-chunk-JXK2HQXS.mjs +0 -318
- package/dist/token-goat-chunk-L7SDVGBT.mjs +0 -430
- package/dist/token-goat-chunk-MMLMALWK.mjs +0 -1381
- package/dist/token-goat-chunk-MVSWBNMD.mjs +0 -1985
package/README.md
CHANGED
|
@@ -11,19 +11,19 @@ permalink: /
|
|
|
11
11
|
|
|
12
12
|
***Give the model what it needs, not everything you have.***
|
|
13
13
|
|
|
14
|
-
**85%** smaller reads · **49%** of first-read bytes withheld · **97.4%** image compression · **205+** filter & interception rules · **94–99%** skill overhead cut · compaction memory · **prompt injection** guard · **3.7 GB** never reached the model · **1.1 Gt** tokens saved
|
|
14
|
+
**85%** smaller reads · **49%** of first-read bytes withheld · **97.4%** image compression · **leaner prompt cache** · **205+** filter & interception rules · **94–99%** skill overhead cut · compaction memory · **prompt injection** guard · **3.7 GB** never reached the model · **1.1 Gt** tokens saved
|
|
15
15
|
|
|
16
16
|
**Reduces AI token use/costs by 40–90%, and improves its focus. Fully automated, always online.**
|
|
17
17
|
|
|
18
18
|
**Also defends against prompt injection. Every fetched page, tool result, and extracted document is wrapped in an untrusted-content fence before hitting the model, whether or not it matched an attack pattern, and the scan only decides what the label says. One config line to disable.**
|
|
19
19
|
|
|
20
|
-
**Your AI re-reads the same file three times. Every compaction causes amnesia. Every build log buries the one line that matters. You pay for all of it. Token-Goat fixes all of it — automatically.**
|
|
20
|
+
**Your AI re-reads the same file three times. Every whole-file dump is paid for again on every turn after it. Every compaction causes amnesia. Every build log buries the one line that matters. You pay for all of it. Token-Goat fixes all of it — automatically.**
|
|
21
21
|
|
|
22
22
|
Token-Goat sits silently between your AI and your tools. Re-read a file? It gets a one-line hint and a narrow-slice suggestion instead of the full file again. Grab a screenshot? A 100 KB copy reaches the model instead of 10 MB. Run `pytest`, `npm install`, `docker build`, or `cargo`? The thousands of progress bars and passing-test names are stripped to the failures before the output even reaches the context window. Open a PDF, a large Markdown doc, or a CSV? The hook intercepts it — heading tree, page count, or column preview — so the model never pays for the full file. Run `gh run watch` or `next dev` a second time? Prior output is recalled rather than re-run. Compact a long session? It gets a clean structured manifest of edited files and key symbols so nothing important is forgotten. Sessions drop 40–90%+ in cost. You change nothing about how you work.
|
|
23
23
|
|
|
24
24
|
The symbol index also understands native Nginx, Caddyfile, and Apache HTTP Server configuration blocks, so `token-goat read "file::symbol"` can jump directly to them.
|
|
25
25
|
|
|
26
|
-
Works with **Claude Code**, **Gemini CLI**, **Qwen Code**, **Codex CLI**, **Aider**, **Cursor**, **Cline**, **Windsurf**, **Copilot CLI**, **VS Code** (Copilot agent), **Visual Studio** (Copilot agent, MCP tools and instructions only), **Zed** (MCP tools only), **Kimi Code**, **Grok CLI** (xAI Grok Build), and OpenCode, plus **pi** ([pi-coding-agent](https://github.com/earendil-works/pi-mono)).
|
|
26
|
+
Works with **Claude Code**, **Gemini CLI**, **Qwen Code**, **Codex CLI**, **Aider**, **Cursor**, **Cline**, **Windsurf**, **Copilot CLI**, **VS Code** (Copilot agent), **Visual Studio** (Copilot agent, MCP tools and instructions only), **Zed** (MCP tools only), **Kimi Code**, **Grok CLI** (xAI Grok Build), **Antigravity CLI** (`agy`), and OpenCode, plus **pi** ([pi-coding-agent](https://github.com/earendil-works/pi-mono)).
|
|
27
27
|
|
|
28
28
|
**Ask your AI to install it fully (give it this GitHub link), or install in one command:**
|
|
29
29
|
|
|
@@ -51,16 +51,19 @@ Restart your AI sessions. Run `token-goat stats` a couple of minutes after your
|
|
|
51
51
|
|
|
52
52
|
AIs read `auth.py`. Then reads it again. And again. Then a third time after compaction wipes the session. Then it can't find what it wanted and searches other lines and files. You pay for every token and most of it is waste.
|
|
53
53
|
|
|
54
|
-
Long sessions accumulate waste
|
|
54
|
+
Long sessions accumulate waste six ways. Screenshots cross the model at full resolution. A single PNG can land at 10+ MB. The agent re-reads files it already parsed earlier in the same conversation. When a session compacts, the summary LLM doesn't know which files were edited or which symbols mattered, so it preserves the wrong things. Every `pytest`, `npm install`, `docker build`, or `git log` dumps thousands of lines of progress bars, deprecation warnings, and passing-test names that bury the one line that actually matters.
|
|
55
55
|
|
|
56
56
|
The fifth waste is skills. A single large skill injects 10k–65k tokens every time. Run a five-iteration `/improve` loop and you've paid for five full copies of the same rules. Token-Goat now blocks repeat skill loads before they happen: a PreToolUse hook intercepts the second invocation, serves the cached compact (~400 tokens) instead, and only allows a reload when compaction may have evicted the skill from context. It also intercepts direct reads of skill files and ensures the compaction manifest carries the full skill index — so nothing is forgotten and the full body never re-enters context unnecessarily.
|
|
57
57
|
|
|
58
|
-
The
|
|
58
|
+
The sixth waste is what a large read costs after the turn it lands in. The prompt cache makes it cheaper, not free: Anthropic bills the first cache write at 1.25x the base input price (2x for the one-hour cache), then about 0.1x for every later turn that reads it back, until the session compacts. A 2,000-line file read to check a three-line helper is carried, and paid for, on every one of those turns. It also brings compaction closer, and the turn after a compaction writes the new prefix at the write price. Token-Goat's surgical reads add only the requested symbol or slice, so every later turn carries less.
|
|
59
|
+
|
|
60
|
+
The fastest way to reduce AI token costs is fixing these six, not writing shorter prompts. Each one is preventable. Token-Goat intercepts all six, automatically.
|
|
59
61
|
|
|
60
62
|
## What changes
|
|
61
63
|
|
|
62
64
|
| Without Token-Goat | With Token-Goat |
|
|
63
65
|
|--------------------|------------------|
|
|
66
|
+
| A full-file read is written to the prompt cache once, then read back on every later turn until compaction | Surgical reads add only the lines asked for, so every later turn reads back less and compaction comes later |
|
|
64
67
|
| 3.3 MB screenshot lands in model context | 84 KB compressed copy, 97.4% smaller |
|
|
65
68
|
| Agent re-reads files from earlier in the session | "Already read this" reminder with narrow slice suggestion |
|
|
66
69
|
| Read tool asks for lines the session was already given | Answered with a pointer at the copy already delivered instead of the file, when the text this read would return matches the text already served for it whole line for whole line. Proof rather than a read count, so it also covers a file inside the recent-read protection window; a changed file, a wider range, and `reread_deny = false` all pass through |
|
|
@@ -109,6 +112,8 @@ The fastest way to reduce AI token costs is fixing these five, not writing short
|
|
|
109
112
|
| Index-only files (lockfiles, source maps, bundles) read on every session | Pre-Read suppression for read-only files (package-lock.json, *.map, dist/), skipped unless explicitly edited |
|
|
110
113
|
| Large markdown file read in full (README.md, CHANGELOG.md, CLAUDE.md ≥8 KB) | Heading tree intercepted instead — H1–H3 with `#2`/`#3` disambiguation; `token-goat section` shortcuts listed for well-known files; post-edit injects a re-read suggestion rather than the full file |
|
|
111
114
|
| Subagent reads a ≥30 KB markdown file whole, on its first look at it | Off by default. Set `subagent_markdown_first_read_deny = true` under `[hints]` to block that read and answer with the heading tree instead. Only fires in a subagent, only on a first, un-ranged read of a `.md`/`.mdx`/`.markdown` file with at least three headings; a read that already asks for a line range, and every main-session read, pass through untouched |
|
|
115
|
+
| Claude Code spawns an agent without `subagent_type` while tools-restricted agent definitions exist | Off by default. Set `agent_scoped_spawn_deny = true` under `[hints]` (or `TOKEN_GOAT_AGENT_SCOPED_SPAWN_DENY=1`) to refuse the first such spawn in a session and name the restricted agents, so the retry can pick one. An untyped spawn runs as general-purpose, whose context starts with every tool and MCP schema on the machine. Re-issuing the same call runs it: the refusal happens once per session. A spawn that names any `subagent_type`, `general-purpose` included, is never refused, and Copilot CLI and VS Code are left alone |
|
|
116
|
+
| Claude Code Bash command on Windows that contains two backslashes in a row | Refused before it runs, with the reason and what to do instead. Git Bash halves every run of two or more backslashes in the command it is handed, so an escaped path, a regular expression or a `printf` format string would run as different text with no error. Write the text to a file with the Write tool and run it by path, use the PowerShell tool, or use forward slashes in paths. Claude Code on Windows only; set `deny_bash_double_backslash = false` under `[hints]` (or `TOKEN_GOAT_DENY_BASH_DOUBLE_BACKSLASH=0`) to turn it off |
|
|
112
117
|
| A source file is read whole for the first time, with no earlier copy to compare it against | Keeps each function's declaration and its first eight lines, replacing the rest with one line naming the symbol, the exact range removed, and the command that returns it. Set `fold_code_bodies = false` under `[hints]` to turn it off. Comment blocks of twelve lines or more fold to their first two on the same terms. Imports, signatures, type declarations, classes and interfaces are never folded, and a file whose index no longer matches what is on disk keeps its bodies. Measured on this repository's own source: 229 of 256 files fold, and 43% of what a read of them delivers is removed. A read that already names an offset or a limit, and any file holding something that looks like a secret, pass through untouched |
|
|
113
118
|
| PDF opened via Read | Full read denied; PDF shows page count and outline (`token-goat pdf-extract` pulls the actual text, optionally paged/sliced, when the outline isn't enough) |
|
|
114
119
|
| Excel/PowerPoint/Word file (.xlsx/.pptx/.docx) opened via Read | Full read denied; redirects to the matching narrow-slice command family (`xlsx-sheets`/`xlsx-columns`/`xlsx-head`/`xlsx-range`/`xlsx-query`, `pptx-outline`/`pptx-slide`/`pptx-notes`/`pptx-text`, `docx-outline`/`docx-tables`/`docx-text`) instead of extracting the whole document as text |
|
|
@@ -116,7 +121,7 @@ The fastest way to reduce AI token costs is fixing these five, not writing short
|
|
|
116
121
|
| Parquet file (.parquet) opened via Read | Full read denied; redirects to DuckDB for SQL querying instead of reading binary columnar data |
|
|
117
122
|
| Large JSON or YAML file (≥20 KB) read in full | Top-level keys or array summary previewed; redirects to `json-outline`/`json-query` or `yaml-outline`/`yaml-query` instead of blowing context on multi-megabyte payloads |
|
|
118
123
|
| A file read through inline Python, Node or PowerShell (`python -c "...open('r.json')..."`) | Runs capped at 2,000 tokens with no other filtering, so a one-key projection comes back whole; a whole-file dump is cut, ends with a recall id, and names `json-outline`/`json-query` for JSON and YAML. Still refused where the wrapper cannot run: a pipeline or chain, a background `&`, compression turned off |
|
|
119
|
-
| Findings you want to survive a compaction | `token-goat note set <key> "<finding>"` stores one per project; notes print at every session start and in the compaction manifest |
|
|
124
|
+
| Findings you want to survive a compaction | `token-goat note set <key> "<finding>"` stores one per project; notes print at every session start and in the compaction manifest. Add `--anchor src/auth.ts::login`, or name a `file::symbol` in the finding, and the note is marked "(changed since note)" once that symbol changes |
|
|
120
125
|
| Large JSON Lines file (.jsonl ≥20 KB) read in full | Record count and first-record schema shown; suggests slicing records with offset/limit instead of loading millions of tokens |
|
|
121
126
|
| Other Office binary (.odt, .ods, .ott, .odp) opened via Read | Full read denied; redirects to `pandoc` for text extraction (no dedicated reader for these formats yet) |
|
|
122
127
|
| Large CSV or TSV file (≥10 KB) read in full | Column headers, row count, and 3 sample rows shown; `token-goat csv-query` projects columns and/or filters rows instead of a full read; `duckdb` query suggestion for very large tabular data |
|
|
@@ -202,8 +207,8 @@ Numbers below come from synthetic-fixture benchmarks in the test suite, except t
|
|
|
202
207
|
|
|
203
208
|
| Source | Improvement | Measured impact | Where |
|
|
204
209
|
|--------|-------------|-----------------|-------|
|
|
205
|
-
| Large-document outline | A read naming no `offset` or `limit` on a markdown document over 8 KB with six or more headings returns the lead-in and heading tree, plus the `token-goat section` command that reads any section verbatim | Measured on 13,870 real reads across 5,104 sessions: withholds 40.4% of all bytes the Read tool delivers. A 104,890 B document returns 1,541 B with its opening paragraph intact. Sections sum to the document, so a reader who pulls every one back pays about 3% over reading it whole | `src/
|
|
206
|
-
| Large-source skeleton | A read naming no `offset` or `limit` on a source file over 12 KB with eight or more declarations returns the preamble and one line per declaration, each withheld run naming the `token-goat read "file::Symbol"` or ranged `Read` that returns it | Measured on the same corpus: withholds up to 8.6% of all bytes the Read tool delivers, a ceiling rather than a booked total, since the shipping gates are narrower than the measurement's. The skeleton is 10.5% of a `.ts` file. Median symbol body is 4.1% of its file, so a reader breaks even at roughly 22 bodies pulled back out of an average 30.8 | `src/
|
|
210
|
+
| Large-document outline | A read naming no `offset` or `limit` on a markdown document over 8 KB with six or more headings returns the lead-in and heading tree, plus the `token-goat section` command that reads any section verbatim | Measured on 13,870 real reads across 5,104 sessions: withholds 40.4% of all bytes the Read tool delivers. A 104,890 B document returns 1,541 B with its opening paragraph intact. Sections sum to the document, so a reader who pulls every one back pays about 3% over reading it whole | `src/hooks_read_post.ts` (`foldMarkdownOutline`) |
|
|
211
|
+
| Large-source skeleton | A read naming no `offset` or `limit` on a source file over 12 KB with eight or more declarations returns the preamble and one line per declaration, each withheld run naming the `token-goat read "file::Symbol"` or ranged `Read` that returns it | Measured on the same corpus: withholds up to 8.6% of all bytes the Read tool delivers, a ceiling rather than a booked total, since the shipping gates are narrower than the measurement's. The skeleton is 10.5% of a `.ts` file. Median symbol body is 4.1% of its file, so a reader breaks even at roughly 22 bodies pulled back out of an average 30.8 | `src/hooks_read_post.ts` (`foldSourceSkeleton`) |
|
|
207
212
|
| Image shrink | Every still is encoded both ways and the smaller file wins, rather than one codec being assumed | 2560x1440 screenshot-shaped PNG: 2,782,963 -> 259,475 bytes (91% smaller) | `src/image_shrink.ts` (codec selection) |
|
|
208
213
|
| Repomap output | `--compact` trims the top-symbols list to 10 (vs 30) and drops the recent-files section and per-symbol locations | Denser overview for the same byte budget | `src/baseline.ts` (`buildProjectMap`, `token-goat map --compact`) |
|
|
209
214
|
| DB reindex | Batched single transaction + composite indexes on `(file_id, kind)` | 100 files / 10K rows: 84 s → 1 s (~80× faster) | `src/parser.ts`, `src/db.ts` (index migration) |
|
|
@@ -304,13 +309,15 @@ FAILED tests/test_x.py::test_one
|
|
|
304
309
|
[token-goat: pytest filter compressed 4.8 KiB to 0.1 KiB (97% saved)]
|
|
305
310
|
```
|
|
306
311
|
|
|
307
|
-
|
|
312
|
+
This is semantic log filtering into natural plain text rather than encoded blobs or compressed data. The model reads standard output directly, requiring zero decoding steps or extra reasoning tokens.
|
|
313
|
+
|
|
314
|
+
Built-in output compression covers 150+ dev tool CLIs: `pytest`, `jest` / `vitest`, `cargo`, `npm` / `pnpm` / `yarn` / `bun`, `docker`, `kubectl` / `helm`, `aws`, `ruff` / `eslint` / `mypy` / `pylint` / `oxlint`, `git`, `make` / `gradle` / `mvn` / `ant` / `bazel`, `go test` / `golangci-lint`, `terraform` / `pulumi` / `cdk`, `pip` / `uv` / `conda`, `python`, `gh`, `ansible`, `pre-commit`, `grep`, `eza` / `ls`, `fd`, `bat`, `jq`, `yq`, `curl` / `wget`, `rsync`, `dotnet`, `cmake` / `ctest`, `swift` / `xcodebuild`, `ruby` / `bundler`, `elixir` / `mix`, `php` / `composer`, `flutter` / `dart`, `rust` / `cargo`, `kotlin` / `ktlint`, `zig`, `crystal`, `haskell` / `cabal`, `nix`, `R`, `c++` (conan / vcpkg / cppcheck / clang-tidy), `wrangler` / `hardhat` / `serverless`, `erlang`, `fly.io`, `forge`, `elm`, `julia`, `tox`, `vault`, `packer`, `nx` / `lerna` / `turbo`, `prettier` / `biome`, `sass`, `wasm-pack`, `deno`, **and AI tool CLIs**: `aider`, `gemini`, `claude`, `gh copilot`, `copilot`, `cursor`, `windsurf` (incl. Cascade), `opencode`, `continue`, `cline`. Each filter strips ANSI escapes, collapses `\r` progress bars, dedupes repeated lines, groups linter issues by rule, keeps every error block verbatim, and caps total output at 1000 lines / 64 KiB. Compound commands (`cmd1 && cmd2`) are wrapped per segment, so `git diff && git log` compresses both halves. Disable globally with `TOKEN_GOAT_BASH_COMPRESS=0` (output is still cached, so `bash-output` and `recall` keep working), per-filter via `[bash_compress] disabled_filters = ["docker"]` in config.toml, or preview the output of any command with `token-goat compress --cmd '<your command>'`. To exclude project-specific directories from indexing (temporary venvs, build sandboxes), add `[indexing] skip_dirs = ["my-tmpdir"]` to config.toml. To exclude specific generated files by basename instead (coverage reports, bundler stats), set `[indexing] skip_files = [...]`; it defaults to `["coverage.json", "coverage-final.json"]`, so a project with a legitimately-named `coverage.json` it wants indexed can override the list to drop that entry. Minified bundles (`*.min.js`, `*.min.mjs`, `*.min.cjs`, `*.min.css`, `*-min.js`) are left out of the index by default, because their one-letter names bury real symbols; set `[indexing] skip_minified = false` in the global config.toml to index them.
|
|
308
315
|
|
|
309
316
|
`gh api` responses get an extra pass: boilerplate `*_url` fields (`followers_url`, `gists_url`, `starred_url`, and around a dozen others) are stripped from JSON objects; `html_url`, `avatar_url`, `clone_url`, and `ssh_url` are kept. User and repo objects typically shrink 60–80%. When token-goat sees a GitHub permission error in the output or a non-zero exit on a security endpoint, it injects a system message suggesting `gh auth refresh -s security_events`.
|
|
310
317
|
|
|
311
318
|
A failing `pytest` / `jest` / `vitest` / `go test` / `cargo test` run (including bare `npm test`/`npm run test`/`yarn test`/`pnpm test`) also gets a one-line advisory naming the exact `token-goat bash-output <id> | token-goat failures` command to run instead of re-reading the raw dump. Silent on a passing run, a non-test command, or output too small to be worth reducing.
|
|
312
319
|
|
|
313
|
-
|
|
320
|
+
Agents and interactive users must pass ordinary plain shell commands directly: as positional arguments (`token-goat compress pytest -v tests/`) or as one string with `-c` / `--cmd`. `--cmd-b64` is strictly an internal hook transport flag generated programmatically by token-goat hooks; never synthesize base64 manually, because LLM tokenization can corrupt characters and file paths. The hook transport preserves quotes, backslashes, and dollar signs and takes precedence when more than one form is supplied. `--native` runs the command through the platform's own shell (`cmd.exe` on Windows) instead of bash, which keeps Windows path backslashes intact for tools that reject the forward-slash form.
|
|
314
321
|
|
|
315
322
|
`-q` / `--quiet-success` trades a clean run's output for one line. On exit code 0 the full output is stored for recall and only the summary prints; on any other exit code the compressed output is delivered as usual.
|
|
316
323
|
|
|
@@ -325,6 +332,14 @@ Token-goat tracks how close a session is to the autocompact trigger and tightens
|
|
|
325
332
|
|
|
326
333
|
For recurring scheduler loops, the 25th, 100th, and 250th observed delivery in a session receive a one-time checkpoint/fresh-session reminder; it prevents further accumulation but cannot reclaim input already injected. The count is independent of the scheduler's bracketed identifier, which some hosts repeat for every delivery. Before a direct test command without a focused selector or explicit timeout, the Bash hook either preserves its existing compressor timeout or gives an advisory when compression cannot apply; it never stops the test.
|
|
327
334
|
|
|
335
|
+
### 7. Prompt cache: less to read back on every turn
|
|
336
|
+
|
|
337
|
+
Anthropic bills a prompt cache write at 1.25x the base input price (2x for the one-hour cache) and a cache read at 0.1x. Other providers price cached input differently. The cache holds the prompt prefix, so appending a tool result does not invalidate what is already cached. Changing something earlier in the prompt does: the system prompt, the model, or the tool definitions, which connecting an MCP server changes.
|
|
338
|
+
|
|
339
|
+
What a whole-file read costs is everything after it. The file is written to the cache once, then read back on every later turn until the session compacts, and its extra lines bring that compaction closer. Compaction replaces the conversation with a summary, so the turn after it writes a new prefix at the write price.
|
|
340
|
+
|
|
341
|
+
Token-Goat's surgical commands (`read "file::symbol"`, `section "file::Heading"`, `skeleton file`, `json-query`) return only the lines asked for. Less is carried into every later turn, and compaction comes later.
|
|
342
|
+
|
|
328
343
|
## Install
|
|
329
344
|
|
|
330
345
|
**Requirements:** Node.js 22.16 or later, on any platform.
|
|
@@ -335,11 +350,11 @@ token-goat install
|
|
|
335
350
|
token-goat doctor # confirms hooks are wired; reports any failure it finds
|
|
336
351
|
```
|
|
337
352
|
|
|
338
|
-
Three commands. Hooks register and start working immediately: no terminal popups, no tray icon, no service to babysit. That wires up Claude Code; other agent CLIs are added with a flag (`--codex`, `--copilot`, and siblings).
|
|
353
|
+
Three commands. Hooks register and start working immediately: no terminal popups, no tray icon, no service to babysit. That wires up Claude Code; other agent CLIs are added with a flag (`--codex`, `--copilot`, and siblings). On Windows and Linux, each hook runs through a small native client, `tg-hook`, that hands the call to token-goat's resident hook server instead of starting Node, and runs the Node command itself when the server is away; a Windows binary ships only when it is code-signed (without one, Windows uses the Node command as macOS does), and the Linux ones carry build provenance. Details and the opt-out: [Native hook client](docs/install.md#what-gets-installed).
|
|
339
354
|
|
|
340
355
|
> **WSL performance tip:** Keep active repositories on WSL's native ext4 filesystem (`~/projects/...`) rather than Windows mounts (`/mnt/c/...`) to avoid 9P cross-OS filesystem translation overhead during initial indexing.
|
|
341
356
|
|
|
342
|
-
Per-harness setup for Codex, Gemini, Qwen, Kimi, opencode, OpenClaw, pi, Copilot, Grok and Cline/Windsurf/Cursor, the companion CLI tools worth installing alongside it, upgrading, and the full list of what lands on your machine: **[Install guide](docs/install.md)**.
|
|
357
|
+
Per-harness setup for Codex, Gemini, Qwen, Kimi, opencode, OpenClaw, pi, Copilot, Grok, Antigravity and Cline/Windsurf/Cursor, the companion CLI tools worth installing alongside it, upgrading, and the full list of what lands on your machine: **[Install guide](docs/install.md)**.
|
|
343
358
|
|
|
344
359
|
## CLI
|
|
345
360
|
|
|
@@ -355,7 +370,7 @@ Every command, with its flags, its output, and the comparison workflows that cha
|
|
|
355
370
|
token-goat mcp-serve
|
|
356
371
|
```
|
|
357
372
|
|
|
358
|
-
Runs token-goat as an MCP ([Model Context Protocol](https://modelcontextprotocol.io)) stdio server, exposing surgical-read tools (including `brief`, a one-shot symbol orientation call bundling body, callers, and containing doc section, and `index_status`, which reports whether a project's index has ever been populated, current file/symbol counts, dirty-queue depth, worker liveness, and embeddings availability — call it after an unexpectedly empty result from another tool, since an MCP-only client has no hook layer to warn it apart from a genuine "not found") plus `compress_text`, `retrieve_text`, `handoff_create`, and `handoff_resolve`. These local-only tools use bounded, redacted storage; MCP never intercepts a client's built-in file reads.
|
|
373
|
+
Runs token-goat as an MCP ([Model Context Protocol](https://modelcontextprotocol.io)) stdio server, exposing surgical-read tools (including `brief`, a one-shot symbol orientation call bundling body, callers, and containing doc section, and `index_status`, which reports whether a project's index has ever been populated, current file/symbol counts, dirty-queue depth, worker liveness, and embeddings availability — call it after an unexpectedly empty result from another tool, since an MCP-only client has no hook layer to warn it apart from a genuine "not found") plus `compress_text`, `retrieve_text`, `handoff_create`, and `handoff_resolve`. These local-only tools use bounded, redacted storage; MCP never intercepts a client's built-in file reads. Every tool takes an optional `projectRoot`. When a call leaves it out, the server infers the project: from an absolute path that exists, then from indexed file paths ending with the path you gave, then, for a bare name, from the project that defines that symbol. It only infers a project token-goat has indexed that sits inside the server's allowed roots; otherwise it keeps its own working directory, so with `mcp.confine_reads_to_project_root` on, a path outside it is still refused. Passing `projectRoot` always wins.
|
|
359
374
|
|
|
360
375
|
### Generic compression and handoffs
|
|
361
376
|
|
|
@@ -369,7 +384,7 @@ token-goat handoff-resolve review-notes --full
|
|
|
369
384
|
|
|
370
385
|
`token-goat compress-text` returns a stable opaque ID, size metadata, an estimated token delta, and a recovery command. The deflate/base64url payload tokenizes far worse per byte than plain text, so for most real inputs inlining it costs more tokens than the original: it is printed only when it genuinely wins, and `--payload` forces it for the self-contained case where you need a blob that decodes on another machine. A negative `tokens_saved` is a cost, not a saving. `token-goat retrieve` restores the locally cached text. Handoffs are created with `token-goat handoff-create` and resolved with `token-goat handoff-resolve`; they are named and project-local, and resolve compactly by default or in full with `--full`. Content is limited to 512 KiB and stored in a bounded local cache with secret redaction. `token-goat stats` includes these outcomes alongside existing savings.
|
|
371
386
|
|
|
372
|
-
`token-goat retrieve <id>` takes the same output filters as `bash-output`/`web-output`/`mcp-output`: `--head <n>`, `--tail <n>`, `--grep <pattern>`, `--max-matches <n>`, `--section <heading>`, and `--full`. With no filter at all, `retrieve` prints the stored text byte-verbatim -- this is its lossless round-trip contract and it never applies the siblings' default head/tail elision. Pass any filter and it switches to sibling semantics (including elision) for that call, so a large stored blob can be recalled a slice at a time instead of taking all of it.
|
|
387
|
+
`token-goat retrieve <id>` takes the same output filters as `bash-output`/`web-output`/`mcp-output`: `--head <n>`, `--tail <n>`, `--grep <pattern>`, `--max-matches <n>`, `--section <heading>`, `--lines <a-b>`, `--context <n>`, `-n` and `--full`. With no filter at all, `retrieve` prints the stored text byte-verbatim -- this is its lossless round-trip contract and it never applies the siblings' default head/tail elision. Pass any filter other than `-n`, which only numbers the lines, and it switches to sibling semantics (including elision) for that call, so a large stored blob can be recalled a slice at a time instead of taking all of it.
|
|
373
388
|
|
|
374
389
|
**VS Code** — add it to `.vscode/mcp.json` under the `"servers"` key (this is the correct root key for VS Code's MCP config; it is not `"mcpServers"`):
|
|
375
390
|
|
|
@@ -411,18 +426,7 @@ Installing the extension is an alternative to `install --vscode`, not an additio
|
|
|
411
426
|
|
|
412
427
|
If the extension is running somewhere that contribution did not take effect, it falls back to calling `token-goat mcp-status --vscode` (add `-p`/`--project` for the workspace scope too) to check whether `mcp.json` already configures the decoder, and offers to run `install --vscode` if not — the same path resolver `install`/`uninstall` write against, so the two can never drift on where `mcp.json` lives or what key name it looks for.
|
|
413
428
|
|
|
414
|
-
**Copilot CLI
|
|
415
|
-
|
|
416
|
-
```json
|
|
417
|
-
{
|
|
418
|
-
"mcpServers": {
|
|
419
|
-
"token-goat": {
|
|
420
|
-
"command": "token-goat",
|
|
421
|
-
"args": ["mcp-serve"]
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
```
|
|
429
|
+
**Copilot CLI**: `token-goat install --copilot` registers the server in `~/.copilot/mcp-config.json` (or `$COPILOT_HOME/mcp-config.json`), in the same shape `copilot mcp add` writes, and `copilot mcp list` shows it. `token-goat uninstall --copilot` removes it and leaves your other servers alone. A `token-goat` entry you wrote by hand from an older version of this README is replaced on install.
|
|
426
430
|
|
|
427
431
|
**Caveat.** Registering the server does not force any harness to prefer it. Unlike the hook-based bridges elsewhere in this project — which intercept a `Read`/`Grep`/`Glob` call before it reaches the model and can redirect or deny it outright — an MCP tool is just one more option in the harness's own tool-selection decision. Copilot (or any other MCP-aware client) decides for itself whether to call token-goat's `read` tool or fall back to its own built-in file-read tool; there is no interception mechanism for MCP the way there is for hooks. In VS Code the agent hooks from `install --vscode` do see the built-in reads: they can deny a repeated read, add a hint, and shrink an image before `view_image` loads it. VS Code gives hooks no way to change a tool's result, though, so there is no folding of what a read returns and no compression of a tool's output after it runs. Terminal output is not compressed in VS Code either: elsewhere token-goat does that by rewriting the command before it runs, but VS Code does not tell the hook which shell will run the command, so rewriting it safely is not possible.
|
|
428
432
|
|
|
@@ -440,7 +444,9 @@ The file-by-file table for each harness, and the path that file sits at: **[What
|
|
|
440
444
|
|
|
441
445
|
Hooks fire automatically on every tool call once installed — nothing to start or restart there. The background worker is a separate, manual step: `token-goat worker start` launches it as a detached process, `token-goat worker status` checks it, `token-goat worker stop` kills it. It restarts itself automatically if it crashes or gets killed while the machine is running — an edit hook checks its liveness and respawns it, rate-limited to about once every 5 minutes. It does not survive a reboot or logout, though; re-run `worker start` after either. `token-goat uninstall` removes the hook entries, `CLAUDE.md` block, and skill directory, but does not touch a running worker — stop it separately with `token-goat worker stop` if you no longer want it running.
|
|
442
446
|
|
|
443
|
-
|
|
447
|
+
Hooks also answer faster after the first call. That call starts a small resident process, the hook server, and later hook calls go to it instead of starting Node and loading token-goat each time. In measurements on Windows that took a hook call from 110 to 135 ms down to about 70 ms in Claude Code, Codex, Copilot CLI and VS Code chat, and a read command such as `token-goat section` from 122 ms to 60 ms when its output goes to the agent rather than a terminal. You never start it yourself. It stops after 30 minutes idle, after an upgrade, when you turn it off, and when `uninstall --purge` runs. `token-goat hook-server status` shows what is running and `token-goat hook-server stop` stops it. To turn it off, set `server = false` under `[hooks]` in your global config, or `TOKEN_GOAT_HOOK_SERVER=0`. A project's `.token-goat.toml` cannot change this setting, because one server answers every project.
|
|
448
|
+
|
|
449
|
+
To move to a newer release, `token-goat upgrade` installs it from npm and then re-runs `token-goat install`, so your hooks and integration manifests point at the build that just landed. `token-goat upgrade --check` reports whether one is available without installing anything, and `--json` gives the same answer for a script. The check asks `npm view` first, so a registry set up in npm (Artifactory, Nexus), its auth token and its CA certificate are used; it falls back to a direct request to the registry in `npm_config_registry`, or to npmjs.org. A successful result is cached for 24 hours, though `upgrade --check` itself always asks again. When a newer version is out, `token-goat doctor` mentions it at the end of its report, `token-goat stats` lists it in its insights, and the context added at session start says so. None of this happens when `network.offline` is set, and `token-goat doctor --repair` installs the update as its last step.
|
|
444
450
|
|
|
445
451
|
## Verify
|
|
446
452
|
|
|
@@ -453,25 +459,15 @@ token-goat stats
|
|
|
453
459
|
|
|
454
460
|
### Confirming hooks are wired
|
|
455
461
|
|
|
456
|
-
`doctor` checks the binary, worker, database, and disk,
|
|
462
|
+
`doctor` checks the binary, worker, database, and disk, whether the installed Claude Code, Codex and Copilot hook shims match the running build, and the hook wiring itself. Its `Claude Code hook events` line reads `every event this build handles is wired` when `settings.json` has a current token-goat entry for each event; otherwise it names, per scope, the events that are missing, still run a command this build no longer writes, or point at a native hook client binary that is gone. The `Native hooks` lines report, per harness, which form of hook command is wired and whether the native client binary is present and passes its self-test. To fix any of them, re-run `install`:
|
|
457
463
|
|
|
458
464
|
```
|
|
459
465
|
token-goat install
|
|
460
466
|
```
|
|
461
467
|
|
|
462
|
-
`install` is idempotent: it adds
|
|
463
|
-
|
|
464
|
-
```bash
|
|
465
|
-
# Linux / macOS / WSL
|
|
466
|
-
jq '[.hooks | to_entries[] | select(.value[].hooks[]?.command | contains("token-goat hook")) | .key]' ~/.claude/settings.json
|
|
467
|
-
|
|
468
|
-
# Windows (PowerShell with jq on your PATH)
|
|
469
|
-
jq '[.hooks | to_entries[] | select(.value[].hooks[]?.command | contains("token-goat hook")) | .key]' "$env:USERPROFILE\.claude\settings.json"
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
A working install returns `["PreToolUse", "PostToolUse", "PreCompact"]`. Any missing event means a partial install; run `token-goat install` to fill it in.
|
|
468
|
+
`install` is idempotent: it adds missing entries, rewrites outdated token-goat entries in place, and leaves everything else in `settings.json` alone. Re-running it is always safe. Restart any running session afterwards so it picks up the new entries.
|
|
473
469
|
|
|
474
|
-
**AI agents:** after `token-goat install`, run
|
|
470
|
+
**AI agents:** after `token-goat install`, run `token-goat doctor` and check the `Claude Code hook events` line before marking the install complete.
|
|
475
471
|
|
|
476
472
|
## Image support
|
|
477
473
|
|
package/SECURITY.md
CHANGED
|
@@ -41,11 +41,11 @@ The following are not treated as security issues unless paired with a working pr
|
|
|
41
41
|
|
|
42
42
|
## Dependency advisories
|
|
43
43
|
|
|
44
|
-
`npm audit` reports Token-Goat clean for anyone who installs it, and that has
|
|
44
|
+
`npm audit` reports Token-Goat clean for anyone who installs it, and that has been true of a default install since the embedding library that carried every finding was removed. This repository's own tree is clean as well, development dependencies included: `adm-zip` and `hono` were resolved to patched versions once they had cleared Dependabot's seven-day cooldown, not bumped the day a fix was published -- see [`.github/dependabot.yml`](.github/dependabot.yml) for why a plain `npm update` isn't the fix. All three numbers below are reproducible with the commands shown. The one place an advisory can still reach is the optional native runtime, which a default install does not carry, and it is described further down rather than folded into these rows.
|
|
45
45
|
|
|
46
46
|
| What you scan | Command | Result |
|
|
47
47
|
| --- | --- | --- |
|
|
48
|
-
| this repository | `npm audit` |
|
|
48
|
+
| this repository | `npm audit` | clean |
|
|
49
49
|
| an install without optional packages | `npm install --omit=optional token-goat` then `npm audit --omit=dev --omit=optional` | clean, 2 packages |
|
|
50
50
|
| a default install | `npm install token-goat` then `npm audit --omit=dev` | clean, 62 packages |
|
|
51
51
|
|
|
@@ -53,23 +53,25 @@ The repository carries an `overrides` block in [`package.json`](package.json) th
|
|
|
53
53
|
|
|
54
54
|
There is no table of reaching advisories here any more, and the last entry in it is worth recording rather than deleting. `@xenova/transformers` was an optional dependency, which in npm means everyone got it unless they asked not to, and it carried [`protobufjs`](https://github.com/advisories/GHSA-xq3m-2v4x-88gg) through `onnx-proto` and `onnxruntime-web` -- one critical advisory and four more -- plus its own nested, older `sharp` carrying [four inherited libvips CVEs](https://github.com/advisories/GHSA-f88m-g3jw-g9cj). None of the six was fixable from here: every one sits in a transitive package with no patched version, and the pins that would have solved it do not travel to consumers.
|
|
55
55
|
|
|
56
|
-
That package is gone entirely now. It had shipped no release since May 2024, so none of those six was going to be fixed upstream either, and what it did for Token-Goat was three separable things: tokenize the text, run an ONNX graph, average the result. All three are in [`src/embed_tokenizer.ts`](src/embed_tokenizer.ts) and [`src/embed_model.ts`](src/embed_model.ts) now, over
|
|
56
|
+
That package is gone entirely now. It had shipped no release since May 2024, so none of those six was going to be fixed upstream either, and what it did for Token-Goat was three separable things: tokenize the text, run an ONNX graph, average the result. All three are in [`src/embed_tokenizer.ts`](src/embed_tokenizer.ts) and [`src/embed_model.ts`](src/embed_model.ts) now, over ONNX Runtime itself, from the same project that produces the format the model is published in.
|
|
57
57
|
|
|
58
|
-
The
|
|
58
|
+
A default install runs the model on the WebAssembly build of ONNX Runtime, [`onnxruntime-web`](https://www.npmjs.com/package/onnxruntime-web) 1.30.0, and that adds no package to it. The runtime's JavaScript is bundled into Token-Goat at build time; the one loader module that ships beside the bundle as a separate file is checked against a recorded SHA-256 and length before it is imported. Its 14 MB binary, `ort-wasm-simd-threaded.wasm`, is downloaded once, on first use. [`src/embed_runtime.ts`](src/embed_runtime.ts) fetches that release's tarball from `registry.npmjs.org` at a URL built entirely from constants, holds it to a recorded SHA-256 and byte length while it streams, takes the one file it needs out of it with its own tar reader, checks that file against a digest of its own, and deletes the tarball. Nothing is installed and no install script runs. The kept copy is re-verified on every load; `network.offline` refuses the download but still accepts a copy placed by hand, because it is checked the same way. If the runtime cannot start at all, `semantic` still works, because it always consults keyword search alongside the vectors, so nothing errors and nothing comes back empty; what goes away is matching on meaning rather than words.
|
|
59
|
+
|
|
60
|
+
[`onnxruntime-node`](https://www.npmjs.com/package/onnxruntime-node), ONNX Runtime's native Node binding, is used instead whenever it is installed. It is optional because it is large, about 288 MB installed with every platform's binaries, and because it is the one package on this page that runs an install script of its own:
|
|
59
61
|
|
|
60
62
|
```bash
|
|
61
63
|
npm install -g onnxruntime-node # drop -g if token-goat is a project dependency
|
|
62
64
|
```
|
|
63
65
|
|
|
64
|
-
**That command
|
|
66
|
+
**That command installs clean from `onnxruntime-node` 1.30.0 onward, and runs clean in this repository.** Earlier releases depend on [`adm-zip`](https://www.npmjs.com/package/adm-zip) below 0.6.0, which carries [GHSA-xcpc-8h2w-3j85](https://github.com/advisories/GHSA-xcpc-8h2w-3j85) -- a crafted ZIP file provoking a 4 GB allocation -- and npm reports it twice, once against `adm-zip` and once against `onnxruntime-node` for depending on it. Both are the same finding. It is reachable only from `onnxruntime-node`'s own postinstall script, which uses it to unpack the prebuilt binary it has just downloaded from Microsoft; nothing in Token-Goat passes it an archive, and no file a user supplies reaches it. `adm-zip` 0.6.0 fixed that one and carries a second, unrelated advisory, [GHSA-vwc7-r8mq-g2x9](https://github.com/advisories/GHSA-vwc7-r8mq-g2x9) (extraction following a destination symlink), which 0.6.1 clears. `onnxruntime-node` 1.30.0 asks for `^0.6.0`, so a fresh install of it resolves 0.6.1 and `npm audit` reports nothing, measured on 1.30.0. This repository pins `adm-zip` to that version in `overrides` as well. If you are held on an older `onnxruntime-node`, the fix is an `overrides` entry of your own:
|
|
65
67
|
|
|
66
68
|
```json
|
|
67
|
-
{ "overrides": { "adm-zip": "^0.6.
|
|
69
|
+
{ "overrides": { "adm-zip": "^0.6.1" } }
|
|
68
70
|
```
|
|
69
71
|
|
|
70
|
-
in the package.json of the project you install into, then reinstall. Measured, because the obvious alternative does not work: installing `adm-zip@^0.6.
|
|
72
|
+
in the package.json of the project you install into, then reinstall. Measured, because the obvious alternative does not work: installing `adm-zip@^0.6.1` alongside an older `onnxruntime-node` changes nothing, since the version those releases ask for is `^0.5.16` and npm nests a second copy rather than sharing yours. An override is what actually replaces it, and the prebuilt binary still extracts afterwards. A global `npm install -g onnxruntime-node` has no project manifest to put an override in, so there, install 1.30.0 or later.
|
|
71
73
|
|
|
72
|
-
Nothing else is needed. The index notices on its own: files skipped while the
|
|
74
|
+
Nothing else is needed. The index notices on its own: files skipped while the runtime could not run are recorded as skipped for that reason specifically, so the next index pass re-embeds them rather than treating them as already done. Vectors are stamped with the runtime that computed them, so moving between the two builds re-embeds rather than mixing them. `token-goat doctor` and `token-goat semantic --preflight` report which runtime is active, whether the WebAssembly binary has been downloaded yet, or that embeddings are switched off in config, because a fallback that works silently is exactly the kind of thing nobody discovers on their own.
|
|
73
75
|
|
|
74
76
|
The model weights are no longer a package at all. They are downloaded once, on first use, from a URL whose every component is a constant in [`src/embed_model.ts`](src/embed_model.ts) -- repository, revision and filename alike, with nothing caller-supplied anywhere in it. The revision is an immutable commit rather than a branch, and each file is checked against a recorded SHA-256 and an exact byte length, on download and again on every load, with the length enforced while the body is still streaming so an overrunning response is cut off rather than written out. The digest is what is trusted, not the hostname: `huggingface.co` accepts uploads from anyone, which is the shape of [CVE-2026-54316](https://github.com/advisories/GHSA-fg94-h982-f3mm), so allowlisting the host would decide nothing. Because the digest decides, following the redirect that `resolve` issues to Hugging Face's CDN is safe. With `network.offline` set, the download is refused and the path says so rather than degrading quietly; files copied into the cache directory by hand are still accepted, because they are checked the same way.
|
|
75
77
|
|
|
@@ -87,7 +89,7 @@ The old model had cost something before any of this, through the nested `sharp`
|
|
|
87
89
|
|
|
88
90
|
`better-sqlite3` stays as a development dependency, and like the MCP SDK that is load-bearing. Three parts of the driver are reimplementations rather than passthroughs, and a test written only against the driver would pin whatever the driver does, bugs included. So [`tests/sqlite_driver.test.ts`](tests/sqlite_driver.test.ts) runs both libraries over the same input and requires the answers to match -- most carefully for the `reader` flag, which is the third defence-in-depth layer in the `sqlite-query` read-only guard and the one thing the driver derives rather than reads. The two libraries differ in exactly one place, deliberately: asked for an integer above 2^53 without big-integer reads switched on, `better-sqlite3` returns the nearest double and `node:sqlite` refuses. Silently rounding is the behaviour `sqlite-query` already had to defend against, so the refusal is kept, and that test pins the difference rather than papering over it. That takes a default install from 106 packages to 70, and an install without optional packages from 40 to 2.
|
|
89
91
|
|
|
90
|
-
Every package count on this page is a measurement, not a constant, and it was taken the same way each time: `npm install <the package>` into an empty project, then counting the directories under `node_modules`, the package itself included. They are counts as of 2026-09-11 and they drift upward on their own, because the version ranges a dependency declares resolve to whatever is newest at install time and other people's trees grow. This paragraph said 238 and 87 for a while for exactly that reason: both were true when they were written and neither was true a few releases later. Re-measure before quoting them rather than assuming they still hold. The default figure additionally depends on where you stand: `@napi-rs/canvas` and `sqlite-vec` each publish a prebuilt binary per platform, an install takes only the one that matches, and the rest are skipped, so a default install is a package larger on Linux than on Windows or macOS. The 62 above is the Linux x64 figure, which is the largest of the three; Windows and macOS are 61. The no-optional install
|
|
92
|
+
Every package count on this page is a measurement, not a constant, and it was taken the same way each time: `npm install <the package>` into an empty project, then counting the directories under `node_modules`, the package itself included. They are counts as of 2026-09-11 and they drift upward on their own, because the version ranges a dependency declares resolve to whatever is newest at install time and other people's trees grow. This paragraph said 238 and 87 for a while for exactly that reason: both were true when they were written and neither was true a few releases later. Re-measure before quoting them rather than assuming they still hold. The default figure additionally depends on where you stand: `@napi-rs/canvas` and `sqlite-vec` each publish a prebuilt binary per platform, an install takes only the one that matches, and the rest are skipped, so a default install is a package larger on Linux than on Windows or macOS. The 62 above is the Linux x64 figure, which is the largest of the three; Windows and macOS are 61. The no-optional install pulls no prebuilt binary from any dependency, so 2 is 2 everywhere. The one native program in either install is token-goat's own: the package ships four `tg-hook` binaries under `dist/native/` (Windows and Linux, x64 and arm64), described under [What actually runs](#what-actually-runs). With the single Windows x64 binary present the unpacked package is 6,204,172 bytes; a release carrying all four is about 8.0 MB unpacked, an estimate from the individual binaries (roughly 480 KB for each signed Windows executable, 709 KB for Linux x64 and 619 KB for Linux arm64), not a measurement of a published tarball.
|
|
91
93
|
|
|
92
94
|
One half of that drift is checked rather than trusted. [`tests/guards/dependency_advisory_disclosure.test.ts`](tests/guards/dependency_advisory_disclosure.test.ts) resolves both installs out of [`package-lock.json`](package-lock.json) the way npm resolves them, platform gating included, and holds this page to the answer: the no-optional figure has to match exactly, and the default figure may not be smaller than the lock file already proves it must be. That catches every package this project adds or removes on its own. It cannot catch the other half, which is other people's trees growing inside ranges an install already accepts, and that is what the date is for.
|
|
93
95
|
|
|
@@ -109,7 +111,9 @@ Which names may appear in that tree is pinned in [`tests/guards/runtime_dependen
|
|
|
109
111
|
|
|
110
112
|
The lockfile is not the only thing that decides what loads, so it is not the only thing checked. [`tests/guards/bundle_runtime_imports_are_reviewed.test.ts`](tests/guards/bundle_runtime_imports_are_reviewed.test.ts) reads the built artifact instead and requires every package name it can resolve at run time to have been reviewed — including the ones the lockfile cannot show you, such as a module the host agent supplies out of its own process. Installing this package runs nothing: it declares no `preinstall`, `install`, or `postinstall` script, which [`tests/guards/lifecycle_script_is_published.test.ts`](tests/guards/lifecycle_script_is_published.test.ts) keeps at zero rather than leaving to habit. `npm audit signatures` runs in CI and before every commit that moves the lockfile, so a tarball altered after publication fails rather than installs.
|
|
111
113
|
|
|
112
|
-
|
|
114
|
+
The package also ships one native program of its own: `tg-hook`, the hook client that `install` puts in front of each hook command on Windows and Linux ([Native hook client](docs/install.md#what-gets-installed)). It is a small Rust program in [`native/tg-hook/`](native/tg-hook/), built in the release workflow from the checked-in source with the committed `Cargo.lock`, and it does one thing: relay a hook call to token-goat's resident hook server over a named pipe or Unix socket, and run the Node hook command it wraps when the server cannot answer. It opens no network connection, the only file it reads is the hook server's key file in token-goat's data directory, and it runs only when a harness fires a hook. A user who would rather not run it sets `native = "off"` under `[hooks]` in the global config and runs `install` again; every hook is then the Node command alone, as on macOS, where no binary ships.
|
|
115
|
+
|
|
116
|
+
Releases are built and published by separate jobs ([`.github/workflows/publish.yml`](.github/workflows/publish.yml)). Everything that executes dependency code (`npm ci`, the suite, the build) runs in jobs that hold no registry credential. What crosses into the publishing job is the built bundle and the four native binaries, each from the build or signing job that produced it, and the publishing job verifies them before it publishes ([`scripts/verify-native-dist.mjs`](scripts/verify-native-dist.mjs)): exactly the release binaries and nothing else, each matching the hash its producing job recorded, each Windows file ending in a certificate table whose Authenticode signature names exactly one signer and whose image digest matches the file's own bytes, and each Linux file a static ELF executable for the right machine with code to run that names no shared library. The Windows check binds the signature to the file, so a signature lifted from another binary or bytes appended after it are refused. The check is structural: it requires the parts the image digest does not cover to be whole DER elements but does not look inside certificates or unsigned attributes, and it does not validate the certificate chain, which is what the signing job and `Get-AuthenticodeSignature` below are for. Anything else stops the release. A release built with no Windows signing configuration ships the two Linux binaries and no Windows ones, and the check then refuses any Windows file it finds; Windows installs fall back to the Node hook command. A signing configuration that names an unknown store type or lacks a secret stops the release rather than dropping Windows. That job installs nothing and passes `--ignore-scripts`, so no lifecycle hook can run beside the upload; [`tests/guards/publish_job_runs_no_dependency_code.test.ts`](tests/guards/publish_job_runs_no_dependency_code.test.ts) holds the split. This does not make a release untamperable, and it is not claimed to: the build itself is a bundler running dependency code, so the artifact is the residual risk. It is a smaller one than a writable checkout sharing a job with a publish token.
|
|
113
117
|
|
|
114
118
|
None of this inspects what a dependency does once it runs. It bounds how much third-party code can run at all, and makes any change to that set something a person has to agree to.
|
|
115
119
|
|
|
@@ -125,6 +129,20 @@ npm audit signatures
|
|
|
125
129
|
|
|
126
130
|
Run from a project that depends on token-goat, that command verifies the registry signature and the provenance attestation for every installed package, token-goat included. The package page on npm links the attestation to the exact commit, so you can read the source that produced the bytes you are running.
|
|
127
131
|
|
|
132
|
+
The native `tg-hook` binaries can be checked on their own. A release ships Windows binaries only when it signs them: both are then Authenticode-signed with a certificate held in a cloud HSM and timestamped, so the signature stays valid after the certificate expires. A release without them leaves Windows on the Node hook command, and `token-goat doctor` says the build ships no native hook client for the platform. In PowerShell:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
Get-AuthenticodeSignature "<path to tg-hook.exe>"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`Status` reads `Valid` for a release binary. The path is the one `token-goat doctor` prints on the `Native hooks` line: on Windows that is the copy under `native\<id>\` in the data directory, and the packaged original sits at `dist\native\win32-x64\tg-hook.exe` (or `win32-arm64`) inside the installed package. Both Linux binaries carry build provenance attestations published to this repository, which tie the file to the workflow run and commit that built it:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
gh attestation verify "<path to tg-hook>" --repo DFKHelper/token-goat
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
A binary that was not produced by the release workflow fails that check. The publishing job runs the same kind of check before it publishes, so a release cannot carry an unsigned Windows binary or a Linux binary the build job did not record. An `npm pack` or `npm publish` run from a working tree checks `dist/native` first as well (the `prepack` script, which npm runs for both, so a tarball packed by hand and published later is checked too), and refuses an unsigned Windows binary, such as the one a local build leaves there, or a dynamically linked Linux one. A user who does not want the native binary at all sets `native = "off"` under `[hooks]` in the global config and re-runs `install`.
|
|
145
|
+
|
|
128
146
|
Every action used by that workflow, and by CI, is pinned to a full commit SHA rather than a tag, so a compromised action repository cannot silently change what runs. That is enforced by a test rather than by review: see [tests/guards/workflow_actions_pinned.test.ts](tests/guards/workflow_actions_pinned.test.ts).
|
|
129
147
|
|
|
130
148
|
## License
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Token-Goat itself is licensed separately: see [LICENSE](LICENSE). This file covers only other people's code.
|
|
4
4
|
|
|
5
|
-
`dist/` is a bundle. Building it copies the source of the
|
|
5
|
+
`dist/` is a bundle. Building it copies the source of the 26 packages below into the
|
|
6
6
|
shipped files, so their copyright and permission notices travel with this package and are
|
|
7
7
|
reproduced here in full.
|
|
8
8
|
|
|
@@ -71,7 +71,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
71
71
|
SOFTWARE.
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
## brace-expansion 5.0.
|
|
74
|
+
## brace-expansion 5.0.12
|
|
75
75
|
|
|
76
76
|
License: MIT
|
|
77
77
|
|
|
@@ -284,6 +284,24 @@ THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRE
|
|
|
284
284
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
285
285
|
```
|
|
286
286
|
|
|
287
|
+
## entities 7.0.1
|
|
288
|
+
|
|
289
|
+
License: BSD-2-Clause
|
|
290
|
+
|
|
291
|
+
```text
|
|
292
|
+
Copyright (c) Felix Böhm
|
|
293
|
+
All rights reserved.
|
|
294
|
+
|
|
295
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
296
|
+
|
|
297
|
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
298
|
+
|
|
299
|
+
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
300
|
+
|
|
301
|
+
THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS,
|
|
302
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
303
|
+
```
|
|
304
|
+
|
|
287
305
|
## html-to-text 10.0.1
|
|
288
306
|
|
|
289
307
|
License: MIT
|
|
@@ -523,6 +541,25 @@ including animation and compression. It does not rely on any specific
|
|
|
523
541
|
underlying system, so should run in the browser, Node, or Plask.
|
|
524
542
|
```
|
|
525
543
|
|
|
544
|
+
## onnxruntime-common 1.30.0
|
|
545
|
+
|
|
546
|
+
License: MIT
|
|
547
|
+
|
|
548
|
+
```text
|
|
549
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
550
|
+
Licensed under the MIT License.
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
## onnxruntime-web 1.30.0
|
|
554
|
+
|
|
555
|
+
License: MIT
|
|
556
|
+
|
|
557
|
+
```text
|
|
558
|
+
ONNX Runtime Web v1.30.0
|
|
559
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
560
|
+
Licensed under the MIT License.
|
|
561
|
+
```
|
|
562
|
+
|
|
526
563
|
## parseley 0.13.1
|
|
527
564
|
|
|
528
565
|
License: MIT
|
|
@@ -607,7 +644,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
607
644
|
SOFTWARE.
|
|
608
645
|
```
|
|
609
646
|
|
|
610
|
-
## smol-toml 1.
|
|
647
|
+
## smol-toml 1.9.0
|
|
611
648
|
|
|
612
649
|
License: BSD-3-Clause
|
|
613
650
|
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
async function ortWasmThreaded(moduleArg={}){var moduleRtn;var h=moduleArg,aa=!!globalThis.window,k=!!globalThis.WorkerGlobalScope,m=globalThis.process?.versions?.node&&"renderer"!=globalThis.process?.type,n=k&&self.name?.startsWith("em-pthread");if(m){const {createRequire:a}=await import("module");var require=a(import.meta.url),ba=require("worker_threads");global.Worker=ba.Worker;n=(k=!ba.jc)&&"em-pthread"==ba.workerData}h.mountExternalData=(a,b)=>{a.startsWith("./")&&(a=a.substring(2));(h.Tb||(h.Tb=new Map)).set(a,b)};
|
|
2
|
+
h.unmountExternalData=()=>{delete h.Tb;delete h.mc;delete h.lc;delete h.nc};var SharedArrayBuffer=globalThis.SharedArrayBuffer??(new WebAssembly.Memory({initial:0,maximum:0,shared:!0})).buffer.constructor,ca="./this.program",da=(a,b)=>{throw b;},ea=import.meta.url,fa="",ha,ia;
|
|
3
|
+
if(m){var fs=require("fs");ea.startsWith("file:")&&(fa=require("path").dirname(require("url").fileURLToPath(ea))+"/");ia=a=>{a=ja(a)?new URL(a):a;return fs.readFileSync(a)};ha=async a=>{a=ja(a)?new URL(a):a;return fs.readFileSync(a,void 0)};1<process.argv.length&&(ca=process.argv[1].replace(/\\/g,"/"));process.argv.slice(2);da=(a,b)=>{process.exitCode=a;throw b;}}else if(aa||k){try{fa=(new URL(".",ea)).href}catch{}m||(k&&(ia=a=>{var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";
|
|
4
|
+
b.send(null);return new Uint8Array(b.response)}),ha=async a=>{if(ja(a))return new Promise((d,c)=>{var e=new XMLHttpRequest;e.open("GET",a,!0);e.responseType="arraybuffer";e.onload=()=>{200==e.status||0==e.status&&e.response?d(e.response):c(e.status)};e.onerror=c;e.send(null)});var b=await fetch(a,{credentials:"same-origin"});if(b.ok)return b.arrayBuffer();throw Error(b.status+" : "+b.url);})}var ka=console.log.bind(console),la=console.error.bind(console);
|
|
5
|
+
if(m){var ma=require("util"),na=a=>"object"==typeof a?ma.inspect(a):a;ka=(...a)=>fs.writeSync(1,a.map(na).join(" ")+"\n");la=(...a)=>fs.writeSync(2,a.map(na).join(" ")+"\n")}var oa=ka,p=la,q,r,pa=!1,t,ja=a=>a.startsWith("file://");function v(){x.buffer!=z.buffer&&qa()}var ra,sa;
|
|
6
|
+
if(m&&n){var ta=ba.parentPort;ta.on("message",a=>global.onmessage?.({data:a}));Object.assign(globalThis,{self:global,postMessage:a=>ta.postMessage(a)});process.on("uncaughtException",a=>{postMessage({Rb:"uncaughtException",error:a});process.exit(1)})}var ua;
|
|
7
|
+
if(n){var va=!1;self.onunhandledrejection=b=>{throw b.reason||b;};function a(b){try{var d=b.data,c=d.Rb;if("load"===c){let e=[];self.onmessage=f=>e.push(f);ua=()=>{postMessage({Rb:"loaded"});for(let f of e)a(f);self.onmessage=a};for(const f of d.ac)if(!h[f]||h[f].proxy)h[f]=(...g)=>{postMessage({Rb:"callHandler",$b:f,args:g})},"print"==f&&(oa=h[f]),"printErr"==f&&(p=h[f]);x=d.fc;qa();r=d.hc;wa();xa()}else if("run"===c){ya(d.Qb);za(d.Qb,0,0,1,0,0);Aa();Ba(d.Qb);va||=!0;try{Ca(d.dc,d.Vb)}catch(e){if("unwind"!=
|
|
8
|
+
e)throw e;}}else"setimmediate"!==d.target&&("checkMailbox"===c?va&&Da():c&&(p(`worker: received unknown command ${c}`),p(d)))}catch(e){throw Ea(),e;}}self.onmessage=a}var z,A,Fa,C,D,Ga,G,H,Ha=!1;function qa(){var a=x.buffer;h.HEAP8=z=new Int8Array(a);Fa=new Int16Array(a);h.HEAPU8=A=new Uint8Array(a);new Uint16Array(a);h.HEAP32=C=new Int32Array(a);h.HEAPU32=D=new Uint32Array(a);Ga=new Float32Array(a);G=new Float64Array(a);H=new BigInt64Array(a);new BigUint64Array(a)}
|
|
9
|
+
function Ia(){Ha=!0;n?ua():I.Va()}function J(a){a="Aborted("+a+")";p(a);pa=!0;a=new WebAssembly.RuntimeError(a+". Build with -sASSERTIONS for more info.");sa?.(a);throw a;}var Ja;async function Ka(a){if(!q)try{var b=await ha(a);return new Uint8Array(b)}catch{}if(a==Ja&&q)a=new Uint8Array(q);else if(ia)a=ia(a);else throw"both async and sync fetching of the wasm failed";return a}
|
|
10
|
+
async function La(a,b){try{var d=await Ka(a);return await WebAssembly.instantiate(d,b)}catch(c){p(`failed to asynchronously prepare wasm: ${c}`),J(c)}}async function Na(a){var b=Ja;if(!q&&!ja(b)&&!m)try{var d=fetch(b,{credentials:"same-origin"});return await WebAssembly.instantiateStreaming(d,a)}catch(c){p(`wasm streaming compile failed: ${c}`),p("falling back to ArrayBuffer instantiation")}return La(b,a)}
|
|
11
|
+
function Oa(){Pa={T:Qa,f:Ra,w:Sa,e:Ta,k:Ua,h:Va,L:Wa,b:Xa,G:Ya,ua:Za,j:$a,M:ab,La:bb,qa:cb,sa:db,Ma:eb,Ja:fb,Ca:gb,Ia:hb,Z:ib,ra:jb,oa:kb,Ka:lb,pa:mb,Ra:nb,Fa:ob,ma:pb,va:qb,ja:rb,U:sb,Ea:Ba,Oa:tb,za:ub,Aa:vb,Ba:wb,xa:xb,ya:yb,ka:zb,Ta:Ab,Qa:Bb,W:Cb,V:Db,Pa:Eb,F:Fb,Na:Gb,na:Hb,u:Ib,H:Jb,S:Kb,la:Lb,ba:Mb,Ua:Nb,Ga:Ob,Ha:Pb,ta:Qb,I:Rb,wa:Sb,Y:Tb,Da:Ub,X:Vb,$:Wb,N:Xb,aa:Yb,O:Zb,v:$b,d:ac,m:bc,n:cc,r:dc,ca:ec,E:fc,o:gc,P:hc,C:ic,J:jc,da:kc,ea:lc,z:mc,fa:nc,Q:oc,ga:pc,y:qc,D:rc,c:sc,q:tc,i:uc,_:vc,l:wc,
|
|
12
|
+
p:xc,s:yc,t:zc,x:Ac,R:Bc,A:Cc,K:Dc,B:Ec,ha:Fc,ia:Gc,g:Hc,a:x,Sa:Ic};return{a:Pa}}
|
|
13
|
+
async function wa(){function a(c,e){I=c.exports;I=Jc();Kc.push(I.xb);c=I;h._OrtInit=c.Wa;h._OrtGetLastError=c.Xa;h._OrtCreateSessionOptions=c.Ya;h._OrtAppendExecutionProvider=c.Za;h._OrtAddFreeDimensionOverride=c._a;h._OrtAddSessionConfigEntry=c.$a;h._OrtReleaseSessionOptions=c.ab;h._OrtCreateSession=c.bb;h._OrtReleaseSession=c.cb;h._OrtGetInputOutputCount=c.db;h._OrtGetInputOutputMetadata=c.eb;h._OrtFree=c.fb;h._OrtCreateTensor=c.gb;h._OrtGetTensorData=c.hb;h._OrtReleaseTensor=c.ib;h._OrtCreateRunOptions=
|
|
14
|
+
c.jb;h._OrtAddRunConfigEntry=c.kb;h._OrtReleaseRunOptions=c.lb;h._OrtCreateBinding=c.mb;h._OrtBindInput=c.nb;h._OrtBindOutput=c.ob;h._OrtClearBoundOutputs=c.pb;h._OrtReleaseBinding=c.qb;h._OrtRunWithBinding=c.rb;h._OrtRun=c.sb;h._OrtEndProfiling=c.tb;Lc=c.ub;Mc=h._free=c.vb;Nc=h._malloc=c.wb;za=c.zb;Ea=c.Ab;Oc=c.Bb;Pc=c.Cb;Qc=c.Db;Rc=c.Eb;Sc=c.Fb;K=c.Gb;L=c.Hb;Tc=c.Ib;M=c.Jb;Uc=c.Kb;N=c.Lb;Vc=c.Mb;Wc=c.Nb;Xc=c.Ob;Yc=c.Pb;Zc=c.yb;r=e;return I}var b=Oa();if(h.instantiateWasm)return new Promise(c=>{h.instantiateWasm(b,
|
|
15
|
+
(e,f)=>{c(a(e,f))})});if(n){var d=new WebAssembly.Instance(r,Oa());return a(d,r)}Ja??=h.locateFile?h.locateFile?h.locateFile("ort-wasm-simd-threaded.wasm",fa):fa+"ort-wasm-simd-threaded.wasm":(new URL("ort-wasm-simd-threaded.wasm",import.meta.url)).href;return function(c){return a(c.instance,c.module)}(await Na(b))}class $c{name="ExitStatus";constructor(a){this.message=`Program terminated with exit(${a})`;this.status=a}}
|
|
16
|
+
var ad=a=>{a.terminate();a.onmessage=()=>{}},bd=[],O=0,P=null,ed=a=>{0==Q.length&&(cd(),dd(Q[0]));var b=Q.pop();if(!b)return 6;R.push(b);S[a.Qb]=b;b.Qb=a.Qb;var d={Rb:"run",dc:a.cc,Vb:a.Vb,Qb:a.Qb};m&&b.unref();b.postMessage(d,a.Zb);return 0},T=0,U=(a,b,...d)=>{var c=16*d.length,e=N(),f=Uc(c),g=f>>>3,l;for(l of d)"bigint"==typeof l?((v(),H)[g++>>>0]=1n,(v(),H)[g++>>>0]=l):((v(),H)[g++>>>0]=0n,(v(),G)[g++>>>0]=l);a=Oc(a,0,c,f,b);M(e);return a};
|
|
17
|
+
function Ic(a){if(n)return U(0,1,a);t=a;if(!(0<T)){for(var b of R)ad(b);for(b of Q)ad(b);Q=[];R=[];S={};pa=!0}da(a,new $c(a))}function fd(a){if(n)return U(1,0,a);Qb(a)}var Qb=a=>{t=a;if(n)throw fd(a),"unwind";Ic(a)},Q=[],R=[],Kc=[],S={};function gd(){for(var a=h.numThreads-1;a--;)cd();bd.push(async()=>{var b=hd();O++;await b;O--;0==O&&P&&(b=P,P=null,b())})}var jd=a=>{var b=a.Qb;delete S[b];Q.push(a);R.splice(R.indexOf(a),1);a.Qb=0;Pc(b)};function Aa(){Kc.forEach(a=>a())}
|
|
18
|
+
var dd=a=>new Promise(b=>{a.onmessage=f=>{var g=f.data;f=g.Rb;if(g.Ub&&g.Ub!=Lc()){var l=S[g.Ub];l?l.postMessage(g,g.Zb):p(`Internal error! Worker sent a message "${f}" to target pthread ${g.Ub}, but that thread no longer exists!`)}else if("checkMailbox"===f)Da();else if("spawnThread"===f)ed(g);else if("cleanupThread"===f)kd(()=>{jd(S[g.ec])});else if("loaded"===f)a.loaded=!0,m&&!a.Qb&&a.unref(),b(a);else if("setimmediate"===g.target)a.postMessage(g);else if("uncaughtException"===f)a.onerror(g.error);
|
|
19
|
+
else if("callHandler"===f)h[g.$b](...g.args);else f&&p(`worker sent an unknown command ${f}`)};a.onerror=f=>{p(`${"worker sent an error!"} ${f.filename}:${f.lineno}: ${f.message}`);throw f;};m&&(a.on("message",f=>a.onmessage({data:f})),a.on("error",f=>a.onerror(f)));var d=[],c=[],e;for(e of c)h.propertyIsEnumerable(e)&&d.push(e);a.postMessage({Rb:"load",ac:d,fc:x,hc:r})});async function hd(){if(!n)return Promise.all(Q.map(dd))}
|
|
20
|
+
function cd(){var a=new Worker(new URL(import.meta.url),{type:"module",workerData:"em-pthread",name:"em-pthread"});Q.push(a)}function ya(a){var b=(v(),D)[a+52>>>2>>>0];a=(v(),D)[a+56>>>2>>>0];Tc(b,b-a);M(b)}var ld=[],V=a=>{var b=ld[a];b||(ld[a]=b=Zc.get(a));return b},Ca=(a,b)=>{T=0;a=V(a)(b);0<T?t=a:Qc(a)},x,md=[],nd=0;function Ra(a){a>>>=0;var b=new od(a);0==(v(),z)[b.Sb+12>>>0]&&(pd(b,!0),nd--);qd(b,!1);md.push(b);return Yc(a)}
|
|
21
|
+
var W=0,Sa=()=>{K(0,0);var a=md.pop();Vc(a.Wb);W=0};function pd(a,b){b=b?1:0;(v(),z)[a.Sb+12>>>0]=b}function qd(a,b){b=b?1:0;(v(),z)[a.Sb+13>>>0]=b}class od{constructor(a){this.Wb=a;this.Sb=a-24}}var rd=a=>{var b=W;if(!b)return L(0),0;var d=new od(b);(v(),D)[d.Sb+16>>>2>>>0]=b;var c=(v(),D)[d.Sb+4>>>2>>>0];if(!c)return L(0),b;for(var e of a){if(0===e||e===c)break;if(Xc(e,c,d.Sb+16))return L(e),b}L(c);return b};function Ta(){return rd([])}function Ua(a){return rd([a>>>0])}
|
|
22
|
+
function Va(a,b,d,c){return rd([a>>>0,b>>>0,d>>>0,c>>>0])}var Wa=()=>{var a=md.pop();a||J("no exception to throw");var b=a.Wb;0==(v(),z)[a.Sb+13>>>0]&&(md.push(a),qd(a,!0),pd(a,!1),nd++);Wc(b);W=b;throw W;};function Xa(a,b,d){a>>>=0;var c=new od(a);b>>>=0;d>>>=0;(v(),D)[c.Sb+16>>>2>>>0]=0;(v(),D)[c.Sb+4>>>2>>>0]=b;(v(),D)[c.Sb+8>>>2>>>0]=d;Wc(a);W=a;nd++;throw W;}var Ya=()=>nd;function sd(a,b,d,c){return n?U(2,1,a,b,d,c):Za(a,b,d,c)}
|
|
23
|
+
function Za(a,b,d,c){a>>>=0;b>>>=0;d>>>=0;c>>>=0;if(!globalThis.SharedArrayBuffer)return 6;var e=[];if(n&&0===e.length)return sd(a,b,d,c);a={cc:d,Qb:a,Vb:c,Zb:e};return n?(a.Rb="spawnThread",postMessage(a,e),0):ed(a)}function $a(a){W||=a>>>0;throw W;}
|
|
24
|
+
var td=globalThis.TextDecoder&&new TextDecoder,ud=(a,b=0,d,c)=>{b>>>=0;var e=b;d=e+d;if(c)c=d;else{for(;a[e]&&!(e>=d);)++e;c=e}if(16<c-b&&a.buffer&&td)return td.decode(a.buffer instanceof ArrayBuffer?a.subarray(b,c):a.slice(b,c));for(e="";b<c;)if(d=a[b++],d&128){var f=a[b++]&63;if(192==(d&224))e+=String.fromCharCode((d&31)<<6|f);else{var g=a[b++]&63;d=224==(d&240)?(d&15)<<12|f<<6|g:(d&7)<<18|f<<12|g<<6|a[b++]&63;65536>d?e+=String.fromCharCode(d):(d-=65536,e+=String.fromCharCode(55296|d>>10,56320|
|
|
25
|
+
d&1023))}}else e+=String.fromCharCode(d);return e},vd=(a,b,d)=>(a>>>=0)?ud((v(),A),a,b,d):"";function ab(a,b,d){return n?U(3,1,a,b,d):0}function bb(a,b){if(n)return U(4,1,a,b)}function cb(a,b){if(n)return U(5,1,a,b)}function db(a,b,d){if(n)return U(6,1,a,b,d)}function eb(a,b,d){return n?U(7,1,a,b,d):0}function fb(a,b){if(n)return U(8,1,a,b)}function gb(a,b,d){if(n)return U(9,1,a,b,d)}function hb(a,b,d,c){if(n)return U(10,1,a,b,d,c)}function ib(a,b,d,c){if(n)return U(11,1,a,b,d,c)}
|
|
26
|
+
function jb(a,b,d,c){if(n)return U(12,1,a,b,d,c)}function kb(a){if(n)return U(13,1,a)}function lb(a,b){if(n)return U(14,1,a,b)}function mb(a,b,d){if(n)return U(15,1,a,b,d)}var nb=()=>J("");function ob(a){za(a>>>0,!k,1,!aa,131072,!1);Aa()}
|
|
27
|
+
var kd=a=>{if(!pa)try{if(a(),!(0<T))try{n?Lc()&&Qc(t):Qb(t)}catch(b){b instanceof $c||"unwind"==b||da(1,b)}}catch(b){b instanceof $c||"unwind"==b||da(1,b)}},wd=!Atomics.waitAsync||globalThis.navigator?.userAgent&&91>Number((navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)||[])[2]);function Ba(a){a>>>=0;wd||(Atomics.waitAsync((v(),C),a>>>2,a).value.then(Da),a+=128,Atomics.store((v(),C),a>>>2,1))}var Da=()=>kd(()=>{var a=Lc();a&&(Ba(a),Sc())});
|
|
28
|
+
function pb(a,b){a>>>=0;a==b>>>0?setTimeout(Da):n?postMessage({Ub:a,Rb:"checkMailbox"}):(a=S[a])&&a.postMessage({Rb:"checkMailbox"})}var xd=[];function qb(a,b,d,c,e){b>>>=0;e>>>=0;xd.length=0;d=e>>>3;for(c=e+c>>>3;d<c;){var f;(v(),H)[d++>>>0]?f=(v(),H)[d++>>>0]:f=(v(),G)[d++>>>0];xd.push(f)}return(b?yd[b]:zd[a])(...xd)}var rb=()=>{T=0};function sb(a){a>>>=0;n?postMessage({Rb:"cleanupThread",ec:a}):jd(S[a])}function tb(a){m&&S[a>>>0].ref()}
|
|
29
|
+
function ub(a,b){a=-9007199254740992>a||9007199254740992<a?NaN:Number(a);b>>>=0;a=new Date(1E3*a);(v(),C)[b>>>2>>>0]=a.getUTCSeconds();(v(),C)[b+4>>>2>>>0]=a.getUTCMinutes();(v(),C)[b+8>>>2>>>0]=a.getUTCHours();(v(),C)[b+12>>>2>>>0]=a.getUTCDate();(v(),C)[b+16>>>2>>>0]=a.getUTCMonth();(v(),C)[b+20>>>2>>>0]=a.getUTCFullYear()-1900;(v(),C)[b+24>>>2>>>0]=a.getUTCDay();a=(a.getTime()-Date.UTC(a.getUTCFullYear(),0,1,0,0,0,0))/864E5|0;(v(),C)[b+28>>>2>>>0]=a}
|
|
30
|
+
var Ad=a=>0===a%4&&(0!==a%100||0===a%400),Bd=[0,31,60,91,121,152,182,213,244,274,305,335],Cd=[0,31,59,90,120,151,181,212,243,273,304,334];
|
|
31
|
+
function vb(a,b){a=-9007199254740992>a||9007199254740992<a?NaN:Number(a);b>>>=0;a=new Date(1E3*a);(v(),C)[b>>>2>>>0]=a.getSeconds();(v(),C)[b+4>>>2>>>0]=a.getMinutes();(v(),C)[b+8>>>2>>>0]=a.getHours();(v(),C)[b+12>>>2>>>0]=a.getDate();(v(),C)[b+16>>>2>>>0]=a.getMonth();(v(),C)[b+20>>>2>>>0]=a.getFullYear()-1900;(v(),C)[b+24>>>2>>>0]=a.getDay();var d=(Ad(a.getFullYear())?Bd:Cd)[a.getMonth()]+a.getDate()-1|0;(v(),C)[b+28>>>2>>>0]=d;(v(),C)[b+36>>>2>>>0]=-(60*a.getTimezoneOffset());d=(new Date(a.getFullYear(),
|
|
32
|
+
6,1)).getTimezoneOffset();var c=(new Date(a.getFullYear(),0,1)).getTimezoneOffset();a=(d!=c&&a.getTimezoneOffset()==Math.min(c,d))|0;(v(),C)[b+32>>>2>>>0]=a}
|
|
33
|
+
function wb(a){a>>>=0;var b=new Date((v(),C)[a+20>>>2>>>0]+1900,(v(),C)[a+16>>>2>>>0],(v(),C)[a+12>>>2>>>0],(v(),C)[a+8>>>2>>>0],(v(),C)[a+4>>>2>>>0],(v(),C)[a>>>2>>>0],0),d=(v(),C)[a+32>>>2>>>0],c=b.getTimezoneOffset(),e=(new Date(b.getFullYear(),6,1)).getTimezoneOffset(),f=(new Date(b.getFullYear(),0,1)).getTimezoneOffset(),g=Math.min(f,e);0>d?(v(),C)[a+32>>>2>>>0]=Number(e!=f&&g==c):0<d!=(g==c)&&(e=Math.max(f,e),b.setTime(b.getTime()+6E4*((0<d?g:e)-c)));(v(),C)[a+24>>>2>>>0]=b.getDay();d=(Ad(b.getFullYear())?
|
|
34
|
+
Bd:Cd)[b.getMonth()]+b.getDate()-1|0;(v(),C)[a+28>>>2>>>0]=d;(v(),C)[a>>>2>>>0]=b.getSeconds();(v(),C)[a+4>>>2>>>0]=b.getMinutes();(v(),C)[a+8>>>2>>>0]=b.getHours();(v(),C)[a+12>>>2>>>0]=b.getDate();(v(),C)[a+16>>>2>>>0]=b.getMonth();(v(),C)[a+20>>>2>>>0]=b.getYear();a=b.getTime();return BigInt(isNaN(a)?-1:a/1E3)}function xb(a,b,d,c,e,f,g){return n?U(16,1,a,b,d,c,e,f,g):-52}function yb(a,b,d,c,e,f){if(n)return U(17,1,a,b,d,c,e,f)}var X={},Ib=()=>performance.timeOrigin+performance.now();
|
|
35
|
+
function zb(a,b){if(n)return U(18,1,a,b);X[a]&&(clearTimeout(X[a].id),delete X[a]);if(!b)return 0;var d=setTimeout(()=>{delete X[a];kd(()=>Rc(a,performance.timeOrigin+performance.now()))},b);X[a]={id:d,oc:b};return 0}
|
|
36
|
+
var Y=(a,b,d)=>{var c=(v(),A);b>>>=0;if(0<d){var e=b;d=b+d-1;for(var f=0;f<a.length;++f){var g=a.codePointAt(f);if(127>=g){if(b>=d)break;c[b++>>>0]=g}else if(2047>=g){if(b+1>=d)break;c[b++>>>0]=192|g>>6;c[b++>>>0]=128|g&63}else if(65535>=g){if(b+2>=d)break;c[b++>>>0]=224|g>>12;c[b++>>>0]=128|g>>6&63;c[b++>>>0]=128|g&63}else{if(b+3>=d)break;c[b++>>>0]=240|g>>18;c[b++>>>0]=128|g>>12&63;c[b++>>>0]=128|g>>6&63;c[b++>>>0]=128|g&63;f++}}c[b>>>0]=0;a=b-e}else a=0;return a};
|
|
37
|
+
function Ab(a,b,d,c){a>>>=0;b>>>=0;d>>>=0;c>>>=0;var e=(new Date).getFullYear(),f=(new Date(e,0,1)).getTimezoneOffset();e=(new Date(e,6,1)).getTimezoneOffset();var g=Math.max(f,e);(v(),D)[a>>>2>>>0]=60*g;(v(),C)[b>>>2>>>0]=Number(f!=e);b=l=>{var u=Math.abs(l);return`UTC${0<=l?"-":"+"}${String(Math.floor(u/60)).padStart(2,"0")}${String(u%60).padStart(2,"0")}`};a=b(f);b=b(e);e<f?(Y(a,d,17),Y(b,c,17)):(Y(a,c,17),Y(b,d,17))}var Eb=()=>Date.now(),Dd=1;
|
|
38
|
+
function Bb(a,b,d){d>>>=0;if(!(0<=a&&3>=a))return 28;if(0===a)a=Date.now();else if(Dd)a=performance.timeOrigin+performance.now();else return 52;a=Math.round(1E6*a);(v(),H)[d>>>3>>>0]=BigInt(a);return 0}var Ed=[];function Cb(a,b,d){a>>>=0;b>>>=0;d>>>=0;Ed.length=0;for(var c;c=(v(),A)[b++>>>0];){var e=105!=c;e&=112!=c;d+=e&&d%8?4:0;Ed.push(112==c?(v(),D)[d>>>2>>>0]:106==c?(v(),H)[d>>>3>>>0]:105==c?(v(),C)[d>>>2>>>0]:(v(),G)[d>>>3>>>0]);d+=e?8:4}return yd[a](...Ed)}var Db=()=>{};
|
|
39
|
+
function Fb(a,b){return p(vd(a>>>0,b>>>0))}var Gb=()=>{T+=1;throw"unwind";};function Hb(){return 4294901760}var Jb=()=>m?require("os").cpus().length:navigator.hardwareConcurrency,Z={},Fd=a=>{for(var b=0,d=0;d<a.length;++d){var c=a.charCodeAt(d);127>=c?b++:2047>=c?b+=2:55296<=c&&57343>=c?(b+=4,++d):b+=3}return b},Gd=a=>{var b;return(b=/\bwasm-function\[\d+\]:(0x[0-9a-f]+)/.exec(a))?+b[1]:(b=/:(\d+):\d+(?:\)|$)/.exec(a))?2147483648|+b[1]:0},Hd=a=>{for(var b of a)(a=Gd(b))&&(Z[a]=b)};
|
|
40
|
+
function Mb(){var a=Error().stack.toString().split("\n");"Error"==a[0]&&a.shift();Hd(a);Z.Xb=Gd(a[3]);Z.bc=a;return Z.Xb}function Kb(a){a=Z[a>>>0];if(!a)return 0;var b;if(b=/^\s+at .*\.wasm\.(.*) \(.*\)$/.exec(a))a=b[1];else if(b=/^\s+at (.*) \(.*\)$/.exec(a))a=b[1];else if(b=/^(.+?)@/.exec(a))a=b[1];else return 0;Mc(Kb.Yb??0);b=Fd(a)+1;var d=Nc(b);d&&Y(a,d,b);Kb.Yb=d;return Kb.Yb}
|
|
41
|
+
function Lb(a){a>>>=0;var b=(v(),A).length;if(a<=b||4294901760<a)return!1;for(var d=1;4>=d;d*=2){var c=b*(1+.2/d);c=Math.min(c,a+100663296);a:{c=(Math.min(4294901760,65536*Math.ceil(Math.max(a,c)/65536))-x.buffer.byteLength+65535)/65536|0;try{x.grow(c);qa();var e=1;break a}catch(f){}e=void 0}if(e)return!0}return!1}
|
|
42
|
+
function Nb(a,b,d){a>>>=0;b>>>=0;if(Z.Xb==a)var c=Z.bc;else c=Error().stack.toString().split("\n"),"Error"==c[0]&&c.shift(),Hd(c);for(var e=3;c[e]&&Gd(c[e])!=a;)++e;for(a=0;a<d&&c[a+e];++a)(v(),C)[b+4*a>>>2>>>0]=Gd(c[a+e]);return a}
|
|
43
|
+
var Id={},Kd=()=>{if(!Jd){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:(globalThis.navigator?.language??"C").replace("-","_")+".UTF-8",_:ca||"./this.program"},b;for(b in Id)void 0===Id[b]?delete a[b]:a[b]=Id[b];var d=[];for(b in a)d.push(`${b}=${a[b]}`);Jd=d}return Jd},Jd;function Ob(a,b){if(n)return U(19,1,a,b);a>>>=0;b>>>=0;var d=0,c=0,e;for(e of Kd()){var f=b+d;(v(),D)[a+c>>>2>>>0]=f;d+=Y(e,f,Infinity)+1;c+=4}return 0}
|
|
44
|
+
function Pb(a,b){if(n)return U(20,1,a,b);a>>>=0;b>>>=0;var d=Kd();(v(),D)[a>>>2>>>0]=d.length;a=0;for(var c of d)a+=Fd(c)+1;(v(),D)[b>>>2>>>0]=a;return 0}function Rb(a){return n?U(21,1,a):52}function Sb(a,b,d,c,e){return n?U(22,1,a,b,d,c,e):52}function Tb(a,b,d,c){return n?U(23,1,a,b,d,c):52}function Ub(a,b,d,c){return n?U(24,1,a,b,d,c):70}var Ld=[null,[],[]];
|
|
45
|
+
function Vb(a,b,d,c){if(n)return U(25,1,a,b,d,c);b>>>=0;d>>>=0;c>>>=0;for(var e=0,f=0;f<d;f++){var g=(v(),D)[b>>>2>>>0],l=(v(),D)[b+4>>>2>>>0];b+=8;for(var u=0;u<l;u++){var w=a,y=(v(),A)[g+u>>>0],B=Ld[w];0===y||10===y?((1===w?oa:p)(ud(B)),B.length=0):B.push(y)}e+=l}(v(),D)[c>>>2>>>0]=e;return 0}function Hc(a){return a>>>0}n||gd();n||(x=new WebAssembly.Memory({initial:256,maximum:65536,shared:!0}),qa());h.wasmBinary&&(q=h.wasmBinary);h.stackSave=()=>N();h.stackRestore=a=>M(a);h.stackAlloc=a=>Uc(a);
|
|
46
|
+
h.setValue=function(a,b,d="i8"){d.endsWith("*")&&(d="*");switch(d){case "i1":(v(),z)[a>>>0]=b;break;case "i8":(v(),z)[a>>>0]=b;break;case "i16":(v(),Fa)[a>>>1>>>0]=b;break;case "i32":(v(),C)[a>>>2>>>0]=b;break;case "i64":(v(),H)[a>>>3>>>0]=BigInt(b);break;case "float":(v(),Ga)[a>>>2>>>0]=b;break;case "double":(v(),G)[a>>>3>>>0]=b;break;case "*":(v(),D)[a>>>2>>>0]=b;break;default:J(`invalid type for setValue: ${d}`)}};
|
|
47
|
+
h.getValue=function(a,b="i8"){b.endsWith("*")&&(b="*");switch(b){case "i1":return(v(),z)[a>>>0];case "i8":return(v(),z)[a>>>0];case "i16":return(v(),Fa)[a>>>1>>>0];case "i32":return(v(),C)[a>>>2>>>0];case "i64":return(v(),H)[a>>>3>>>0];case "float":return(v(),Ga)[a>>>2>>>0];case "double":return(v(),G)[a>>>3>>>0];case "*":return(v(),D)[a>>>2>>>0];default:J(`invalid type for getValue: ${b}`)}};h.UTF8ToString=vd;h.stringToUTF8=Y;h.lengthBytesUTF8=Fd;
|
|
48
|
+
var zd=[Ic,fd,sd,ab,bb,cb,db,eb,fb,gb,hb,ib,jb,kb,lb,mb,xb,yb,zb,Ob,Pb,Rb,Sb,Tb,Ub,Vb],yd={1042604:(a,b,d,c,e)=>{if("undefined"==typeof h||!h.Tb)return 1;a=vd(Number(a>>>0));a.startsWith("./")&&(a=a.substring(2));a=h.Tb.get(a);if(!a)return 2;b=Number(b>>>0);d=Number(d>>>0);c=Number(c>>>0);if(b+d>a.byteLength)return 3;try{const f=a.subarray(b,b+d);switch(e){case 0:(v(),A).set(f,c>>>0);break;case 1:h.ic?h.ic(c,f):h.kc(c,f);break;default:return 4}return 0}catch{return 4}},1043428:()=>"undefined"!==typeof wasmOffsetConverter};
|
|
49
|
+
function Qa(){return"undefined"!==typeof wasmOffsetConverter}var Lc,Mc,Nc,za,Ea,Oc,Pc,Qc,Rc,Sc,K,L,Tc,M,Uc,N,Vc,Wc,Xc,Yc,Zc,Pa;function cc(a,b,d,c){var e=N();try{return V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}function bc(a,b,d){var c=N();try{return V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0)}}function sc(a){var b=N();try{V(a)()}catch(d){M(b);if(d!==d+0)throw d;K(1,0)}}function ac(a,b){var d=N();try{return V(a)(b)}catch(c){M(d);if(c!==c+0)throw c;K(1,0)}}
|
|
50
|
+
function uc(a,b,d){var c=N();try{V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0)}}function tc(a,b){var d=N();try{V(a)(b)}catch(c){M(d);if(c!==c+0)throw c;K(1,0)}}function gc(a,b,d,c,e,f,g){var l=N();try{return V(a)(b,d,c,e,f,g)}catch(u){M(l);if(u!==u+0)throw u;K(1,0)}}function yc(a,b,d,c,e,f){var g=N();try{V(a)(b,d,c,e,f)}catch(l){M(g);if(l!==l+0)throw l;K(1,0)}}function wc(a,b,d,c){var e=N();try{V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}
|
|
51
|
+
function xc(a,b,d,c,e){var f=N();try{V(a)(b,d,c,e)}catch(g){M(f);if(g!==g+0)throw g;K(1,0)}}function zc(a,b,d,c,e,f,g){var l=N();try{V(a)(b,d,c,e,f,g)}catch(u){M(l);if(u!==u+0)throw u;K(1,0)}}function Gc(a,b,d,c,e,f,g){var l=N();try{V(a)(b,d,c,e,f,g)}catch(u){M(l);if(u!==u+0)throw u;K(1,0)}}function Fc(a,b,d,c,e,f,g,l){var u=N();try{V(a)(b,d,c,e,f,g,l)}catch(w){M(u);if(w!==w+0)throw w;K(1,0)}}function dc(a,b,d,c,e){var f=N();try{return V(a)(b,d,c,e)}catch(g){M(f);if(g!==g+0)throw g;K(1,0)}}
|
|
52
|
+
function mc(a,b,d){var c=N();try{return V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0)}}function Ac(a,b,d,c,e,f,g,l){var u=N();try{V(a)(b,d,c,e,f,g,l)}catch(w){M(u);if(w!==w+0)throw w;K(1,0)}}function Dc(a,b,d,c,e,f,g,l,u,w,y,B){var E=N();try{V(a)(b,d,c,e,f,g,l,u,w,y,B)}catch(F){M(E);if(F!==F+0)throw F;K(1,0)}}function qc(a,b,d){var c=N();try{return V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0);return 0n}}
|
|
53
|
+
function Bc(a,b,d,c,e,f,g,l,u){var w=N();try{V(a)(b,d,c,e,f,g,l,u)}catch(y){M(w);if(y!==y+0)throw y;K(1,0)}}function $b(a){var b=N();try{return V(a)()}catch(d){M(b);if(d!==d+0)throw d;K(1,0)}}function pc(a,b){var d=N();try{return V(a)(b)}catch(c){M(d);if(c!==c+0)throw c;K(1,0);return 0n}}function nc(a,b,d,c){var e=N();try{return V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}function oc(a){var b=N();try{return V(a)()}catch(d){M(b);if(d!==d+0)throw d;K(1,0);return 0n}}
|
|
54
|
+
function lc(a,b,d,c){var e=N();try{return V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}function kc(a,b,d,c,e){var f=N();try{return V(a)(b,d,c,e)}catch(g){M(f);if(g!==g+0)throw g;K(1,0)}}function jc(a,b,d,c,e,f){var g=N();try{return V(a)(b,d,c,e,f)}catch(l){M(g);if(l!==l+0)throw l;K(1,0)}}function fc(a,b,d,c,e,f){var g=N();try{return V(a)(b,d,c,e,f)}catch(l){M(g);if(l!==l+0)throw l;K(1,0)}}
|
|
55
|
+
function ec(a,b,d,c,e,f){var g=N();try{return V(a)(b,d,c,e,f)}catch(l){M(g);if(l!==l+0)throw l;K(1,0)}}function hc(a,b,d,c,e,f,g,l){var u=N();try{return V(a)(b,d,c,e,f,g,l)}catch(w){M(u);if(w!==w+0)throw w;K(1,0)}}function rc(a,b,d,c,e){var f=N();try{return V(a)(b,d,c,e)}catch(g){M(f);if(g!==g+0)throw g;K(1,0);return 0n}}function Zb(a,b,d,c){var e=N();try{return V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}
|
|
56
|
+
function Xb(a,b,d,c){var e=N();try{return V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}function ic(a,b,d,c,e,f,g,l,u,w,y,B){var E=N();try{return V(a)(b,d,c,e,f,g,l,u,w,y,B)}catch(F){M(E);if(F!==F+0)throw F;K(1,0)}}function Cc(a,b,d,c,e,f,g,l,u,w,y){var B=N();try{V(a)(b,d,c,e,f,g,l,u,w,y)}catch(E){M(B);if(E!==E+0)throw E;K(1,0)}}function Ec(a,b,d,c,e,f,g,l,u,w,y,B,E,F,Md,Nd){var Od=N();try{V(a)(b,d,c,e,f,g,l,u,w,y,B,E,F,Md,Nd)}catch(Ma){M(Od);if(Ma!==Ma+0)throw Ma;K(1,0)}}
|
|
57
|
+
function Yb(a,b,d){var c=N();try{return V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0)}}function Wb(a,b,d){var c=N();try{return V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0)}}function vc(a,b,d,c){var e=N();try{V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}function Jc(){var a=I;a=Object.assign({},a);var b=c=>()=>c()>>>0,d=c=>e=>c(e)>>>0;a.ub=b(a.ub);a.wb=d(a.wb);a.Kb=d(a.Kb);a.Lb=b(a.Lb);a.Pb=d(a.Pb);return a}
|
|
58
|
+
function xa(){if(0<O)P=xa;else if(n)ra?.(h),Ia();else{for(var a=bd;0<a.length;)a.shift()(h);0<O?P=xa:(h.calledRun=!0,pa||(Ia(),ra?.(h)))}}var I;n||(I=await (wa()),xa());h.PTR_SIZE=4;Ha?moduleRtn=h:moduleRtn=new Promise((a,b)=>{ra=a;sa=b});
|
|
59
|
+
;return moduleRtn}export default ortWasmThreaded;var isPthread=globalThis.self?.name?.startsWith("em-pthread");var isNode=globalThis.process?.versions?.node&&globalThis.process?.type!="renderer";if(isNode)isPthread=(await import("worker_threads")).workerData==="em-pthread";isPthread&&ortWasmThreaded();
|