tokenmaxxing 1.71.0 → 1.72.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/package.json +2 -2
- package/src/cli/status.ts +1 -30
- package/src/lib/claudebin.ts +3 -3
- package/src/lib/codexbin.ts +3 -3
- package/src/lib/install.ts +11 -19
- package/src/lib/statusonly.ts +1 -1
- package/src/lib/tty.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tokenmaxxing",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.72.0",
|
|
4
4
|
"description": "Automatic Claude Code account switching: pool multiple accounts, start each session on its own account, and resume a session on a fresher account when quota fills.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"DESIGN.md"
|
|
20
20
|
],
|
|
21
21
|
"engines": {
|
|
22
|
-
"bun": ">=1.3.
|
|
22
|
+
"bun": ">=1.3.7"
|
|
23
23
|
},
|
|
24
24
|
"os": [
|
|
25
25
|
"darwin",
|
package/src/cli/status.ts
CHANGED
|
@@ -138,35 +138,6 @@ const NOTE_INDENT = " ";
|
|
|
138
138
|
type Note = { paint: (s: string) => string; text: string };
|
|
139
139
|
type Card = { lines: string[]; notes: Note[] };
|
|
140
140
|
|
|
141
|
-
function splitToWidth(token: string, width: number): string[] {
|
|
142
|
-
const parts: string[] = [];
|
|
143
|
-
let part = "";
|
|
144
|
-
for (const ch of token) {
|
|
145
|
-
if (part !== "" && Bun.stringWidth(part + ch) > width) {
|
|
146
|
-
parts.push(part);
|
|
147
|
-
part = "";
|
|
148
|
-
}
|
|
149
|
-
part += ch;
|
|
150
|
-
}
|
|
151
|
-
if (part !== "") parts.push(part);
|
|
152
|
-
return parts;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
function wrapWords(text: string, width: number): string[] {
|
|
156
|
-
const out: string[] = [];
|
|
157
|
-
let line = "";
|
|
158
|
-
for (const word of text.split(" ").flatMap((token) => splitToWidth(token, width))) {
|
|
159
|
-
if (line !== "" && Bun.stringWidth(`${line} ${word}`) > width) {
|
|
160
|
-
out.push(line);
|
|
161
|
-
line = word;
|
|
162
|
-
} else {
|
|
163
|
-
line = line === "" ? word : `${line} ${word}`;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
if (line !== "") out.push(line);
|
|
167
|
-
return out;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
141
|
function renderGrid(cards: Card[]): void {
|
|
171
142
|
const bodyWidth = Math.max(...cards.flatMap((card) => card.lines.map((line) => Bun.stringWidth(line))));
|
|
172
143
|
const termWidth = process.stdout.isTTY ? process.stdout.columns : Number.POSITIVE_INFINITY;
|
|
@@ -174,7 +145,7 @@ function renderGrid(cards: Card[]): void {
|
|
|
174
145
|
const cellWidth = columns === 1 ? termWidth : Math.floor((termWidth + CARD_GAP) / columns) - CARD_GAP;
|
|
175
146
|
const blocks = cards.map((card) => [
|
|
176
147
|
...card.lines,
|
|
177
|
-
...card.notes.flatMap((note) =>
|
|
148
|
+
...card.notes.flatMap((note) => Bun.wrapAnsi(note.text, cellWidth - NOTE_INDENT.length, { hard: true }).split("\n").map((line) => `${NOTE_INDENT}${note.paint(line)}`)),
|
|
178
149
|
]);
|
|
179
150
|
const width = Math.max(...blocks.flat().map((line) => Bun.stringWidth(line)));
|
|
180
151
|
for (const rowBlocks of chunk(blocks, columns)) {
|
package/src/lib/claudebin.ts
CHANGED
|
@@ -93,14 +93,14 @@ export function resolveRealClaude(): string {
|
|
|
93
93
|
|
|
94
94
|
export function verifyRealClaude(bin: string): string | null {
|
|
95
95
|
const env = { ...process.env, [WRAP_DEPTH_ENV]: String(MAX_WRAP_DEPTH), TOKENMAXXING_PROBE: "1" };
|
|
96
|
-
let p
|
|
96
|
+
let p;
|
|
97
97
|
try {
|
|
98
98
|
p = Bun.spawnSync([bin, "--version"], { env, stdout: "pipe", stderr: "pipe", timeout: 15_000, killSignal: "SIGKILL" });
|
|
99
99
|
} catch (e) {
|
|
100
100
|
return errorMessage(e);
|
|
101
101
|
}
|
|
102
|
-
const outText =
|
|
103
|
-
const err =
|
|
102
|
+
const outText = p.stdout.toString().trim();
|
|
103
|
+
const err = p.stderr.toString().trim();
|
|
104
104
|
if (p.exitCode === 0) {
|
|
105
105
|
if (/claude/i.test(outText)) return null;
|
|
106
106
|
return `--version output does not identify claude: "${outText.slice(0, 80)}"`;
|
package/src/lib/codexbin.ts
CHANGED
|
@@ -38,14 +38,14 @@ export function resolveRealCodex(): string {
|
|
|
38
38
|
|
|
39
39
|
export function verifyRealCodex(input: { bin: string }): string | null {
|
|
40
40
|
const env = { ...process.env, [WRAP_DEPTH_ENV]: String(MAX_WRAP_DEPTH), TOKENMAXXING_PROBE: "1" };
|
|
41
|
-
let p
|
|
41
|
+
let p;
|
|
42
42
|
try {
|
|
43
43
|
p = Bun.spawnSync([input.bin, "--version"], { env, stdout: "pipe", stderr: "pipe", timeout: 15_000, killSignal: "SIGKILL" });
|
|
44
44
|
} catch (e) {
|
|
45
45
|
return errorMessage(e);
|
|
46
46
|
}
|
|
47
|
-
const outText =
|
|
48
|
-
const err =
|
|
47
|
+
const outText = p.stdout.toString().trim();
|
|
48
|
+
const err = p.stderr.toString().trim();
|
|
49
49
|
if (p.exitCode === 0) {
|
|
50
50
|
if (outText.toLowerCase().includes("codex")) return null;
|
|
51
51
|
return `--version output does not identify codex: "${outText.slice(0, 80)}"`;
|
package/src/lib/install.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { accessSync, appendFileSync, constants, existsSync, mkdirSync, readFileSync, realpathSync, rmSync, statSync } from "node:fs";
|
|
2
|
+
import { userInfo } from "node:os";
|
|
2
3
|
import { basename, dirname, join, resolve } from "node:path";
|
|
3
4
|
import { escape } from "es-toolkit";
|
|
4
5
|
import { z } from "zod";
|
|
@@ -215,9 +216,8 @@ function launchdPlist(label: string): string {
|
|
|
215
216
|
return join(paths.launchdAgentsDir, `${label}.plist`);
|
|
216
217
|
}
|
|
217
218
|
|
|
218
|
-
function launchdDomain(): string
|
|
219
|
-
|
|
220
|
-
return uid == null ? null : `gui/${uid}`;
|
|
219
|
+
function launchdDomain(): string {
|
|
220
|
+
return `gui/${userInfo().uid}`;
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
function run(cmd: string[]): boolean {
|
|
@@ -258,7 +258,6 @@ ${launchdEnv()} <key>StandardOutPath</key><string>/dev/null</string>
|
|
|
258
258
|
0o644,
|
|
259
259
|
);
|
|
260
260
|
const domain = launchdDomain();
|
|
261
|
-
if (domain == null) return false;
|
|
262
261
|
run(["launchctl", "bootout", `${domain}/${LAUNCHD_LABEL}`]);
|
|
263
262
|
return run(["launchctl", "bootstrap", domain, plist]) || checkTimerHealthy();
|
|
264
263
|
}
|
|
@@ -313,8 +312,7 @@ export function hubActivationHint(): string {
|
|
|
313
312
|
export function checkTimerHealthy(): boolean {
|
|
314
313
|
if (skipImperativeTimer()) return true;
|
|
315
314
|
if (process.platform === "darwin") {
|
|
316
|
-
|
|
317
|
-
return existsSync(launchdPlist(LAUNCHD_LABEL)) && domain != null && run(["launchctl", "print", `${domain}/${LAUNCHD_LABEL}`]);
|
|
315
|
+
return existsSync(launchdPlist(LAUNCHD_LABEL)) && run(["launchctl", "print", `${launchdDomain()}/${LAUNCHD_LABEL}`]);
|
|
318
316
|
}
|
|
319
317
|
return (
|
|
320
318
|
existsSync(join(paths.systemdUserDir, "tokenmaxxing-check.timer")) &&
|
|
@@ -325,8 +323,7 @@ export function checkTimerHealthy(): boolean {
|
|
|
325
323
|
export function hubServiceHealthy(): boolean {
|
|
326
324
|
if (skipImperativeHub()) return true;
|
|
327
325
|
if (process.platform === "darwin") {
|
|
328
|
-
|
|
329
|
-
return existsSync(launchdPlist(LAUNCHD_HUB_LABEL)) && domain != null && run(["launchctl", "print", `${domain}/${LAUNCHD_HUB_LABEL}`]);
|
|
326
|
+
return existsSync(launchdPlist(LAUNCHD_HUB_LABEL)) && run(["launchctl", "print", `${launchdDomain()}/${LAUNCHD_HUB_LABEL}`]);
|
|
330
327
|
}
|
|
331
328
|
return existsSync(join(paths.systemdUserDir, HUB_UNIT)) && run(["systemctl", "--user", "is-active", "--quiet", HUB_UNIT]);
|
|
332
329
|
}
|
|
@@ -346,10 +343,8 @@ export function hubDeactivationHint(): string {
|
|
|
346
343
|
}
|
|
347
344
|
|
|
348
345
|
function launchdJobLoaded(label: string): "loaded" | "not-loaded" | "unavailable" {
|
|
349
|
-
const domain = launchdDomain();
|
|
350
|
-
if (domain == null) return "unavailable";
|
|
351
346
|
try {
|
|
352
|
-
const { exitCode } = Bun.spawnSync(["launchctl", "print", `${
|
|
347
|
+
const { exitCode } = Bun.spawnSync(["launchctl", "print", `${launchdDomain()}/${label}`], { stdout: "ignore", stderr: "ignore", timeout: 10_000 });
|
|
353
348
|
if (exitCode === 0) return "loaded";
|
|
354
349
|
return exitCode === 113 ? "not-loaded" : "unavailable";
|
|
355
350
|
} catch {
|
|
@@ -387,9 +382,8 @@ function uninstallCheckTimer(live: boolean): UnitOutcome {
|
|
|
387
382
|
return "removed";
|
|
388
383
|
}
|
|
389
384
|
if (process.platform === "darwin") {
|
|
390
|
-
const domain = launchdDomain();
|
|
391
385
|
const loaded = launchdJobLoaded(LAUNCHD_LABEL);
|
|
392
|
-
const deactivated = loaded === "loaded"
|
|
386
|
+
const deactivated = loaded === "loaded" ? run(["launchctl", "bootout", `${launchdDomain()}/${LAUNCHD_LABEL}`]) : loaded === "not-loaded";
|
|
393
387
|
removeTimerUnits();
|
|
394
388
|
return deactivated ? "removed" : "still-loaded";
|
|
395
389
|
}
|
|
@@ -423,7 +417,6 @@ ${launchdEnv()} <key>StandardOutPath</key><string>/dev/null</string>
|
|
|
423
417
|
0o644,
|
|
424
418
|
);
|
|
425
419
|
const domain = launchdDomain();
|
|
426
|
-
if (domain == null) return false;
|
|
427
420
|
run(["launchctl", "bootout", `${domain}/${LAUNCHD_HUB_LABEL}`]);
|
|
428
421
|
return run(["launchctl", "bootstrap", domain, plist]) || hubServiceHealthy();
|
|
429
422
|
}
|
|
@@ -463,9 +456,8 @@ function uninstallHubService(live: boolean): UnitOutcome {
|
|
|
463
456
|
return "removed";
|
|
464
457
|
}
|
|
465
458
|
if (process.platform === "darwin") {
|
|
466
|
-
const domain = launchdDomain();
|
|
467
459
|
const loaded = launchdJobLoaded(LAUNCHD_HUB_LABEL);
|
|
468
|
-
const deactivated = loaded === "loaded"
|
|
460
|
+
const deactivated = loaded === "loaded" ? run(["launchctl", "bootout", `${launchdDomain()}/${LAUNCHD_HUB_LABEL}`]) : loaded === "not-loaded";
|
|
469
461
|
removeHubUnits();
|
|
470
462
|
return deactivated ? "removed" : "still-loaded";
|
|
471
463
|
}
|
|
@@ -562,7 +554,7 @@ export function removePathFromRc(rc: string): boolean {
|
|
|
562
554
|
export type UninstallOutcome = { timer: UnitOutcome; hub: UnitOutcome; pathLineRemoved: boolean };
|
|
563
555
|
|
|
564
556
|
export function loginHome(): string {
|
|
565
|
-
const cmd = process.platform === "darwin" ? ["id", "-P"] : ["getent", "passwd", String(
|
|
557
|
+
const cmd = process.platform === "darwin" ? ["id", "-P"] : ["getent", "passwd", String(userInfo().uid)];
|
|
566
558
|
const proc = Bun.spawnSync(cmd, { stdout: "pipe", stderr: "ignore", timeout: 10_000 });
|
|
567
559
|
const home = proc.stdout.toString().trim().split(":").at(-2);
|
|
568
560
|
if (proc.exitCode !== 0 || home == null || home === "") throw new Error(`cannot read the login home: ${cmd.join(" ")} failed`);
|
|
@@ -576,11 +568,11 @@ export function onLoginHome(): boolean {
|
|
|
576
568
|
export function uninstallTargets(live: boolean): string[] {
|
|
577
569
|
const timer =
|
|
578
570
|
process.platform === "darwin"
|
|
579
|
-
? `${launchdPlist(LAUNCHD_LABEL)}${live ? ` (and launchctl bootout
|
|
571
|
+
? `${launchdPlist(LAUNCHD_LABEL)}${live ? ` (and launchctl bootout ${launchdDomain()}/${LAUNCHD_LABEL})` : ""}`
|
|
580
572
|
: `${join(paths.systemdUserDir, "tokenmaxxing-check.timer")} and .service${live ? " (and systemctl --user disable --now tokenmaxxing-check.timer)" : ""}`;
|
|
581
573
|
const hub =
|
|
582
574
|
process.platform === "darwin"
|
|
583
|
-
? `${launchdPlist(LAUNCHD_HUB_LABEL)}${live ? ` (and launchctl bootout
|
|
575
|
+
? `${launchdPlist(LAUNCHD_HUB_LABEL)}${live ? ` (and launchctl bootout ${launchdDomain()}/${LAUNCHD_HUB_LABEL})` : ""}`
|
|
584
576
|
: `${join(paths.systemdUserDir, HUB_UNIT)}${live ? ` (and systemctl --user disable --now ${HUB_UNIT})` : ""}`;
|
|
585
577
|
const rc = shellRcPath();
|
|
586
578
|
return [
|
package/src/lib/statusonly.ts
CHANGED
|
@@ -104,7 +104,7 @@ export function statusOnlyProvider(spec: StatusOnlySpec): Provider {
|
|
|
104
104
|
function preflight(): void {
|
|
105
105
|
const real = resolveBin();
|
|
106
106
|
const p = Bun.spawnSync([real, "--version"], { stdout: "pipe", stderr: "pipe", timeout: 15_000 });
|
|
107
|
-
if (p.exitCode !== 0 || !spec.versionOk(p.stdout
|
|
107
|
+
if (p.exitCode !== 0 || !spec.versionOk(p.stdout.toString())) {
|
|
108
108
|
throw new Error(`${spec.binName} binary failed verification: ${real}`);
|
|
109
109
|
}
|
|
110
110
|
pinBinOverride({ key: spec.binKey, bin: real });
|
package/src/lib/tty.ts
CHANGED