From 4ce5114748c785c67fd578c2f8916968c2a029bf Mon Sep 17 00:00:00 2001 From: Faraazuddin Mohammed Date: Fri, 8 May 2026 12:30:14 -0400 Subject: [PATCH] fix(cli): run main() when invoked via npx symlink The entry-point guard compared `import.meta.url` against a naively constructed `file://${process.argv[1]}`. Under `npx`, argv[1] points at the symlink in the npx cache while import.meta.url resolves to the real dist path, so the guard was always false and the CLI silently exited 0. Resolve the symlink with realpathSync and convert with pathToFileURL so the comparison matches whether the binary is invoked directly, via npm bin shim, or via npx. Bump all packages 0.0.1 -> 0.0.2 so the fix can ship. Co-Authored-By: Claude Opus 4.7 (1M context) --- package-lock.json | 14 +++++++------- packages/action/package.json | 4 ++-- packages/cli/package.json | 4 ++-- packages/cli/src/index.ts | 17 ++++++++++++++--- packages/core/package.json | 2 +- packages/web/package.json | 4 ++-- 6 files changed, 28 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index c0b0b7f..910a720 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5148,13 +5148,13 @@ }, "packages/action": { "name": "@tokenometer/action", - "version": "0.0.1", + "version": "0.0.2", "license": "MIT", "dependencies": { "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", - "@tokenometer/core": "0.0.1", + "@tokenometer/core": "0.0.2", "minimatch": "^10.2.5" }, "devDependencies": { @@ -5631,10 +5631,10 @@ }, "packages/cli": { "name": "tokenometer", - "version": "0.0.1", + "version": "0.0.2", "license": "MIT", "dependencies": { - "@tokenometer/core": "0.0.1" + "@tokenometer/core": "0.0.2" }, "bin": { "tokenometer": "dist/index.js" @@ -5647,7 +5647,7 @@ }, "packages/core": { "name": "@tokenometer/core", - "version": "0.0.1", + "version": "0.0.2", "license": "MIT", "dependencies": { "@anthropic-ai/sdk": "^0.95.0", @@ -5662,12 +5662,12 @@ }, "packages/web": { "name": "@tokenometer/web", - "version": "0.0.1", + "version": "0.0.2", "license": "MIT", "dependencies": { "@anthropic-ai/sdk": "^0.40.0", "@google/generative-ai": "^0.21.0", - "@tokenometer/core": "0.0.1", + "@tokenometer/core": "0.0.2", "react": "^19.0.0", "react-dom": "^19.0.0" }, diff --git a/packages/action/package.json b/packages/action/package.json index 48313b8..e6fd658 100644 --- a/packages/action/package.json +++ b/packages/action/package.json @@ -1,6 +1,6 @@ { "name": "@tokenometer/action", - "version": "0.0.1", + "version": "0.0.2", "description": "GitHub Action that posts a sticky PR comment with prompt-cost diff.", "license": "MIT", "private": true, @@ -13,7 +13,7 @@ "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", - "@tokenometer/core": "0.0.1", + "@tokenometer/core": "0.0.2", "minimatch": "^10.2.5" }, "devDependencies": { diff --git a/packages/cli/package.json b/packages/cli/package.json index c4de1d4..443ce58 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "tokenometer", - "version": "0.0.1", + "version": "0.0.2", "description": "Empirical token-cost benchmarking CLI for LLM prompts. Tells you what your prompt actually costs across Claude, GPT-4o, and Gemini, in every format.", "license": "MIT", "author": "Faraazuddin Mohammed ", @@ -49,7 +49,7 @@ "clean": "rm -rf dist" }, "dependencies": { - "@tokenometer/core": "0.0.1" + "@tokenometer/core": "0.0.2" }, "devDependencies": { "@types/node": "^22.10.5", diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 2a8f425..a18c5fc 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -1,11 +1,13 @@ #!/usr/bin/env node +import { realpathSync } from 'node:fs'; import { readFile } from 'node:fs/promises'; +import { pathToFileURL } from 'node:url'; import { tokenizeMatrix, tokenizeMatrixEmpirical } from '@tokenometer/core'; import type { EmpiricalEnv } from '@tokenometer/core'; import { HELP_TEXT, parseArgs } from './args.js'; import { renderSummary, renderTable } from './render.js'; -const VERSION = '0.0.1'; +const VERSION = '0.0.2'; const readEnv = (): EmpiricalEnv => { const env: EmpiricalEnv = {}; @@ -88,8 +90,17 @@ export const main = async (argv: readonly string[]): Promise => { return 0; }; -const scriptUrl = `file://${process.argv[1]}`; -if (import.meta.url === scriptUrl) { +const isInvokedAsScript = (): boolean => { + const entry = process.argv[1]; + if (!entry) return false; + try { + return pathToFileURL(realpathSync(entry)).href === import.meta.url; + } catch { + return false; + } +}; + +if (isInvokedAsScript()) { main(process.argv.slice(2)).then( (code) => process.exit(code), (err: unknown) => { diff --git a/packages/core/package.json b/packages/core/package.json index d83093f..a19d601 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@tokenometer/core", - "version": "0.0.1", + "version": "0.0.2", "description": "Empirical token-cost benchmarking for LLM prompts — core library (tokenizers, format converters, rate matrix, empirical countTokens dispatch).", "license": "MIT", "author": "Faraazuddin Mohammed ", diff --git a/packages/web/package.json b/packages/web/package.json index c547def..d86c18c 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,6 +1,6 @@ { "name": "@tokenometer/web", - "version": "0.0.1", + "version": "0.0.2", "description": "Browser playground for paste-and-compare prompt cost analysis.", "license": "MIT", "private": true, @@ -13,7 +13,7 @@ "dependencies": { "@anthropic-ai/sdk": "^0.40.0", "@google/generative-ai": "^0.21.0", - "@tokenometer/core": "0.0.1", + "@tokenometer/core": "0.0.2", "react": "^19.0.0", "react-dom": "^19.0.0" },