@tokenade/cli 0.5.5 → 0.6.0

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/install.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * postinstall — download the prebuilt Tokenade binary for this platform from
4
- * the signed release manifest, verify its SHA-256, and drop `tokenade` +
5
- * `tokenade-mcp` into ./vendor. The bin shims in ./bin exec them.
4
+ * the signed release manifest, verify its SHA-256, and drop `tokenade`
5
+ * into ./vendor. The bin shim in ./bin execs it.
6
6
  *
7
7
  * Closed-source commercial binary, distributed via the npm registry (the trust
8
8
  * anchor) — same pattern as esbuild/biome/swc. Nothing is executed blindly:
@@ -261,10 +261,19 @@ async function main() {
261
261
  throw new Error(`no published build for ${target}`);
262
262
  }
263
263
 
264
- const tmp = path.join(
265
- os.tmpdir(),
266
- `tokenade-${process.pid}-${path.basename(entry.url)}`,
267
- );
264
+ // Derive the temp filename from the URL's path only. The download URL
265
+ // carries a cache-buster query string (…tar.gz?b=<hash>); `?` and the
266
+ // rest are legal in a URL but ILLEGAL in a Windows filename, so leaving
267
+ // them in the basename makes fs.createWriteStream fail with ENOENT on
268
+ // win32 (passes silently on POSIX where `?` is a valid char). Strip the
269
+ // query/fragment, then sanitize any remaining hostile chars defensively.
270
+ const urlPath = entry.url.split(/[?#]/, 1)[0];
271
+ const safeBase =
272
+ (path.basename(urlPath) || "tokenade-build.tar.gz").replace(
273
+ /[^A-Za-z0-9._-]/g,
274
+ "_",
275
+ );
276
+ const tmp = path.join(os.tmpdir(), `tokenade-${process.pid}-${safeBase}`);
268
277
  const got = await downloadTo(entry.url, tmp);
269
278
  if (got !== entry.sha256) {
270
279
  fs.rmSync(tmp, { force: true });
@@ -292,7 +301,7 @@ async function main() {
292
301
  fs.rmSync(tmp, { force: true });
293
302
 
294
303
  if (process.platform !== "win32") {
295
- for (const name of ["tokenade", "tokenade-mcp"]) {
304
+ for (const name of ["tokenade"]) {
296
305
  const f = path.join(VENDOR, name);
297
306
  if (fs.existsSync(f)) fs.chmodSync(f, 0o755);
298
307
  }
@@ -301,7 +310,7 @@ async function main() {
301
310
  console.log(`✓ tokenade ${manifest.version} installed (${target})`);
302
311
  console.log(" Next: run `tokenade login` to activate this machine.");
303
312
  console.log(
304
- " Login also wires up your coding agents (hooks + MCP) so token savings start —",
313
+ " Login also wires up your coding agents (hooks) so token savings start —",
305
314
  );
306
315
  console.log(
307
316
  " already activated? run `tokenade install`, or `tokenade healthcheck` to verify the wiring.",
package/package.json CHANGED
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "@tokenade/cli",
3
- "version": "0.5.5",
4
- "description": "Tokenade — cut your AI coding agent's token bill. Installs the Tokenade CLI + MCP server (a local, paid token-reduction tool; activate via your browser).",
3
+ "version": "0.6.0",
4
+ "description": "Tokenade — 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",
7
7
  "bin": {
8
- "tokenade": "bin/tokenade.js",
9
- "tokenade-mcp": "bin/tokenade-mcp.js"
8
+ "tokenade": "bin/tokenade.js"
10
9
  },
11
10
  "scripts": {
12
11
  "postinstall": "node install.js"
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- const { spawnSync } = require("node:child_process");
4
- const path = require("node:path");
5
- const fs = require("node:fs");
6
-
7
- const bin = path.join(
8
- __dirname,
9
- "..",
10
- "vendor",
11
- process.platform === "win32" ? "tokenade-mcp.exe" : "tokenade-mcp",
12
- );
13
- if (!fs.existsSync(bin)) {
14
- console.error(
15
- "tokenade-mcp: binary not found. Re-run `npm install -g @tokenade/cli`.",
16
- );
17
- process.exit(1);
18
- }
19
- const r = spawnSync(bin, process.argv.slice(2), { stdio: "inherit" });
20
- if (r.error) {
21
- console.error(`tokenade-mcp: ${r.error.message}`);
22
- process.exit(1);
23
- }
24
- process.exit(r.status === null ? 1 : r.status);