cc-token-usage 0.1.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/bin/cli.mjs +95 -0
- package/bin/install.mjs +52 -0
- package/package.json +33 -0
package/bin/cli.mjs
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execSync, spawnSync } from "child_process";
|
|
4
|
+
import { existsSync, mkdirSync } from "fs";
|
|
5
|
+
import { join, dirname } from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
import { tmpdir, homedir, platform } from "os";
|
|
8
|
+
|
|
9
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
|
|
11
|
+
// ─── Find binary ─────────────────────────────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
function findBinary() {
|
|
14
|
+
// 1. Check bundled binary
|
|
15
|
+
const bundled = join(__dirname, "cc-token-usage");
|
|
16
|
+
if (existsSync(bundled)) return bundled;
|
|
17
|
+
|
|
18
|
+
// 2. Check PATH
|
|
19
|
+
try {
|
|
20
|
+
const which = platform() === "win32" ? "where" : "which";
|
|
21
|
+
const result = execSync(`${which} cc-token-usage`, {
|
|
22
|
+
encoding: "utf-8",
|
|
23
|
+
}).trim();
|
|
24
|
+
if (result) return result;
|
|
25
|
+
} catch {}
|
|
26
|
+
|
|
27
|
+
// 3. Check cargo bin
|
|
28
|
+
const cargoBin = join(homedir(), ".cargo", "bin", "cc-token-usage");
|
|
29
|
+
if (existsSync(cargoBin)) return cargoBin;
|
|
30
|
+
|
|
31
|
+
console.error("Error: cc-token-usage binary not found.");
|
|
32
|
+
console.error("Install it with: cargo install --path /path/to/cc-token-usage");
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ─── Parse args ──────────────────────────────────────────────────────────────
|
|
37
|
+
|
|
38
|
+
const args = process.argv.slice(2);
|
|
39
|
+
const hasFormatFlag = args.some((a) => a === "--format");
|
|
40
|
+
const hasOutputFlag = args.some((a) => a === "--output");
|
|
41
|
+
const wantsHelp = args.includes("--help") || args.includes("-h");
|
|
42
|
+
const wantsVersion = args.includes("--version") || args.includes("-V");
|
|
43
|
+
|
|
44
|
+
// ─── Simple passthrough for help/version/explicit args ───────────────────────
|
|
45
|
+
|
|
46
|
+
if (wantsHelp || wantsVersion || hasFormatFlag) {
|
|
47
|
+
const binary = findBinary();
|
|
48
|
+
const result = spawnSync(binary, args, { stdio: "inherit" });
|
|
49
|
+
process.exit(result.status ?? 1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ─── Default behavior: summary + HTML ────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
const binary = findBinary();
|
|
55
|
+
const subcommand = args[0] || "overview";
|
|
56
|
+
const restArgs = args.slice(1);
|
|
57
|
+
|
|
58
|
+
// 1. Print terminal summary
|
|
59
|
+
const textResult = spawnSync(binary, [subcommand, ...restArgs], {
|
|
60
|
+
stdio: "inherit",
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
if (textResult.status !== 0) {
|
|
64
|
+
process.exit(textResult.status ?? 1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 2. Generate HTML report
|
|
68
|
+
const outputDir = join(tmpdir(), "cc-token-usage");
|
|
69
|
+
mkdirSync(outputDir, { recursive: true });
|
|
70
|
+
|
|
71
|
+
const htmlFile =
|
|
72
|
+
subcommand === "session"
|
|
73
|
+
? join(outputDir, "session-report.html")
|
|
74
|
+
: join(outputDir, "report.html");
|
|
75
|
+
|
|
76
|
+
const htmlArgs = [subcommand, "--format", "html", "--output", htmlFile, ...restArgs];
|
|
77
|
+
const htmlResult = spawnSync(binary, htmlArgs, { stdio: "pipe" });
|
|
78
|
+
|
|
79
|
+
if (htmlResult.status === 0) {
|
|
80
|
+
console.log(`\nHTML report: ${htmlFile}`);
|
|
81
|
+
|
|
82
|
+
// 3. Auto-open in browser
|
|
83
|
+
const openCmd =
|
|
84
|
+
process.platform === "darwin"
|
|
85
|
+
? "open"
|
|
86
|
+
: process.platform === "win32"
|
|
87
|
+
? "start"
|
|
88
|
+
: "xdg-open";
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
execSync(`${openCmd} "${htmlFile}"`, { stdio: "ignore" });
|
|
92
|
+
} catch {
|
|
93
|
+
// Silent fail — user can open manually
|
|
94
|
+
}
|
|
95
|
+
}
|
package/bin/install.mjs
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Postinstall: resolve platform binary from optionalDependencies or PATH.
|
|
4
|
+
|
|
5
|
+
import { execSync } from "child_process";
|
|
6
|
+
import { existsSync, copyFileSync, chmodSync } from "fs";
|
|
7
|
+
import { join, dirname } from "path";
|
|
8
|
+
import { fileURLToPath } from "url";
|
|
9
|
+
import { createRequire } from "module";
|
|
10
|
+
|
|
11
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const binaryDest = join(__dirname, "cc-token-usage");
|
|
13
|
+
|
|
14
|
+
// Already have it
|
|
15
|
+
if (existsSync(binaryDest)) {
|
|
16
|
+
process.exit(0);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Try to resolve from platform-specific optionalDependency
|
|
20
|
+
const platform = process.platform;
|
|
21
|
+
const arch = process.arch;
|
|
22
|
+
const pkgMap = {
|
|
23
|
+
"darwin-arm64": "cc-token-usage-darwin-arm64",
|
|
24
|
+
"darwin-x64": "cc-token-usage-darwin-x64",
|
|
25
|
+
"linux-x64": "cc-token-usage-linux-x64",
|
|
26
|
+
};
|
|
27
|
+
const pkgName = pkgMap[`${platform}-${arch}`];
|
|
28
|
+
|
|
29
|
+
if (pkgName) {
|
|
30
|
+
try {
|
|
31
|
+
const require = createRequire(import.meta.url);
|
|
32
|
+
const pkgDir = dirname(require.resolve(`${pkgName}/package.json`));
|
|
33
|
+
const src = join(pkgDir, "cc-token-usage");
|
|
34
|
+
if (existsSync(src)) {
|
|
35
|
+
copyFileSync(src, binaryDest);
|
|
36
|
+
chmodSync(binaryDest, 0o755);
|
|
37
|
+
console.log(`cc-token-usage: installed binary from ${pkgName}`);
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
40
|
+
} catch {
|
|
41
|
+
// Package not installed (wrong platform, or not published yet)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Fallback: check PATH
|
|
46
|
+
try {
|
|
47
|
+
execSync("cc-token-usage --version", { stdio: "ignore" });
|
|
48
|
+
process.exit(0);
|
|
49
|
+
} catch {
|
|
50
|
+
console.warn("cc-token-usage: no pre-built binary for your platform.");
|
|
51
|
+
console.warn("Install via cargo: cargo install cc-token-usage");
|
|
52
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cc-token-usage",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Analyze Claude Code session token usage, costs, and efficiency",
|
|
5
|
+
"bin": {
|
|
6
|
+
"cc-token-usage": "./bin/cli.mjs"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "node ./bin/install.mjs"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin/",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"keywords": [
|
|
16
|
+
"claude",
|
|
17
|
+
"claude-code",
|
|
18
|
+
"token",
|
|
19
|
+
"analyzer",
|
|
20
|
+
"usage",
|
|
21
|
+
"cost"
|
|
22
|
+
],
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18"
|
|
26
|
+
},
|
|
27
|
+
"optionalDependencies": {
|
|
28
|
+
"cc-token-usage-darwin-arm64": "0.1.0",
|
|
29
|
+
"cc-token-usage-darwin-x64": "0.1.0",
|
|
30
|
+
"cc-token-usage-linux-x64": "0.1.0",
|
|
31
|
+
"cc-token-usage-linux-arm64": "0.1.0"
|
|
32
|
+
}
|
|
33
|
+
}
|