token-goat 2.9.10 → 2.9.11
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 +54 -11
- package/SECURITY.md +17 -19
- package/THIRD_PARTY_NOTICES.md +667 -0
- package/dist/token-goat-chunk-2ZUPQYLO.mjs +3728 -0
- package/dist/{token-goat-chunk-DCYHAUW3.mjs → token-goat-chunk-3ZALKJ23.mjs} +69 -37
- package/dist/{token-goat-chunk-JS44SRAX.mjs → token-goat-chunk-4NZUXC4F.mjs} +3 -2
- package/dist/{token-goat-chunk-VCEK77ED.mjs → token-goat-chunk-AAEYU2U2.mjs} +5307 -6350
- package/dist/{token-goat-chunk-ATVQ6IIT.mjs → token-goat-chunk-FDURVZQD.mjs} +10 -2
- package/dist/{token-goat-chunk-DSHYDU53.mjs → token-goat-chunk-HDL77BN3.mjs} +11 -7
- package/dist/{token-goat-chunk-LYWIRYCF.mjs → token-goat-chunk-LHLQFGWQ.mjs} +1 -1
- package/dist/{token-goat-chunk-YFXFUG3L.mjs → token-goat-chunk-LKOYKSID.mjs} +1275 -655
- package/dist/{token-goat-chunk-ZQODJQTP.mjs → token-goat-chunk-MKITQ5RY.mjs} +354 -180
- package/dist/{token-goat-chunk-7ALFFPJW.mjs → token-goat-chunk-MRZ555B3.mjs} +2699 -2175
- package/dist/{token-goat-chunk-2TJBY5RD.mjs → token-goat-chunk-PJPFOOGM.mjs} +6 -5
- package/dist/{token-goat-chunk-FQD3OB5W.mjs → token-goat-chunk-QCQUIPIP.mjs} +6068 -1687
- package/dist/{token-goat-chunk-PA5UXNOT.mjs → token-goat-chunk-SY7WTZMW.mjs} +5053 -7735
- package/dist/{token-goat-chunk-PXWBHSFB.mjs → token-goat-chunk-T6M7DAW3.mjs} +31 -4
- package/dist/{token-goat-chunk-SLGOIXKF.mjs → token-goat-chunk-V53Z47ZH.mjs} +85 -328
- package/dist/token-goat-chunk-Y5VKNLVD.mjs +5942 -0
- package/dist/token-goat-chunk-YCKCFYTM.mjs +3564 -0
- package/dist/token-goat-hook.mjs +6 -5
- package/dist/token-goat.core.mjs +8 -6
- package/docs/C4_RUNTIME_ARCHITECTURE.md +1 -1
- package/docs/cli.md +4 -1
- package/docs/install.md +131 -11
- package/docs/security.md +2 -0
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ 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 · **
|
|
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
|
|
15
15
|
|
|
16
16
|
**Reduces AI token use/costs by 40–90%, and improves its focus. Fully automated, always online.**
|
|
17
17
|
|
|
@@ -21,7 +21,7 @@ permalink: /
|
|
|
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
|
-
Works with **Claude Code**, **Gemini CLI**, **Qwen Code**, **Codex CLI**, **Aider**, **Cursor**, **Cline**, **Windsurf**, **Copilot CLI**, **Kimi Code**, **Grok CLI** (xAI Grok Build), and OpenCode, plus **pi** ([pi-coding-agent](https://github.com/earendil-works/pi-mono)).
|
|
24
|
+
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)).
|
|
25
25
|
|
|
26
26
|
**Ask your AI to install it fully (give it this GitHub link), or install in one command:**
|
|
27
27
|
|
|
@@ -288,7 +288,7 @@ FAILED tests/test_x.py::test_one
|
|
|
288
288
|
[token-goat: pytest filter compressed 4.8 KiB to 0.1 KiB (97% saved)]
|
|
289
289
|
```
|
|
290
290
|
|
|
291
|
-
Built-in output compression covers
|
|
291
|
+
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`, 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.
|
|
292
292
|
|
|
293
293
|
`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`.
|
|
294
294
|
|
|
@@ -316,7 +316,7 @@ Per-harness setup for Codex, Gemini, Qwen, Kimi, opencode, OpenClaw, pi, Copilot
|
|
|
316
316
|
|
|
317
317
|
## CLI
|
|
318
318
|
|
|
319
|
-
You rarely type these yourself. Installation writes a routing guide into the agent's instructions, and the agent picks the command that answers its question: a surgical read (`read`, `symbol`, `section`, `skeleton`), a search (`semantic`, `refs`), orientation in an unfamiliar repo (`map`, `arch`, `affected`), recall of output it already has (`bash-output`, `web-output`, `mcp-output`), or a bounded reader for a PDF, Word file, slide deck, workbook, SQLite database or image.
|
|
319
|
+
You rarely type these yourself. Installation writes a routing guide into the agent's instructions, and the agent picks the command that answers its question: a surgical read (`read`, `symbol`, `section`, `skeleton`), a search (`semantic`, `refs`), orientation in an unfamiliar repo (`map`, `arch`, `affected`), recall of output it already has (`bash-output`, `web-output`, `mcp-output`), or a bounded reader for a PDF, Word file, slide deck, workbook, SQLite database, HTML document or image.
|
|
320
320
|
|
|
321
321
|
One command is for people working on token-goat rather than for agents: `token-goat bench` replays a
|
|
322
322
|
corpus of captured shell output through the real compression path and reports how much smaller the
|
|
@@ -365,13 +365,56 @@ token-goat handoff-resolve review-notes --full
|
|
|
365
365
|
user-profile `mcp.json` by default (`%APPDATA%\Code\User\mcp.json` on
|
|
366
366
|
Windows, `~/Library/Application Support/Code/User/mcp.json` on macOS,
|
|
367
367
|
`~/.config/Code/User/mcp.json` on Linux) — add `-p`/`--project` for the
|
|
368
|
-
project-local `.vscode/mcp.json` shown above instead.
|
|
369
|
-
|
|
370
|
-
|
|
368
|
+
project-local `.vscode/mcp.json` shown above instead. It also adds a delimited
|
|
369
|
+
routing block, preserving unrelated JSON and user text: to
|
|
370
|
+
`~/.copilot/instructions/token-goat.instructions.md` for the user install (a
|
|
371
|
+
personal instructions file VS Code applies in every workspace, so the folder
|
|
372
|
+
you run it from is left alone), or to `.github/copilot-instructions.md` with
|
|
373
|
+
`-p`. It fails clearly on malformed JSON, and refuses to
|
|
371
374
|
install into one scope if the other scope already has a token-goat-managed
|
|
372
375
|
entry (registering it twice would duplicate its tool schemas in that
|
|
373
|
-
workspace).
|
|
374
|
-
|
|
376
|
+
workspace). It also installs agent hooks in `~/.copilot/hooks/` (or
|
|
377
|
+
`.github/hooks/` with `-p`), the folder VS Code's Copilot agent reads hooks
|
|
378
|
+
from, so token-goat sees the agent's built-in reads, edits, and terminal
|
|
379
|
+
commands. `token-goat uninstall --vscode` (add `-p`/`--project` for the
|
|
380
|
+
project scope) removes only token-goat's server entry, guidance block, and
|
|
381
|
+
hooks, and keeps the hooks if `--copilot` still uses them.
|
|
382
|
+
|
|
383
|
+
**Visual Studio** (2022 17.14 or later, or 2026): `token-goat install --visualstudio`
|
|
384
|
+
adds the same `servers` entry to `%USERPROFILE%\.mcp.json` and a routing block
|
|
385
|
+
to `%USERPROFILE%\copilot-instructions.md` (Visual Studio 2026 reads that
|
|
386
|
+
file). With `-p`/`--project` it writes `.mcp.json` and
|
|
387
|
+
`.github/copilot-instructions.md` in the solution folder instead. Visual Studio
|
|
388
|
+
has no agent hooks, so token-goat works there through its MCP tools and
|
|
389
|
+
instructions only: no read dedup, hints, image shrink, or output folding. Two
|
|
390
|
+
switches in Visual Studio turn it on: the Tools > Options checkbox for custom
|
|
391
|
+
instructions, and the token-goat tools in the chat Tools picker, since new MCP
|
|
392
|
+
tools start disabled. `token-goat uninstall --visualstudio` (add `-p` for the
|
|
393
|
+
project) removes only token-goat's entry and block. See
|
|
394
|
+
[Visual Studio users](docs/install.md#visual-studio-users).
|
|
395
|
+
|
|
396
|
+
**Zed**: `token-goat install --zed` registers token-goat as an MCP context
|
|
397
|
+
server in Zed's `settings.json` (user scope only — Zed has no
|
|
398
|
+
project-local equivalent). Zed's first-party agent has no hooks API at all,
|
|
399
|
+
so this is MCP tools only, the same limits as Visual Studio above: no read
|
|
400
|
+
dedup, hints, image shrink, or output folding. Enable the token-goat server
|
|
401
|
+
under Zed's Agent panel tools list after installing; new MCP servers start
|
|
402
|
+
disabled. `token-goat uninstall --zed` removes the entry and its generated
|
|
403
|
+
shim script. See [Zed users](docs/install.md#zed-users).
|
|
404
|
+
|
|
405
|
+
**Cursor**: `token-goat install --cursor` registers token-goat as an MCP
|
|
406
|
+
server in `~/.cursor/mcp.json` (`-p`/`--project` for
|
|
407
|
+
`<project>/.cursor/mcp.json`). This never touches `~/.cursor/hooks.json`:
|
|
408
|
+
Cursor already imports Claude Code's hooks from `~/.claude/settings.json` by
|
|
409
|
+
default, so a plain `token-goat install` for Claude Code already gets hooks
|
|
410
|
+
running in Cursor too, with no separate Cursor hooks file to maintain or risk
|
|
411
|
+
clobbering. `token-goat uninstall --cursor` removes only the MCP entry. See
|
|
412
|
+
[Cursor users](docs/install.md#cursor-users).
|
|
413
|
+
|
|
414
|
+
**JetBrains** (WebStorm, IntelliJ, PyCharm, Rider, PhpStorm): no integration
|
|
415
|
+
today — no hooks, no MCP, no terminal filter. See
|
|
416
|
+
[JetBrains IDEs users](docs/install.md#jetbrains-ides-webstorm-intellij-pycharm-rider-phpstorm-users)
|
|
417
|
+
for why and what a Copilot-for-JetBrains user might already get for free.
|
|
375
418
|
|
|
376
419
|
The optional source-controlled extension lives in `vscode-extension/`. Build
|
|
377
420
|
and install its VSIX manually; `--vscode` intentionally does not copy or
|
|
@@ -417,7 +460,7 @@ never drift on where `mcp.json` lives or what key name it looks for.
|
|
|
417
460
|
}
|
|
418
461
|
```
|
|
419
462
|
|
|
420
|
-
**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.
|
|
463
|
+
**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.
|
|
421
464
|
|
|
422
465
|
## What gets installed?
|
|
423
466
|
|
|
@@ -664,7 +707,7 @@ Token-Goat is licensed under the PolyForm Noncommercial License 1.0.0. See the L
|
|
|
664
707
|
|
|
665
708
|
Individual developers may install and use Token-Goat on their own machines for personal productivity without a commercial license, provided the use does not involve providing Token-Goat as a service to others, incorporating it into a commercial product or platform, or deploying it as shared infrastructure across a team or organization. Employment at a for-profit company does not by itself make use commercial — but if your employer is the primary beneficiary of the deployment, a commercial license applies. When in doubt, email token-goat@dfkhelper.com.
|
|
666
709
|
|
|
667
|
-
Commercial use is reserved. That means copying or incorporating this codebase into a product, charging for access to it, or running it as shared infrastructure across a team at a for-profit company. Commercial licensing: token-goat@dfkhelper.com.
|
|
710
|
+
Commercial use is reserved. That means copying or incorporating this codebase into a product, charging for access to it, or running it as shared infrastructure across a team at a for-profit company. Commercial licenses have been issued and are agreed per organization by email; there is no price list or self-serve purchase. Commercial licensing: token-goat@dfkhelper.com.
|
|
668
711
|
|
|
669
712
|
Copyright (c) 2026 DFK Helper LLC.
|
|
670
713
|
|
package/SECURITY.md
CHANGED
|
@@ -41,13 +41,13 @@ 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
|
|
44
|
+
`npm audit` reports Token-Goat clean for anyone who installs it, and that has only been true of a default install since the embedding model became opt-in. This repository's own tree, development dependencies included, is not: two moderate advisories currently sit in dev-only transitive dependencies (`adm-zip` under `onnxruntime-node`, `hono` under `@modelcontextprotocol/sdk`), both behind Dependabot's cooldown rather than bumped ad hoc -- see [`.github/dependabot.yml`](.github/dependabot.yml) for why a plain `npm update` isn't the fix. Neither ships to an installer: both packages drop out the moment `--omit=dev` is added, which is what the next two rows scan. All three numbers below are reproducible with the commands shown. The one thing that is not clean in a default install is the opt-in package itself, 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` | 2 moderate, development dependencies only (`adm-zip`, `hono`; see above) |
|
|
49
49
|
| an install without optional packages | `npm install --omit=optional token-goat` then `npm audit --omit=dev --omit=optional` | clean, 2 packages |
|
|
50
|
-
| a default install | `npm install token-goat` then `npm audit --omit=dev` | clean,
|
|
50
|
+
| a default install | `npm install token-goat` then `npm audit --omit=dev` | clean, 62 packages |
|
|
51
51
|
|
|
52
52
|
The repository carries an `overrides` block in [`package.json`](package.json) that pins six packages to patched versions, and **npm applies `overrides` only in the root project**, so those pins do not travel to anyone who installs Token-Goat as a dependency. That distinction used to matter a great deal, because a clean repository scan was standing in for an install that was not clean. It decides one thing now, and the section on the embedding runtime below says which. Otherwise the packages those pins were protecting against are not in a consumer's tree at all, whether or not the pins travel; the block stays because the development tree still resolves them.
|
|
53
53
|
|
|
@@ -61,7 +61,7 @@ The embedding runtime is opt-in, the same way the model was. `semantic` still wo
|
|
|
61
61
|
npm install -g onnxruntime-node # drop -g if token-goat is a project dependency
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
**That command is the one thing on this page that is not clean, and the number is two.** `onnxruntime-node` depends 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. This repository pins `adm-zip` past it in `overrides`, which
|
|
64
|
+
**That command is the one thing on this page that is not clean, and the number is two.** `onnxruntime-node` depends 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. This repository pins `adm-zip` past it in `overrides`, which used to be why the repository row above was clean. It no longer is: a second, unrelated `adm-zip` advisory ([GHSA-vwc7-r8mq-g2x9](https://github.com/advisories/GHSA-vwc7-r8mq-g2x9), extraction following a destination symlink) reaches into the patched version itself, so the `^0.6.0` override no longer clears everything `adm-zip` carries -- that is the `adm-zip` finding the repository row above now discloses, alongside `hono`'s. By the rule stated above the override does not travel regardless: run the command and you will resolve the 0.5 line and see the original ZIP-bomb finding twice. If that matters where you are, the fix is an `overrides` entry of your own:
|
|
65
65
|
|
|
66
66
|
```json
|
|
67
67
|
{ "overrides": { "adm-zip": "^0.6.0" } }
|
|
@@ -73,7 +73,7 @@ Nothing else is needed. The index notices on its own: files skipped while the mo
|
|
|
73
73
|
|
|
74
74
|
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
75
|
|
|
76
|
-
The old model had cost something before any of this, through the nested `sharp` it carried. That `sharp` ships its own libvips binaries, and loading the model eagerly put them ahead of Token-Goat
|
|
76
|
+
The old model had cost something before any of this, through the nested `sharp` it carried. That `sharp` ships its own libvips binaries, and loading the model eagerly put them ahead of the `sharp` Token-Goat installed for itself at the time in the Windows DLL search order, which broke image shrinking with `ERR_DLOPEN_FAILED` while `sharp` loaded perfectly well on its own. Neither package reaches an install today: image shrinking is pure TypeScript in the bundle, and `sharp` is a development dependency. `onnxruntime-node` carries no `sharp` and no libvips, so that particular collision cannot recur -- but the load is still deferred until something actually asks to embed, in [`src/embed_model.ts`](src/embed_model.ts), because it is a native addon whose DLLs have no business being loaded into every hook invocation that never embeds anything.
|
|
77
77
|
|
|
78
78
|
`npm install --omit=optional` remains available and gives a smaller install still, at 2 packages -- Token-Goat and [`jsonc-parser`](https://www.npmjs.com/package/jsonc-parser), and nothing else. Every command starts either way; the ones that need a package you skipped say so. The `xlsx-*`, `docx-*` and `pptx-*` commands report that fflate is not installed rather than failing oddly, and `zip-list`/`zip-read` do the same.
|
|
79
79
|
|
|
@@ -87,7 +87,7 @@ The old model had cost something before any of this, through the nested `sharp`
|
|
|
87
87
|
|
|
88
88
|
`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
89
|
|
|
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-
|
|
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 has no prebuilt binary in it at all, so 2 is 2 everywhere.
|
|
91
91
|
|
|
92
92
|
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
93
|
|
|
@@ -95,7 +95,7 @@ One half of that drift is checked rather than trusted. [`tests/guards/dependency
|
|
|
95
95
|
|
|
96
96
|
Five more packages were in `dependencies` for the same reason and have moved the same way: `commander`, `csv-parse`, `js-yaml`, `smol-toml` and `zod`. esbuild inlines each one into the bundle, and the published bundle resolves none of them, so a consumer was downloading code the artifact already carried. Moving them takes an install without optional packages from 46 packages to 40. `jsonc-parser` stays, because the bundle really does load it at run time: it is reached through `createRequire` rather than an import esbuild can inline. `zod` is the largest of the five on disk, and when that move was made it saved least in practice, because `@modelcontextprotocol/sdk` and `puppeteer-core` both depended on it and a default install still got it from them. Neither is true any more: the puppeteer-core major bump dropped its `zod` dependency, and the MCP SDK is a development dependency now for the reason below. A default install carries no copy of `zod` at all.
|
|
97
97
|
|
|
98
|
-
Direct dependencies with a forward patch are kept current rather than pinned: `
|
|
98
|
+
Direct dependencies with a forward patch are kept current rather than pinned: `puppeteer-core` was moved across a major version to clear its advisories, and `sharp` was moved the same way while it was still one. `sharp` is a development dependency now, which is the larger change: nothing under `src/` imports it, the image pipeline is pure TypeScript that esbuild inlines into the bundle, and so a default install no longer downloads it or the libvips binaries behind it. The tests still use it, as an independent encoder to check the bundled one against, so it is kept current there for the repository's own `npm audit`.
|
|
99
99
|
|
|
100
100
|
For a scanner that ingests a bill of materials rather than a lockfile, `npm run sbom` writes CycloneDX 1.5 to stdout.
|
|
101
101
|
|
|
@@ -122,9 +122,9 @@ Token-Goat is source-available under the PolyForm Noncommercial License 1.0.0. S
|
|
|
122
122
|
|
|
123
123
|
Every production dependency is permissively licensed, but a scan does not read it that way on its
|
|
124
124
|
own. Counted from `package-lock.json`, which lists the packages for every platform rather than only
|
|
125
|
-
the ones this machine installed,
|
|
126
|
-
cannot resolve, and
|
|
127
|
-
with `npm install --omit=optional token-goat` and not one of them is present.
|
|
125
|
+
the ones this machine installed, 6 entries need a human answer: all 6 declare a license a scanner
|
|
126
|
+
cannot resolve, and none carries a copyleft term. All 6 arrive through optional dependencies.
|
|
127
|
+
Install with `npm install --omit=optional token-goat` and not one of them is present.
|
|
128
128
|
|
|
129
129
|
**Declarations a scanner cannot resolve.** One remains, and it is an upstream mistake of the same
|
|
130
130
|
kind this project made in its own manifest and fixed: `MIT OR Apache` is not a valid expression,
|
|
@@ -136,15 +136,13 @@ while actually granting Apache-2.0. It arrived through `@xenova/transformers` an
|
|
|
136
136
|
| --- | --- | --- | --- |
|
|
137
137
|
| `sqlite-vec` and its 5 platform packages | `MIT OR Apache` | MIT or Apache-2.0, your choice | direct optional dependency |
|
|
138
138
|
|
|
139
|
-
**Copyleft terms.** Two families
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
`sharp` is optional: it powers image shrinking. `jszip` used to be listed here too; it arrived
|
|
147
|
-
through `exceljs`, which is no longer a dependency a consumer installs.
|
|
139
|
+
**Copyleft terms.** None reach an install. Two families used to be here, and both left at once:
|
|
140
|
+
`@img/sharp-libvips-<platform>` (10 packages, `LGPL-3.0-or-later`, the libvips shared library) and
|
|
141
|
+
`@img/sharp-<platform>` (4 packages, `Apache-2.0 AND LGPL-3.0-or-later`, `sharp` itself over that
|
|
142
|
+
same libvips). They arrived through `sharp`, which is a development dependency now: nothing under
|
|
143
|
+
`src/` imports it, image shrinking is pure TypeScript inlined into the bundle, and so no libvips
|
|
144
|
+
is downloaded by an install at all. `jszip` used to be listed here too; it arrived through
|
|
145
|
+
`exceljs`, which is no longer a dependency a consumer installs.
|
|
148
146
|
|
|
149
147
|
**Three packages with no license at all used to be here.** `buffers@0.1.1` and `chainsaw@0.1.0`
|
|
150
148
|
shipped with neither a `license` field nor a license file, and `traverse@0.3.9` had the file but
|