tanuki-context 0.4.0 → 0.4.1
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 +71 -0
- package/dist/agent.js +1 -1
- package/dist/cli.js +1 -1
- package/package.json +2 -1
- package/skills/tanuki-context/SKILL.md +60 -0
package/README.md
CHANGED
|
@@ -73,6 +73,63 @@ No AI client at all, just curious what it would save you:
|
|
|
73
73
|
npx tanuki-context estimate some-big-file.log 0
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
+
## Installing it: two ways, same tools
|
|
77
|
+
|
|
78
|
+
**npm (the default).** `npx -y tanuki-context` downloads a 0.98 MB tarball
|
|
79
|
+
with zero dependencies and starts the MCP server on stdio. That is the
|
|
80
|
+
whole install. Your client spawns one short-lived process per session
|
|
81
|
+
(35 ms to first response under node, 27 under bun); the model calls the
|
|
82
|
+
seven `tanuki_*` tools; pages come back inline as PNG blocks. On disk it
|
|
83
|
+
touches exactly two places, both yours to delete: `~/.tanuki/stash` for
|
|
84
|
+
stashed text and `~/.pxpipe/events.jsonl` for the savings log.
|
|
85
|
+
|
|
86
|
+
**cargo (the static binary).** No node at all:
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
cargo install --git https://github.com/Osyna/tanuki-context --branch rust
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
One 5.7 MB binary, same seven tools, same numbers — a 103-check parity
|
|
93
|
+
harness holds the two engines to byte-identical JSON and pixel-identical
|
|
94
|
+
PNGs on every release. It spawns in 0.4 ms and idles at 3.8 MB RSS, which
|
|
95
|
+
matters when every session forks its own server. Point any client config
|
|
96
|
+
at `"command": "tanuki-context"` instead of the npx line and nothing else
|
|
97
|
+
changes.
|
|
98
|
+
|
|
99
|
+
## Should you use it at all?
|
|
100
|
+
|
|
101
|
+
Reach for tanuki when:
|
|
102
|
+
|
|
103
|
+
- **bulky text is about to enter context** — logs, build output, command
|
|
104
|
+
results, long docs, anything past roughly 2,000 tokens;
|
|
105
|
+
- **an agent keeps re-reading big files** — the proxy dedupes exact
|
|
106
|
+
repeats, and stash turns re-reads into cheap fetches;
|
|
107
|
+
- **a long session is running out of context** — pages carry ~4x more
|
|
108
|
+
characters per token, and the proxy can image old bulky turns in place;
|
|
109
|
+
- **you cannot change the client** — the proxy mode needs only a base-URL
|
|
110
|
+
export.
|
|
111
|
+
|
|
112
|
+
Leave it alone when:
|
|
113
|
+
|
|
114
|
+
- **your model cannot read images.** Hard requirement. Everything here
|
|
115
|
+
assumes a vision-capable reader (any current Claude model qualifies).
|
|
116
|
+
- **the exact bytes must survive a round trip** — secrets, hashes, code
|
|
117
|
+
the model is about to edit. Rendering is exact, but model read-back of
|
|
118
|
+
dense random strings is not guaranteed (pxpipe measured 13/15 on
|
|
119
|
+
12-char hex). Keep those in text.
|
|
120
|
+
- **the content is small.** A 500-token snippet is not worth a modality
|
|
121
|
+
switch even when the math technically favors it; `estimate` and the
|
|
122
|
+
proxy gate both say so.
|
|
123
|
+
- **your bill is output-dominated.** tanuki cuts input tokens only. If
|
|
124
|
+
most of your spend is the model's own output, fix that first.
|
|
125
|
+
- **you are not on Anthropic pricing.** Verdicts use Anthropic's
|
|
126
|
+
28-px patch grid. OpenAI and Google price images differently (tiles,
|
|
127
|
+
fixed per-image rates), so every verdict needs re-deriving before you
|
|
128
|
+
trust it there.
|
|
129
|
+
- **the bulk is already prompt-cached.** Cache reads cost a tenth of
|
|
130
|
+
fresh input; imaging content that was riding the cache can be a net
|
|
131
|
+
loss. The proxy never touches `cache_control` blocks for this reason.
|
|
132
|
+
|
|
76
133
|
## The three ways to run it
|
|
77
134
|
|
|
78
135
|
**Explicit (MCP tools) — the default and the recommendation.** Your AI gets
|
|
@@ -461,6 +518,20 @@ pi install npm:tanuki-context
|
|
|
461
518
|
claude mcp add tanuki-context -- npx -y tanuki-context
|
|
462
519
|
```
|
|
463
520
|
|
|
521
|
+
The package also ships a **skill** — a short instruction file that teaches
|
|
522
|
+
the model the whole workflow (estimate first, read `recommend`, stash big
|
|
523
|
+
references, the page decode grammar, the do-nots) without you prompting
|
|
524
|
+
any of it. Install it once and the tools get used correctly on their own:
|
|
525
|
+
|
|
526
|
+
```
|
|
527
|
+
npm i -g tanuki-context # or any install that gives you the package on disk
|
|
528
|
+
cp -r "$(npm root -g)/tanuki-context/skills/tanuki-context" ~/.claude/skills/
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
From a checkout it is just `cp -r skills/tanuki-context ~/.claude/skills/`.
|
|
532
|
+
The same file works for any skill-aware harness (OMP picks it up from the
|
|
533
|
+
same directory).
|
|
534
|
+
|
|
464
535
|
**Rust instead of Node?** Same pipeline, same numbers, one 5.7 MB static
|
|
465
536
|
binary:
|
|
466
537
|
|
package/dist/agent.js
CHANGED
|
@@ -78,7 +78,7 @@ function oJ(){let J=cJ.env.TANUKI_STASH;if(J!==void 0&&J!=="")return J;return`${
|
|
|
78
78
|
//! tanuki-context estimate <file> [level] [--distill]
|
|
79
79
|
//! tanuki-context render <file> [level] [outdir]
|
|
80
80
|
//! tanuki-context proxy [--port N] [--upstream URL] [knobs] (implicit mode)
|
|
81
|
-
var rJ="0.4.
|
|
81
|
+
var rJ="0.4.1",RJ=6;function BZ(J,Q){let Z=Math.min(J.length,Q.length),$=0;while($<Z&&J.charCodeAt($)===Q.charCodeAt($))$++;if($>=Z)return J.length-Q.length;return J.codePointAt($)-Q.codePointAt($)}function L(J,Q,Z=""){if(J===null||J===void 0)return"null";if(J instanceof YJ){let z=J.value;return Number.isFinite(z)&&Number.isInteger(z)?z.toFixed(1):String(z)}let $=typeof J;if($==="string")return JSON.stringify(J);if($==="number"||$==="boolean")return String(J);if(Array.isArray(J)){if(J.length===0)return"[]";if(!Q){let O="[";for(let B=0;B<J.length;B++){if(B>0)O+=",";O+=L(J[B],!1)}return O+"]"}let z=Z+" ",K=`[
|
|
82
82
|
`;for(let O=0;O<J.length;O++){if(O>0)K+=`,
|
|
83
83
|
`;K+=z+L(J[O],!0,z)}return K+`
|
|
84
84
|
`+Z+"]"}let V=J,G=Object.keys(V).sort(BZ);if(G.length===0)return"{}";if(!Q){let z="{";for(let K=0;K<G.length;K++){if(K>0)z+=",";z+=JSON.stringify(G[K])+":"+L(V[G[K]],!1)}return z+"}"}let Y=Z+" ",H=`{
|
package/dist/cli.js
CHANGED
|
@@ -84,7 +84,7 @@ function zQ(){let J=VQ.env.TANUKI_STASH;if(J!==void 0&&J!=="")return J;return`${
|
|
|
84
84
|
//! tanuki-context estimate <file> [level] [--distill]
|
|
85
85
|
//! tanuki-context render <file> [level] [outdir]
|
|
86
86
|
//! tanuki-context proxy [--port N] [--upstream URL] [knobs] (implicit mode)
|
|
87
|
-
var TZ="0.4.
|
|
87
|
+
var TZ="0.4.1",wJ=6,bJ=8000;function LZ(J,Q){let Z=Math.min(J.length,Q.length),$=0;while($<Z&&J.charCodeAt($)===Q.charCodeAt($))$++;if($>=Z)return J.length-Q.length;return J.codePointAt($)-Q.codePointAt($)}function P(J,Q,Z=""){if(J===null||J===void 0)return"null";if(J instanceof ZJ){let H=J.value;return Number.isFinite(H)&&Number.isInteger(H)?H.toFixed(1):String(H)}let $=typeof J;if($==="string")return JSON.stringify(J);if($==="number"||$==="boolean")return String(J);if(Array.isArray(J)){if(J.length===0)return"[]";if(!Q){let B="[";for(let U=0;U<J.length;U++){if(U>0)B+=",";B+=P(J[U],!1)}return B+"]"}let H=Z+" ",K=`[
|
|
88
88
|
`;for(let B=0;B<J.length;B++){if(B>0)K+=`,
|
|
89
89
|
`;K+=H+P(J[B],!0,H)}return K+`
|
|
90
90
|
`+Z+"]"}let V=J,z=Object.keys(V).sort(LZ);if(z.length===0)return"{}";if(!Q){let H="{";for(let K=0;K<z.length;K++){if(K>0)H+=",";H+=JSON.stringify(z[K])+":"+P(V[z[K]],!1)}return H+"}"}let G=Z+" ",Y=`{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tanuki-context",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Token-cutting context pipeline as an MCP server: distill logs, compress text, render dense PNG pages (pxpipe imaging engine). Zero dependencies.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"files": [
|
|
18
18
|
"dist",
|
|
19
19
|
"assets",
|
|
20
|
+
"skills",
|
|
20
21
|
"README.md",
|
|
21
22
|
"LICENSE"
|
|
22
23
|
],
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tanuki-context
|
|
3
|
+
version: 0.4.1
|
|
4
|
+
description: |
|
|
5
|
+
Cut input-token cost by rendering bulky text (logs, command output, long
|
|
6
|
+
docs) as dense PNG pages the model reads at a fraction of the price, or by
|
|
7
|
+
parking it outside context and fetching slices. Use when pasting or reading
|
|
8
|
+
anything over ~2,000 tokens of logs, build output, or documents; when a
|
|
9
|
+
session is close to its context limit; or before re-reading a large file.
|
|
10
|
+
Requires the tanuki-context MCP server (tanuki_* tools) and a
|
|
11
|
+
vision-capable model.
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# tanuki-context: pay pixels, not tokens
|
|
15
|
+
|
|
16
|
+
Text costs ~1 token per 4 characters. A dense PNG page costs a fixed 1,456
|
|
17
|
+
tokens and carries up to 28,080 characters. The tanuki_* tools exploit that
|
|
18
|
+
gap deterministically: nothing is summarized by a model, errors stay
|
|
19
|
+
verbatim, and every drop is counted.
|
|
20
|
+
|
|
21
|
+
## Workflow
|
|
22
|
+
|
|
23
|
+
1. **Estimate first, always.** `tanuki_estimate { text }` is instant and
|
|
24
|
+
never renders pixels. Read two things from the answer:
|
|
25
|
+
- `recommend` - the cheapest reversible knob set (pack/codebook), priced.
|
|
26
|
+
- `recommend.withDistill` - the log route (repeats collapsed with exact
|
|
27
|
+
counts). Cheaper, and honest for logs; do not use it on source code.
|
|
28
|
+
2. **Act on the verdict.**
|
|
29
|
+
- `"PIPELINE cheaper"` and you need the content in front of you ->
|
|
30
|
+
`tanuki_render` with the recommended knobs. Use the returned pages
|
|
31
|
+
instead of pasting the text.
|
|
32
|
+
- You only need parts of it, now or later -> `tanuki_stash { text }`
|
|
33
|
+
(returns a ~300-token map + id), then `tanuki_fetch { id, query }` or
|
|
34
|
+
`{ id, lines: "a-b" }`. Big slices arrive as pages automatically.
|
|
35
|
+
- `"TEXT cheaper"` -> just use the text. Small inputs are not worth an
|
|
36
|
+
image even when the math technically favors one.
|
|
37
|
+
3. **For noisy logs**, add `distill: true` (and `query: "regex"` for a
|
|
38
|
+
slice). Error/warn/fail lines survive verbatim; repeats become one
|
|
39
|
+
exemplar plus an exact xN count.
|
|
40
|
+
4. **Shell commands with chatty output**: run them as
|
|
41
|
+
`tanuki-context run -- <cmd>` instead of reading the firehose. Exit code
|
|
42
|
+
passes through; the full capture is stashed and fetchable.
|
|
43
|
+
|
|
44
|
+
## Reading the pages
|
|
45
|
+
|
|
46
|
+
`↵` = original newline · `→` = tab · `⇥N` = N leading spaces · a trailing
|
|
47
|
+
`·legend·` line maps codebook sigils back to full tokens · `[U+XXXX]` = a
|
|
48
|
+
codepoint the atlas has no glyph for · `[×N similar]` = N near-identical
|
|
49
|
+
lines collapsed here.
|
|
50
|
+
|
|
51
|
+
## Do not
|
|
52
|
+
|
|
53
|
+
- Do not image content whose exact bytes you must retype later (secrets,
|
|
54
|
+
hashes, code you are about to edit). Rendering is exact; model read-back
|
|
55
|
+
of dense hex is not guaranteed.
|
|
56
|
+
- Do not use `font: "tiny"` or ladder levels 2-4 on anything you may need
|
|
57
|
+
to quote. Tiny is a 99.7%-read-back trade; levels 2-4 reword prose.
|
|
58
|
+
- Do not use `withDistill` numbers on source code or docs you want intact -
|
|
59
|
+
distill collapses similar-looking lines.
|
|
60
|
+
- Do not probe knob combinations by hand; `recommend` already priced them.
|