@tokenade/cli 0.8.11 → 0.8.12
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 +2 -2
- package/package.json +4 -2
- package/uninstall.js +76 -0
package/README.md
CHANGED
|
@@ -108,7 +108,7 @@ When reporting, please include your OS, `tokenade --version`, your coding agent,
|
|
|
108
108
|
| Command | What it does |
|
|
109
109
|
|---|---|
|
|
110
110
|
| `install` | Register Tokenade with your detected agent (hooks). Flags: `--only <agent>`, `--with-hook`, `--with-claude-md`, `--with-lsp-enforcement-hook`, `--with-brevity-skill`, `--dry-run`. |
|
|
111
|
-
| `uninstall
|
|
111
|
+
| `uninstall` | Remove the integration (restores wrapped MCP servers). `--dry-run` to preview. |
|
|
112
112
|
| `login` | Activate via browser device-flow — no key to type. |
|
|
113
113
|
| `activate <key>` | Link this machine to a tokenade.net license (free or paid) with a key. |
|
|
114
114
|
| `upgrade` | Self-update in place (aliases: `self-update`). `--on`/`--off` toggles the 24h background updater. |
|
|
@@ -266,7 +266,7 @@ $ tokenade incompatibilities
|
|
|
266
266
|
[redundant] rtk
|
|
267
267
|
Output-filtering CLI proxy (filters/compresses bash output)
|
|
268
268
|
→ binary at ~/.cargo/bin/rtk
|
|
269
|
-
fix: Tokenade subsumes rtk: `tokenade
|
|
269
|
+
fix: Tokenade subsumes rtk: `tokenade wrap '<cmd>'` does the same AND
|
|
270
270
|
auto-detects 48 formats — usually with better savings.
|
|
271
271
|
|
|
272
272
|
Run `tokenade install` to interactively migrate & fix the [redundant] /
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenade/cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.12",
|
|
4
4
|
"description": "Tokenade \u2014 cut your AI coding agent's token bill. Installs the Tokenade CLI (a local, paid token-reduction tool; activate via your browser).",
|
|
5
5
|
"homepage": "https://tokenade.net",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"tokenade": "bin/tokenade.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"postinstall": "node install.js"
|
|
11
|
+
"postinstall": "node install.js",
|
|
12
|
+
"preuninstall": "node uninstall.js"
|
|
12
13
|
},
|
|
13
14
|
"dependencies": {
|
|
14
15
|
"tar": "^7.5.16"
|
|
@@ -16,6 +17,7 @@
|
|
|
16
17
|
"files": [
|
|
17
18
|
"bin/",
|
|
18
19
|
"install.js",
|
|
20
|
+
"uninstall.js",
|
|
19
21
|
"README.md"
|
|
20
22
|
],
|
|
21
23
|
"engines": {
|
package/uninstall.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* preuninstall — run tokenade's own cleanup BEFORE npm deletes the package
|
|
4
|
+
* files, so that `npm uninstall -g @tokenade/cli` actually restores the
|
|
5
|
+
* machine (unwraps MCPs, strips hooks/CLAUDE.md/shell-proxy, and wipes
|
|
6
|
+
* ~/.tokenade + ~/.cache/tokenade) instead of orphaning integration that then
|
|
7
|
+
* spawns a missing binary on every tool call.
|
|
8
|
+
*
|
|
9
|
+
* We locate the SAME vendored binary that install.js (postinstall) dropped in
|
|
10
|
+
* ./vendor and invoke it as `tokenade uninstall --headless`:
|
|
11
|
+
* --headless → no banner, no next-step guidance, and it does NOT touch the
|
|
12
|
+
* binary itself (npm removes ./vendor right after this script).
|
|
13
|
+
*
|
|
14
|
+
* FAIL-OPEN by construction: every failure path (missing binary, spawn error,
|
|
15
|
+
* timeout, non-zero exit) is swallowed and we ALWAYS `process.exit(0)`. A
|
|
16
|
+
* cleanup that can't run must never block `npm uninstall` or leave the user
|
|
17
|
+
* unable to remove the package.
|
|
18
|
+
*
|
|
19
|
+
* npm lifecycle note: `preuninstall` runs on `npm uninstall` / `npm rm` /
|
|
20
|
+
* `npm remove` (local AND `-g`), and fires while the package files still
|
|
21
|
+
* exist. Caveats we accept: it is skipped when the user passes
|
|
22
|
+
* `--ignore-scripts` (or sets that config), and yarn/pnpm do not guarantee it.
|
|
23
|
+
* In those cases the binary is simply gone and its self-heal / a future
|
|
24
|
+
* `tokenade uninstall` covers the leftover integration.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
"use strict";
|
|
28
|
+
|
|
29
|
+
const fs = require("node:fs");
|
|
30
|
+
const path = require("node:path");
|
|
31
|
+
const { spawnSync } = require("node:child_process");
|
|
32
|
+
|
|
33
|
+
// Bound the child so a wedged cleanup can never hang `npm uninstall`.
|
|
34
|
+
const CLEANUP_TIMEOUT_MS =
|
|
35
|
+
Number(process.env.TOKENADE_UNINSTALL_TIMEOUT_MS) || 20000;
|
|
36
|
+
|
|
37
|
+
function binaryPath() {
|
|
38
|
+
const name = process.platform === "win32" ? "tokenade.exe" : "tokenade";
|
|
39
|
+
return path.join(__dirname, "vendor", name);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function main() {
|
|
43
|
+
const bin = binaryPath();
|
|
44
|
+
// Missing binary (never installed, --ignore-scripts, half-install) → nothing
|
|
45
|
+
// to run; npm still removes the package. Not an error.
|
|
46
|
+
if (!fs.existsSync(bin)) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
const res = spawnSync(bin, ["uninstall", "--headless"], {
|
|
51
|
+
stdio: "inherit",
|
|
52
|
+
timeout: CLEANUP_TIMEOUT_MS,
|
|
53
|
+
// A cleanup crash must not surface as a throw here.
|
|
54
|
+
windowsHide: true,
|
|
55
|
+
});
|
|
56
|
+
if (res.error) {
|
|
57
|
+
console.error(
|
|
58
|
+
` tokenade cleanup skipped (${res.error.message}); ` +
|
|
59
|
+
"run `tokenade uninstall` manually if any integration lingers.",
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
} catch (e) {
|
|
63
|
+
console.error(` tokenade cleanup skipped (${e && e.message});`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
main();
|
|
69
|
+
} catch (e) {
|
|
70
|
+
// Absolute backstop — nothing above should throw, but never let it matter.
|
|
71
|
+
try {
|
|
72
|
+
console.error(` tokenade cleanup skipped (${e && e.message});`);
|
|
73
|
+
} catch {}
|
|
74
|
+
}
|
|
75
|
+
// ALWAYS succeed: npm must be free to remove the package.
|
|
76
|
+
process.exit(0);
|