@tokmizer/plugin 0.9.56 → 0.9.58
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/.claude-plugin/plugin.json +1 -1
- package/README.md +168 -9
- package/agent-plugins/amp.js +38 -0
- package/agent-plugins/hermes/__init__.py +39 -0
- package/agent-plugins/hermes/plugin.yaml +5 -0
- package/agent-plugins/kilo.js +40 -0
- package/agent-plugins/omp.js +32 -0
- package/agent-plugins/openclaw/index.js +39 -0
- package/agent-plugins/openclaw/openclaw.plugin.json +12 -0
- package/agent-plugins/openclaw/package.json +11 -0
- package/agent-plugins/opencode.js +40 -0
- package/agent-plugins/pi.js +30 -0
- package/codex-plugin/plugin.json +1 -1
- package/command-templates/tkr-gain.md +7 -2
- package/command-templates/tkr-link.md +1 -1
- package/command-templates/tkr-status.md +5 -3
- package/command-templates/tkr-telemetry.md +3 -3
- package/command-templates/tkr-unlink.md +2 -2
- package/dist/bin/tkr-agent-hook.js +11 -0
- package/dist/bin/tkr-codex-hook.js +131 -40
- package/dist/bin/tkr-copilot-hook.js +11 -0
- package/dist/bin/tkr-crush-hook.js +11 -0
- package/dist/bin/tkr-cursor-hook.js +11 -0
- package/dist/bin/tkr-daemon.js +161 -55
- package/dist/bin/tkr-droid-hook.js +11 -0
- package/dist/bin/tkr-exec +135 -42
- package/dist/bin/tkr-exec.js +135 -42
- package/dist/bin/tkr-gemini-hook.js +11 -0
- package/dist/bin/tkr-grok-hook.js +11 -0
- package/dist/bin/tkr-junie-hook.js +11 -0
- package/dist/bin/tkr-processor.js +162 -0
- package/dist/bin/tkr-qwen-hook.js +11 -0
- package/dist/bin/tkr-shim.js +131 -38
- package/dist/bin/tkr-trae-hook.js +11 -0
- package/dist/bin/tkr-zcode-hook.js +11 -0
- package/dist/bin/tkr.js +356 -152
- package/dist/hooks-host/post-tool-use.js +144 -48
- package/dist/hooks-host/pre-tool-use.js +8 -7
- package/dist/hooks-host/reducer-prompt-submit.js +1 -1
- package/dist/hooks-host/reducer-session-start.js +1 -1
- package/dist/hooks-host/reducer-stop.js +25 -16
- package/dist/hooks-host/session-recap.js +4 -3
- package/dist/index.js +125 -39
- package/dist/native/manifest.json +18 -8
- package/dist/native/single.json +38 -0
- package/dist/native/tkr-exec-darwin-arm64 +0 -0
- package/dist/native/tkr-exec-darwin-x64 +0 -0
- package/dist/native/tkr-exec-linux-arm64 +0 -0
- package/dist/native/tkr-exec-linux-x64 +0 -0
- package/dist/native/tkr-exec-win32-arm64.exe +0 -0
- package/dist/native/tkr-exec-win32-x64.exe +0 -0
- package/hooks/on-session-start.d.mts +1 -0
- package/hooks/on-session-start.mjs +25 -8
- package/package.json +24 -2
- package/scripts/README-INSTALL.md +13 -5
- package/scripts/install-mac-linux.sh +72 -6
- package/scripts/install-native.mjs +164 -25
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ In Claude Code:
|
|
|
13
13
|
/plugin install tokmizer@tokmizer
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
Then restart Claude Code once, hooks only load at startup. Verify with `/tkr-status`, you should see
|
|
16
|
+
Then restart Claude Code once, hooks only load at startup. Verify with `/tkr-status`, you should see Status active.
|
|
17
17
|
|
|
18
18
|
Any other tool (universal shell-shim):
|
|
19
19
|
|
|
@@ -38,6 +38,59 @@ tkr setup-codex
|
|
|
38
38
|
|
|
39
39
|
Restart Codex, then approve the hook in `/hooks`.
|
|
40
40
|
|
|
41
|
+
Cursor or Gemini CLI, after installing with npm or Homebrew:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
tkr setup-cursor
|
|
45
|
+
tkr setup-gemini
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`tkr setup-cursor` adds a `preToolUse` hook to `~/.cursor/hooks.json`; `tkr setup-gemini` adds a `BeforeTool` hook to `~/.gemini/settings.json`. Each hook routes the agent's shell commands through Tokmizer before they run, keeps your other hooks and settings, and saves a `.tkr-bak` copy the first time it edits the file. Remove either with `--remove`. Cursor's `afterShellExecution` and Gemini's `AfterTool` events cannot replace command output, so these hooks rewrite the command itself.
|
|
49
|
+
|
|
50
|
+
Other agents with plugin or hook support:
|
|
51
|
+
|
|
52
|
+
| Agent | Command | What it installs |
|
|
53
|
+
| --- | --- | --- |
|
|
54
|
+
| OpenCode | `tkr setup-opencode` | plugin `~/.config/opencode/plugins/tokmizer.js` |
|
|
55
|
+
| Kilo Code (CLI and VS Code extension) | `tkr setup-kilo` | plugin `~/.config/kilo/plugin/tokmizer.js` |
|
|
56
|
+
| Amp | `tkr setup-amp` | plugin `~/.config/amp/plugins/tokmizer.js` |
|
|
57
|
+
| Mistral Vibe | `tkr setup-vibe` | `pre_tool` hook in `~/.vibe/hooks.toml` |
|
|
58
|
+
| Antigravity | `tkr setup-antigravity` | `PreToolUse` hook in `~/.gemini/config/hooks.json` |
|
|
59
|
+
| OpenClaw | `tkr setup-openclaw` | plugin `~/.openclaw/extensions/tokmizer/`, then `openclaw plugins enable tokmizer` |
|
|
60
|
+
| Pi | `tkr setup-pi` | extension `~/.pi/agent/extensions/tokmizer.js` |
|
|
61
|
+
| Oh My Pi | `tkr setup-omp` | extension `~/.omp/agent/extensions/tokmizer.js` |
|
|
62
|
+
| Hermes | `tkr setup-hermes` | plugin `~/.hermes/plugins/tokmizer/`, then `hermes plugins enable tokmizer` (Hermes v2026.8.16 or newer) |
|
|
63
|
+
|
|
64
|
+
Each plugin asks `tkr rewrite` for the Tokmizer form of a shell command just before the agent runs it. If `tkr` is missing, slow or fails, the command runs as typed. `XDG_CONFIG_HOME`, `VIBE_HOME`, `PI_CODING_AGENT_DIR` and `HERMES_HOME` are respected. Run the same command with `--remove` to take it out; your other plugins, hooks and settings are kept.
|
|
65
|
+
|
|
66
|
+
GitHub Copilot, Factory Droid, Trae, Qwen Code, Crush, Junie CLI, ZCode or Grok Build, after installing with npm or Homebrew:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
tkr setup-copilot
|
|
70
|
+
tkr setup-droid
|
|
71
|
+
tkr setup-trae
|
|
72
|
+
tkr setup-qwen
|
|
73
|
+
tkr setup-crush
|
|
74
|
+
tkr setup-junie
|
|
75
|
+
tkr setup-zcode
|
|
76
|
+
tkr setup-grok
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
| Command | Agent | File it edits |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| `tkr setup-copilot` | Copilot in VS Code and Copilot CLI | `~/.copilot/hooks/tokmizer.json` (or `$COPILOT_HOME/hooks/`) |
|
|
82
|
+
| `tkr setup-droid` | Factory Droid | `~/.factory/hooks.json`, or `~/.factory/settings.json` when your own `PreToolUse` hooks live there |
|
|
83
|
+
| `tkr setup-trae` | Trae | `~/.trae/hooks.json`, plus `~/.trae-cn/hooks.json` when Trae CN is installed |
|
|
84
|
+
| `tkr setup-qwen` | Qwen Code | `~/.qwen/settings.json` (or `$QWEN_HOME`) |
|
|
85
|
+
| `tkr setup-crush` | Crush | `~/.config/crush/crush.json` (or `$XDG_CONFIG_HOME/crush/`) |
|
|
86
|
+
| `tkr setup-junie` | Junie CLI | `~/.junie/config.json` |
|
|
87
|
+
| `tkr setup-zcode` | ZCode | `~/.zcode/cli/config.json` (`hooks.events.PreToolUse`) |
|
|
88
|
+
| `tkr setup-grok` | Grok Build 1.0.4 or newer | `~/.grok/hooks/tokmizer.json` |
|
|
89
|
+
|
|
90
|
+
Each command adds one `PreToolUse` hook for the agent's shell tool. It rewrites the command before it runs, never approves it: the agent keeps asking for permission as usual. Your other hooks and settings stay as they are, a `.tkr-bak` copy is saved the first time a file is edited, and `--remove` takes the hook out again. Restart the agent after setup. Crush still reads `crush.json` but now prefers `crushrc`; a `crush.json` with comments is left untouched and reported.
|
|
91
|
+
|
|
92
|
+
Permission rules stay in force. Agents match their allow, ask and deny rules against the command text, so Tokmizer leaves a command untouched whenever one of your deny or ask rules matches it. Tokmizer reads those rules for Claude Code (`permissions.deny` and `permissions.ask` in user, project, local and managed settings), OpenCode (`permission` in `opencode.json`), Cursor CLI (`permissions.deny`), Gemini CLI (policy files and `tools.exclude`) and Antigravity CLI (`permissions.deny` and `permissions.ask`). For the other agents, and on top of the Cursor, Gemini and Antigravity rules, only inspection, build and test commands (`cat`, `rg`, `git log`, `npm test`, `cargo build` and similar; inspection only for Codex) are routed; anything else, such as `git push` or `rm`, runs exactly as typed. If a settings file cannot be read, nothing is routed.
|
|
93
|
+
|
|
41
94
|
Homebrew:
|
|
42
95
|
|
|
43
96
|
```bash
|
|
@@ -63,16 +116,16 @@ In Claude Code:
|
|
|
63
116
|
- `/tkr-link tokmizer_yourkey` connects an optional account
|
|
64
117
|
- `/tkr-unlink` unlinks this machine from your account
|
|
65
118
|
- `/tkr-gain` shows the estimated reduction in command-output tokens
|
|
66
|
-
- `/tkr-status` shows your
|
|
119
|
+
- `/tkr-status` shows your account and engine status
|
|
67
120
|
- `/tkr-compression` picks the compression level (light, balanced, max)
|
|
68
121
|
- `/tkr-yolo on` explicitly enables YOLO on this machine; `/tkr-yolo off` disables it
|
|
69
122
|
- `/tkr-reducer` makes the assistant's replies shorter (off, light, balanced, max)
|
|
70
|
-
- `/tkr-telemetry` views or changes
|
|
123
|
+
- `/tkr-telemetry` views or changes usage stats (command names and token counts; on by default, off in one command)
|
|
71
124
|
- `/tkr-update` updates the plugin when a new version is out
|
|
72
125
|
|
|
73
126
|
From any terminal (after the shell-shim install, or `npm install -g @tokmizer/plugin`):
|
|
74
127
|
|
|
75
|
-
- `tkr status` shows your
|
|
128
|
+
- `tkr status` shows your account and engine status
|
|
76
129
|
- `tkr gain` shows the estimated reduction in command-output tokens
|
|
77
130
|
- `tkr link <key>` connects an optional account
|
|
78
131
|
- `tkr unlink` unlinks this machine
|
|
@@ -80,6 +133,8 @@ From any terminal (after the shell-shim install, or `npm install -g @tokmizer/pl
|
|
|
80
133
|
- `tkr yolo on|off|status` enables, disables, or checks the local YOLO mode
|
|
81
134
|
- `tkr reducer off|light|balanced|max` makes the assistant's replies shorter (default off)
|
|
82
135
|
- `tkr settings show|set|configure` manages settings and syncs them across your machines
|
|
136
|
+
- `tkr network off|on|status` blocks or allows every connection to tokmizer.com
|
|
137
|
+
- `tkr migrate rtk` moves your rtk filters, settings and history over and turns off rtk hooks where Tokmizer runs (see [Switching from rtk to Tokmizer](#switching-from-rtk-to-tokmizer))
|
|
83
138
|
|
|
84
139
|
## Choosing a compression mode
|
|
85
140
|
|
|
@@ -112,8 +167,24 @@ Terminal commands managed by Tokmizer use the mode selected when execution start
|
|
|
112
167
|
|
|
113
168
|
In the next release, successful `tkr restore` calls are counted as additional output in the local gain history, even with telemetry disabled. They reduce the net saving; repeated restorations count again and can make it negative. The display shows restored tokens separately. `gain --json` exposes the net estimate in `observed.savedTokens` and restoration totals in `restoration`; the existing top-level `savedTokens` remains the total for reduced outputs only. Earlier restorations cannot be reconstructed from local history. Manually repeated commands, prompts, replies and replayed conversation context are not attributed to restoration costs.
|
|
114
169
|
|
|
170
|
+
Other local views: `tkr gain --by-rule` groups savings by rule (your custom filters by name, built-in rules by command), `tkr gain --failures` lists commands whose output went through unchanged and why (no rule, nothing to cut, failed run kept in full), and `tkr gain --quota [pro|5x|20x]` estimates the share of a Claude plan budget the savings represent. The quota view is an estimate, not a plan limit: tokens saved per day × 30, divided by an assumed 44,000 tokens per 5-hour window × 144 windows × the plan multiplier (1, 5 or 20). Anthropic does not publish plan limits in tokens. All three combine with a period, `--project` and `--json`.
|
|
171
|
+
|
|
115
172
|
The percentages in `tkr gain` measure byte reduction. A byte percentage can differ substantially from the reduction counted by a model's tokenizer. Restoring a full file after reading its outline can cost more tokens than reading it once. Compression is not a promise of faster task completion or a correct answer.
|
|
116
173
|
|
|
174
|
+
## Restoring shortened output
|
|
175
|
+
|
|
176
|
+
When Tokmizer shortens an output it can add a `[tkr restore <hash>]` hint. `tkr restore <hash>` prints the complete original output when it is at most 8 MB; for a larger output, the entry holds only the part that was left out and `tkr restore` says so. A unique prefix of the hash is enough.
|
|
177
|
+
|
|
178
|
+
| Command | Effect |
|
|
179
|
+
| --- | --- |
|
|
180
|
+
| `tkr restore <hash>` | Print the cached output |
|
|
181
|
+
| `tkr restore <hash> --lines 120:180` | Print only lines 120 to 180 (`120:`, `:40` and `57` also work) |
|
|
182
|
+
| `tkr restore <hash> --grep <pattern>` | Print matching lines with their line numbers |
|
|
183
|
+
| `tkr restore --grep <pattern>` | Search every cached output |
|
|
184
|
+
| `tkr restore --list` | List cached outputs with age, size, line count and command |
|
|
185
|
+
|
|
186
|
+
Entries are kept 30 days, up to 8 MB each and 200 MB in total; the oldest go first. `TOKMIZER_CCR_MAX_AGE_MS`, `TOKMIZER_CCR_ENTRY_MAX_BYTES` and `TOKMIZER_CCR_DIR_CAP_BYTES` change these limits, `TOKMIZER_CCR_DISABLED=1` turns copies off. `tkr gain` shows the restored tokens and the cache size.
|
|
187
|
+
|
|
117
188
|
## Measured comparison
|
|
118
189
|
|
|
119
190
|
On October 9, 2026, a fixed set of 30 real and synthetic command outputs contained 774,863 tokens before compression. The table counts tokens with the cl100k tokenizer, excluding restoration notices. It is a test corpus, not a sample of customer usage.
|
|
@@ -137,6 +208,51 @@ In a separate controlled test for 0.9.52, a repetitive failure log went from 1,0
|
|
|
137
208
|
|
|
138
209
|
These tokenizer counts are separate from the byte-based estimates in `tkr gain`. They measure output volume, not your bill, an agent's task success, or execution speed. See the [mode guide](https://tokmizer.com/en/docs#configuration) for usage and limits.
|
|
139
210
|
|
|
211
|
+
## Custom filters
|
|
212
|
+
|
|
213
|
+
Add your own output rules as `*.toml` files in `~/.tokmizer/filters/` (or `$TOKMIZER_HOME/filters/`). They load next to the built-in rules and win over them for the commands they match. They stay on your machine and are never uploaded. A file or rule that fails validation is skipped; `tkr doctor` shows what was loaded and why something was skipped.
|
|
214
|
+
|
|
215
|
+
A file is used only after you trust it: review it, then run `tkr filters trust` (all files) or `tkr filters trust <file>`. Tokmizer records the file's SHA-256; editing the file stops it from being used until you trust it again. `tkr filters untrust [file]` removes the trust.
|
|
216
|
+
|
|
217
|
+
```toml
|
|
218
|
+
schema_version = 1
|
|
219
|
+
|
|
220
|
+
[filters.make-check]
|
|
221
|
+
match_command = "^make\\s+check(\\s|$)"
|
|
222
|
+
strip_lines_matching = ["^make\\[\\d+\\]: (Entering|Leaving) directory"]
|
|
223
|
+
max_lines = 120
|
|
224
|
+
on_empty = "make check: no output"
|
|
225
|
+
|
|
226
|
+
[[filters.make-check.tests]]
|
|
227
|
+
name = "drops directory noise"
|
|
228
|
+
input = "make[1]: Entering directory '/src'\nok\n"
|
|
229
|
+
expected = "ok"
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
`schema_version` is optional; a version this tkr cannot read makes the file skipped with a message. `tkr filters test [rule]` runs the inline tests, including on files you have not trusted yet, and exits with 1 when one fails. Tests check the rule as written (the Light level) and ignore trailing whitespace; Balanced and Max shorten `max_lines` further.
|
|
233
|
+
|
|
234
|
+
`match_command` is a regular expression tested against the command line. `strip_lines_matching` drops matching lines, `max_lines` caps the number of lines kept and `on_empty` replaces an empty result. Also available: `strip_ansi = true`, `keep_failures = true` (failure lines survive the cap), `truncate_lines_at = 400`, and `priority = 60` to pick between several of your rules that match the same command.
|
|
235
|
+
|
|
236
|
+
## Switching from rtk to Tokmizer
|
|
237
|
+
|
|
238
|
+
If you already use rtk, one command brings over what can be brought over and stops commands from going through two hooks:
|
|
239
|
+
|
|
240
|
+
```sh
|
|
241
|
+
tkr migrate rtk # show the plan, then ask before changing anything
|
|
242
|
+
tkr migrate rtk --dry-run # only show the plan
|
|
243
|
+
tkr migrate rtk --yes # apply without asking
|
|
244
|
+
tkr migrate rtk --undo # put back every file the migrations changed, newest first
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
- **Filters.** rtk's global `filters.toml` (`~/.config/rtk/` on Linux, `~/Library/Application Support/rtk/` on macOS, `%APPDATA%\rtk\` on Windows) and the project's `.rtk/filters.toml` become files in `~/.tokmizer/filters/`. Their `[[tests]]` run again on Tokmizer and each result is printed. A filter that uses an option Tokmizer filters do not have (`replace`, `match_output`, `keep_lines_matching`, `head_lines`, `tail_lines`, `filter_stderr`) is not imported, and the plan says why. A file rtk had trusted stays trusted; the others, and project files (Tokmizer filters apply in every project), wait for `tkr filters trust`.
|
|
248
|
+
- **Settings.** From `config.toml`: `exclude_commands` (the output of those commands is left unchanged), the `rtk recall` retention or its `disabled` mode (`~/.tokmizer/restore.json`), and telemetry turned off (`tkr telemetry off`). Every other setting is listed as not imported.
|
|
249
|
+
- **History.** The totals in rtk's `history.db` are read without changing it. `tkr gain` shows them on their own "Imported from rtk" line, never added to the savings Tokmizer measured. An unreadable file is skipped.
|
|
250
|
+
- **Agent hooks.** For each agent where both rtk and Tokmizer are installed (Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, Factory Droid, Trae, Mistral Vibe, Antigravity, OpenCode, Pi, Oh My Pi), the rtk hook is removed so commands are not wrapped twice. Where Tokmizer is not installed yet, the rtk hook stays and the plan says which `tkr setup-…` to run first. rtk's own proxy setting (`ANTHROPIC_BASE_URL`) is left alone. `tkr doctor` reports any agent where both still hook the same commands.
|
|
251
|
+
|
|
252
|
+
Every changed file is backed up under `~/.tokmizer/migrate-rtk/`. Running `--yes` again changes only what is new since the last migration and says `Already migrated` when nothing is; `--undo` reverts every migration still in place, newest first, and does not overwrite a file you changed after the migration: it tells you where its backup is.
|
|
253
|
+
|
|
254
|
+
`tkr migrate rtk --shim` also adds an `rtk` command to `~/.tokmizer/shims` for scripts and habits: `rtk gain` runs `tkr gain`, `rtk recall <hash>` runs `tkr restore <hash>`, `rtk bypass <cmd>` (or `rtk proxy <cmd>`) runs the command unchanged, and any other subcommand explains what to run instead. It takes over once rtk itself is uninstalled and `~/.tokmizer/shims` is on your `PATH`.
|
|
255
|
+
|
|
140
256
|
## Distribution
|
|
141
257
|
|
|
142
258
|
This README is shared by the npm package and the public GitHub repository.
|
|
@@ -146,12 +262,55 @@ This README is shared by the npm package and the public GitHub repository.
|
|
|
146
262
|
|
|
147
263
|
The optimization engine and API client ship compiled with [`@tokmizer/plugin`](https://www.npmjs.com/package/@tokmizer/plugin). Their source code is not in the public repository.
|
|
148
264
|
|
|
149
|
-
##
|
|
265
|
+
## Network & privacy
|
|
266
|
+
|
|
267
|
+
Tokmizer works without an account or email. It contacts `tokmizer.com` to keep its rules up to date and to improve the product. One command turns all of it off: `tkr network off`.
|
|
268
|
+
|
|
269
|
+
What leaves your machine, and when:
|
|
270
|
+
|
|
271
|
+
| When | What is sent | Why |
|
|
272
|
+
|---|---|---|
|
|
273
|
+
| First online run, no account | A random install ID, your computer name, OS and version, CPU model and core count, a SHA-256 hash of your network card (MAC) address, a SHA-256 hash of your user name, a fingerprint (SHA-256 of all of these), your time zone and the plugin version | Create the install token used to download rules |
|
|
274
|
+
| `tkr link <key>` | The same, plus your key, and your email only if you pass `--email` | Attach this machine to your account |
|
|
275
|
+
| Regular check-in (heartbeat) | Install ID, fingerprint, plugin version, local date and time zone | Refresh access and learn that a new version is out |
|
|
276
|
+
| Rule downloads | Install ID, fingerprint, plugin version | Get the latest compression rules and the `/power` and reducer instructions |
|
|
277
|
+
| Settings sync, linked accounts only | Your Tokmizer settings | Keep them in sync with the dashboard |
|
|
278
|
+
| Usage stats, only while they are on (with or without an account) | Command names such as `npm install` (never arguments; Git and GitHub commands excluded), token counts, rule IDs with output sizes, session ID, agent name | See which commands to optimize next |
|
|
279
|
+
| `tkr unlink` | Install ID, fingerprint | Remove this device from your account |
|
|
280
|
+
| CLI self-update, after a check-in reports a new version | Runs `npm i -g @tokmizer/plugin@<version>` or `brew upgrade tokmizer`, which contact the npm registry, Homebrew and GitHub | Keep the CLI current (`tkr auto-update off` stops only this) |
|
|
281
|
+
|
|
282
|
+
The hashes are not anonymous: the same machine always gives the same values, and a user name hash can be guessed. Like any web server, `tokmizer.com` sees your IP address and keeps it in its security log. Tokmizer never sends command arguments, command output, file contents or file paths.
|
|
283
|
+
|
|
284
|
+
Usage stats are on by default and off in one command: `tkr telemetry off` (or `tkr network off` to stop every connection). The choice is saved on this machine and survives updates; an install that turned them off stays off. Before anything is sent, Tokmizer says so once, in the terminal or in the Claude Code session notice. Check with `tkr telemetry status`.
|
|
285
|
+
|
|
286
|
+
### Usage stats without an account
|
|
287
|
+
|
|
288
|
+
Usage stats do not need an account. Without one, they are stored against this install's random key, not against an email or a person. They are still not anonymous: the computer name and the other device details listed above are sent when the install registers and are kept with that key.
|
|
289
|
+
|
|
290
|
+
- **Sent:** for each command, its name, the token count before compression, tokens saved and restored, whether it was compressed, the session ID and the agent name. Never arguments, output, file contents or paths.
|
|
291
|
+
- **Only with your consent:** the plugin uploads them only while `tkr telemetry status` says `on`, and tells the server so with each upload. Nothing is accepted from an install that is off or whose network is off.
|
|
292
|
+
- **Once per install, before the first upload:** Tokmizer says so once (first run, setup, session start or upgrade) and sends nothing until that notice has been shown, then stays quiet.
|
|
293
|
+
- **Kept:** detailed rows for 90 days, then only a running total of tokens saved per key.
|
|
294
|
+
- **Linking later:** `tkr link` moves the install's past usage stats to your account, so your dashboard includes them.
|
|
295
|
+
- **Turn off:** `tkr telemetry off`. To stop every connection: `tkr network off`.
|
|
296
|
+
|
|
297
|
+
### Turn the network off
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
tkr network off # nothing leaves this machine
|
|
301
|
+
tkr network status
|
|
302
|
+
tkr network on
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
In CI or for one shell, set `TOKMIZER_NETWORK=0`. `tkr status` and `tkr doctor` show the current state.
|
|
306
|
+
|
|
307
|
+
While it is off there is no sign-up, heartbeat, rule download, settings sync, usage stats or update check. Tokmizer keeps compressing locally: with the last downloaded rules for up to 7 days, then with its core built-in rules. Settings are saved on this machine only. `tkr link` and `tkr heartbeat` explain how to turn the network back on.
|
|
308
|
+
|
|
309
|
+
The switch does not cover Claude Code's own marketplace auto-update, which `/tkr-update` turns on (set `extraKnownMarketplaces.tokmizer.autoUpdate` to `false` in `~/.claude/settings.json` to stop it), nor commands you run yourself such as the installer, `/tkr-update`, npm or brew.
|
|
310
|
+
|
|
311
|
+
### Local data
|
|
150
312
|
|
|
151
|
-
-
|
|
152
|
-
- In 0.9.52, telemetry defaults to on unless setup or saved settings turn it off. Check `tkr telemetry status`; using Tokmizer without an account does not itself disable telemetry.
|
|
153
|
-
- Turning telemetry off stops optional usage reporting. Initial activation, rule downloads, update checks and account synchronization are separate network operations. Activation includes device and installation metadata. Offline use requires previously downloaded rules and is subject to cache availability and expiry.
|
|
154
|
-
- Restoration copies are local and temporary. A restore hint identifies available cached content; there is no guarantee that every removed detail has a saved copy. YOLO creates no new restoration copies.
|
|
313
|
+
- Restoration copies are local and kept up to 30 days. A restore hint identifies available cached content; there is no guarantee that every removed detail has a saved copy. YOLO creates no new restoration copies.
|
|
155
314
|
- The public [redaction helpers](https://github.com/norwelltw/Tokmizer/blob/main/src/learn/redact.ts) are available for inspection.
|
|
156
315
|
- Local state lives in `~/.tokmizer/`.
|
|
157
316
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
|
|
3
|
+
const TKR = __TKR_ARGV__;
|
|
4
|
+
const ARGS = ["rewrite", "--host", "amp"];
|
|
5
|
+
|
|
6
|
+
export const description = "Routes shell commands through tokmizer to cut tool-output tokens.";
|
|
7
|
+
|
|
8
|
+
function rewrite(command, session) {
|
|
9
|
+
return new Promise((resolve) => {
|
|
10
|
+
if (typeof command !== "string" || !command.trim()) return resolve(null);
|
|
11
|
+
try {
|
|
12
|
+
const args = [...TKR.slice(1), ...ARGS, ...(typeof session === "string" && session ? ["--session", session] : [])];
|
|
13
|
+
const child = execFile(TKR[0], args, { timeout: 3000, windowsHide: true, encoding: "utf8", maxBuffer: 1 << 20 }, (error, stdout) => {
|
|
14
|
+
resolve(!error && typeof stdout === "string" && stdout.trim() ? stdout : null);
|
|
15
|
+
});
|
|
16
|
+
child.stdin?.on("error", () => {});
|
|
17
|
+
child.stdin?.end(command);
|
|
18
|
+
} catch {
|
|
19
|
+
resolve(null);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default function (amp) {
|
|
25
|
+
amp.on("tool.call", async (event) => {
|
|
26
|
+
try {
|
|
27
|
+
const shell = amp.helpers?.shellCommandFromToolCall?.(event);
|
|
28
|
+
const input = event?.input;
|
|
29
|
+
if (!shell || !input || typeof input !== "object") return { action: "allow" };
|
|
30
|
+
const key = input.command === shell.command ? "command" : input.cmd === shell.command ? "cmd" : null;
|
|
31
|
+
if (!key) return { action: "allow" };
|
|
32
|
+
const rewritten = await rewrite(shell.command, event?.thread?.id);
|
|
33
|
+
return rewritten ? { action: "modify", input: { ...input, [key]: rewritten } } : { action: "allow" };
|
|
34
|
+
} catch {
|
|
35
|
+
return { action: "allow" };
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
|
|
3
|
+
TKR = __TKR_ARGV__
|
|
4
|
+
ARGS = ["rewrite", "--host", "hermes"]
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def _rewrite(command, session):
|
|
8
|
+
extra = ["--session", session] if isinstance(session, str) and session else []
|
|
9
|
+
result = subprocess.run(
|
|
10
|
+
TKR + ARGS + extra,
|
|
11
|
+
input=command,
|
|
12
|
+
capture_output=True,
|
|
13
|
+
text=True,
|
|
14
|
+
encoding="utf-8",
|
|
15
|
+
timeout=3,
|
|
16
|
+
shell=False,
|
|
17
|
+
)
|
|
18
|
+
if result.returncode != 0 or not result.stdout.strip():
|
|
19
|
+
return None
|
|
20
|
+
return result.stdout
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _pre_tool_call(tool_name=None, args=None, **kwargs):
|
|
24
|
+
try:
|
|
25
|
+
if tool_name != "terminal" or not isinstance(args, dict):
|
|
26
|
+
return None
|
|
27
|
+
command = args.get("command")
|
|
28
|
+
if not isinstance(command, str) or not command.strip():
|
|
29
|
+
return None
|
|
30
|
+
rewritten = _rewrite(command, kwargs.get("session_id"))
|
|
31
|
+
if not rewritten:
|
|
32
|
+
return None
|
|
33
|
+
return {"action": "modify", "args": {"command": rewritten}}
|
|
34
|
+
except Exception:
|
|
35
|
+
return None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def register(ctx):
|
|
39
|
+
ctx.register_hook("pre_tool_call", _pre_tool_call)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
|
|
3
|
+
const TKR = __TKR_ARGV__;
|
|
4
|
+
const ARGS = ["rewrite", "--host", "kilo"];
|
|
5
|
+
|
|
6
|
+
function rewrite(command, session) {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
if (typeof command !== "string" || !command.trim()) return resolve(null);
|
|
9
|
+
try {
|
|
10
|
+
const args = [...TKR.slice(1), ...ARGS, ...(typeof session === "string" && session ? ["--session", session] : [])];
|
|
11
|
+
const child = execFile(TKR[0], args, { timeout: 3000, windowsHide: true, encoding: "utf8", maxBuffer: 1 << 20 }, (error, stdout) => {
|
|
12
|
+
resolve(!error && typeof stdout === "string" && stdout.trim() ? stdout : null);
|
|
13
|
+
});
|
|
14
|
+
child.stdin?.on("error", () => {});
|
|
15
|
+
child.stdin?.end(command);
|
|
16
|
+
} catch {
|
|
17
|
+
resolve(null);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function apply(tool, container, session) {
|
|
23
|
+
try {
|
|
24
|
+
if ((tool !== "bash" && tool !== "shell") || !container || typeof container !== "object") return;
|
|
25
|
+
const rewritten = await rewrite(container.command, session);
|
|
26
|
+
if (rewritten) container.command = rewritten;
|
|
27
|
+
} catch {}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default {
|
|
31
|
+
id: "tokmizer",
|
|
32
|
+
async setup(ctx) {
|
|
33
|
+
await ctx?.tool?.hook?.("execute.before", (event) => apply(event?.tool, event?.input, event?.sessionID));
|
|
34
|
+
},
|
|
35
|
+
async server() {
|
|
36
|
+
return {
|
|
37
|
+
"tool.execute.before": (input, output) => apply(input?.tool, output?.args, input?.sessionID)
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
|
|
3
|
+
const TKR = __TKR_ARGV__;
|
|
4
|
+
const ARGS = ["rewrite", "--host", "omp"];
|
|
5
|
+
|
|
6
|
+
function rewrite(command, session) {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
if (typeof command !== "string" || !command.trim()) return resolve(null);
|
|
9
|
+
try {
|
|
10
|
+
const args = [...TKR.slice(1), ...ARGS, ...(typeof session === "string" && session ? ["--session", session] : [])];
|
|
11
|
+
const child = execFile(TKR[0], args, { timeout: 3000, windowsHide: true, encoding: "utf8", maxBuffer: 1 << 20 }, (error, stdout) => {
|
|
12
|
+
resolve(!error && typeof stdout === "string" && stdout.trim() ? stdout : null);
|
|
13
|
+
});
|
|
14
|
+
child.stdin?.on("error", () => {});
|
|
15
|
+
child.stdin?.end(command);
|
|
16
|
+
} catch {
|
|
17
|
+
resolve(null);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default function (pi) {
|
|
23
|
+
pi.on("tool_call", async (event) => {
|
|
24
|
+
try {
|
|
25
|
+
if (event?.toolName !== "bash" || !event.input || typeof event.input !== "object") return;
|
|
26
|
+
const rewritten = await rewrite(event.input.command);
|
|
27
|
+
return rewritten ? { input: { ...event.input, command: rewritten } } : undefined;
|
|
28
|
+
} catch {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
|
|
3
|
+
const TKR = __TKR_ARGV__;
|
|
4
|
+
const ARGS = ["rewrite", "--host", "openclaw"];
|
|
5
|
+
|
|
6
|
+
function rewrite(command, session) {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
if (typeof command !== "string" || !command.trim()) return resolve(null);
|
|
9
|
+
try {
|
|
10
|
+
const args = [...TKR.slice(1), ...ARGS, ...(typeof session === "string" && session ? ["--session", session] : [])];
|
|
11
|
+
const child = execFile(TKR[0], args, { timeout: 3000, windowsHide: true, encoding: "utf8", maxBuffer: 1 << 20 }, (error, stdout) => {
|
|
12
|
+
resolve(!error && typeof stdout === "string" && stdout.trim() ? stdout : null);
|
|
13
|
+
});
|
|
14
|
+
child.stdin?.on("error", () => {});
|
|
15
|
+
child.stdin?.end(command);
|
|
16
|
+
} catch {
|
|
17
|
+
resolve(null);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default {
|
|
23
|
+
id: "tokmizer",
|
|
24
|
+
name: "Tokmizer",
|
|
25
|
+
description: "Routes exec commands through tokmizer to cut tool-output tokens.",
|
|
26
|
+
register(api) {
|
|
27
|
+
api.on("before_tool_call", async (event) => {
|
|
28
|
+
try {
|
|
29
|
+
if (event?.toolName !== "exec" || event.toolKind === "code_mode_exec") return undefined;
|
|
30
|
+
const params = event.params;
|
|
31
|
+
if (!params || typeof params !== "object") return undefined;
|
|
32
|
+
const rewritten = await rewrite(params.command);
|
|
33
|
+
return rewritten ? { params: { ...params, command: rewritten } } : undefined;
|
|
34
|
+
} catch {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
|
|
3
|
+
const TKR = __TKR_ARGV__;
|
|
4
|
+
const ARGS = ["rewrite", "--host", "opencode"];
|
|
5
|
+
|
|
6
|
+
function rewrite(command, session) {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
if (typeof command !== "string" || !command.trim()) return resolve(null);
|
|
9
|
+
try {
|
|
10
|
+
const args = [...TKR.slice(1), ...ARGS, ...(typeof session === "string" && session ? ["--session", session] : [])];
|
|
11
|
+
const child = execFile(TKR[0], args, { timeout: 3000, windowsHide: true, encoding: "utf8", maxBuffer: 1 << 20 }, (error, stdout) => {
|
|
12
|
+
resolve(!error && typeof stdout === "string" && stdout.trim() ? stdout : null);
|
|
13
|
+
});
|
|
14
|
+
child.stdin?.on("error", () => {});
|
|
15
|
+
child.stdin?.end(command);
|
|
16
|
+
} catch {
|
|
17
|
+
resolve(null);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function apply(tool, container, session) {
|
|
23
|
+
try {
|
|
24
|
+
if ((tool !== "bash" && tool !== "shell") || !container || typeof container !== "object") return;
|
|
25
|
+
const rewritten = await rewrite(container.command, session);
|
|
26
|
+
if (rewritten) container.command = rewritten;
|
|
27
|
+
} catch {}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default {
|
|
31
|
+
id: "tokmizer",
|
|
32
|
+
async setup(ctx) {
|
|
33
|
+
await ctx?.tool?.hook?.("execute.before", (event) => apply(event?.tool, event?.input, event?.sessionID));
|
|
34
|
+
},
|
|
35
|
+
async server() {
|
|
36
|
+
return {
|
|
37
|
+
"tool.execute.before": (input, output) => apply(input?.tool, output?.args, input?.sessionID)
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
|
|
3
|
+
const TKR = __TKR_ARGV__;
|
|
4
|
+
const ARGS = ["rewrite", "--host", "pi"];
|
|
5
|
+
|
|
6
|
+
function rewrite(command, session) {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
if (typeof command !== "string" || !command.trim()) return resolve(null);
|
|
9
|
+
try {
|
|
10
|
+
const args = [...TKR.slice(1), ...ARGS, ...(typeof session === "string" && session ? ["--session", session] : [])];
|
|
11
|
+
const child = execFile(TKR[0], args, { timeout: 3000, windowsHide: true, encoding: "utf8", maxBuffer: 1 << 20 }, (error, stdout) => {
|
|
12
|
+
resolve(!error && typeof stdout === "string" && stdout.trim() ? stdout : null);
|
|
13
|
+
});
|
|
14
|
+
child.stdin?.on("error", () => {});
|
|
15
|
+
child.stdin?.end(command);
|
|
16
|
+
} catch {
|
|
17
|
+
resolve(null);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default function (pi) {
|
|
23
|
+
pi.on("tool_call", async (event) => {
|
|
24
|
+
try {
|
|
25
|
+
if (event?.toolName !== "bash" || !event.input || typeof event.input !== "object") return;
|
|
26
|
+
const rewritten = await rewrite(event.input.command);
|
|
27
|
+
if (rewritten) event.input.command = rewritten;
|
|
28
|
+
} catch {}
|
|
29
|
+
});
|
|
30
|
+
}
|
package/codex-plugin/plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Show estimated token reductions in recorded tool outputs.
|
|
3
|
-
argument-hint: [--day | --week | --month]
|
|
3
|
+
argument-hint: [--day | --week | --month] [--project [path]] [--csv | --graph | --history | --by-rule | --failures | --quota [pro|5x|20x]]
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
Show the user Tokmizer's recorded tool-output reductions.
|
|
@@ -17,11 +17,16 @@ Choose the scope the user requested:
|
|
|
17
17
|
- Today or `--day`: `gain --day` for the current local calendar day.
|
|
18
18
|
- Last seven days or `--week`: `gain --week`.
|
|
19
19
|
- Last thirty days or `--month`: `gain --month`.
|
|
20
|
+
- Only this project (or a given directory): add `--project` or `--project <path>`. It covers the live local journal only; older rotated history is not included, and commands recorded before this field existed are excluded.
|
|
21
|
+
- Export or alternative views, combinable with a period: `--csv` (one row per day), `--graph` (per-day bar chart, default last 30 days), `--history` (last 20 recorded commands).
|
|
22
|
+
- Savings per rule: `--by-rule` (custom filters by name, built-in rules grouped by command).
|
|
23
|
+
- Commands left unchanged and why: `--failures`.
|
|
24
|
+
- Share of a Claude plan budget: `--quota`, optionally followed by `pro`, `5x` or `20x` (default `pro`, last 30 days unless a period is given). Only when the user asks for it; it is a labelled estimate with its formula, not a plan limit.
|
|
20
25
|
- This session: `session` for session coverage. This command reports routing counts, not token or dollar savings.
|
|
21
26
|
|
|
22
27
|
Show the CLI output verbatim inside a fenced code block: do not summarize, translate, reformat or rebuild it as a table. After the block, add at most one short sentence. Keep its measurement scope and caveats. Token counts are estimates from output bytes, not model tokenizer counts. Dollar values use reference input prices and do not measure a bill reduction. Percentages apply only to the recorded tool outputs, not all tokens used by the agent.
|
|
23
28
|
|
|
24
|
-
Keep modeled reducer estimates separate from observed output reductions. Do not add them together, invent replay or repeated-context savings, or infer avoided model calls. Do not turn a period's estimate into a monthly projection or paid-plan payback. A comparison with another optimizer requires measurements on the same workload; these local totals alone do not establish one.
|
|
29
|
+
Keep modeled reducer estimates separate from observed output reductions. Do not add them together, invent replay or repeated-context savings, or infer avoided model calls. Do not turn a period's estimate into a monthly projection or paid-plan payback, except the projection printed by `--quota`, kept with its estimate label. A comparison with another optimizer requires measurements on the same workload; these local totals alone do not establish one.
|
|
25
30
|
|
|
26
31
|
If the output shows zero activity, report that no activity was recorded in the selected scope. This does not establish whether the optimizer is configured or running.
|
|
27
32
|
|
|
@@ -11,7 +11,7 @@ If $ARGUMENTS contains a value starting with `tokmizer_`, run it immediately, no
|
|
|
11
11
|
node "${CLAUDE_PLUGIN_ROOT}/dist/bin/tkr.js" link <that value>
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
On success the command prints
|
|
14
|
+
On success the command prints "Linked.". Tell the user it is done.
|
|
15
15
|
|
|
16
16
|
If $ARGUMENTS contains no `tokmizer_...` value, do not run anything and reply exactly:
|
|
17
17
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Show your Tokmizer
|
|
2
|
+
description: Show your Tokmizer account and engine status.
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
Show the user their Tokmizer account status.
|
|
@@ -10,8 +10,10 @@ Run the bundled CLI:
|
|
|
10
10
|
node "${CLAUDE_PLUGIN_ROOT}/dist/bin/tkr.js" status
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Print the output as is. It includes the
|
|
13
|
+
Print the output as is. It includes the network state, the token state, whether the device is linked and whether `/power` is available right now. Tokmizer is free: there is no plan or subscription to mention.
|
|
14
14
|
|
|
15
|
-
If the user is
|
|
15
|
+
If the user asks what Tokmizer sends over the network, answer plainly. No account or email is needed. Tokmizer contacts tokmizer.com to keep its rules up to date and to improve the product. It sends a random install ID, the computer name, OS and CPU model, a hash of the network card address and of the user name, and the plugin version. This is not anonymous: the same machine always gives the same values. Command contents and output are never sent. Usage stats (command names and token counts) are sent only if the user turned them on.
|
|
16
|
+
|
|
17
|
+
If the output shows `Network: off`, explain that nothing leaves the machine and Tokmizer keeps compressing with the rules already on it. To turn it back on: `tkr network on`. To turn everything off: `tkr network off`; usage stats only: `tkr telemetry off`.
|
|
16
18
|
|
|
17
19
|
If the command fails because the plugin files are missing, tokmizer was uninstalled. Offer to clean up: delete the tokmizer-managed `tkr*.md` copies (they end with a `managed-by: tokmizer` marker) from `~/.claude/commands/`.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Show or change Tokmizer
|
|
2
|
+
description: Show or change Tokmizer usage stats (status, on, off, forget).
|
|
3
3
|
argument-hint: status | on | off | forget
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -11,11 +11,11 @@ Pick the subcommand from the user's request. Default to `status` when they only
|
|
|
11
11
|
node "${CLAUDE_PLUGIN_ROOT}/dist/bin/tkr.js" telemetry status
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
- `telemetry status` shows whether
|
|
14
|
+
- `telemetry status` shows whether usage stats are on or off, the network state, whether an account is linked, what is sent and the local record count.
|
|
15
15
|
- `telemetry on` turns it on.
|
|
16
16
|
- `telemetry off` turns it off.
|
|
17
17
|
- `telemetry forget` erases telemetry data stored on this machine.
|
|
18
18
|
|
|
19
|
-
Print the output as is. If the user asks what is collected, tell them:
|
|
19
|
+
Print the output as is. If the user asks what is collected, tell them: command names and token counts only, never arguments, output or file contents. Like every request to tokmizer.com, they come with the install ID and a fingerprint of the machine, so they are not anonymous. They are sent with or without an account; without one they are tied to the install's key, and linking an account later moves them to it. Detailed rows are kept 90 days. The online dashboard at https://tokmizer.com needs telemetry on to show savings. To stop every connection, not only usage stats, the user runs `tkr network off`.
|
|
20
20
|
|
|
21
21
|
If the command fails because the plugin files are missing, tokmizer was uninstalled. Offer to clean up: delete the tokmizer-managed `tkr*.md` copies (they end with a `managed-by: tokmizer` marker) from `~/.claude/commands/`.
|