tokenmaxxing 1.168.0 → 1.169.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/README.md +0 -27
- package/package.json +2 -3
- package/src/lib/install.ts +4 -42
- package/src/lib/update.ts +0 -2
package/README.md
CHANGED
|
@@ -25,33 +25,6 @@ bun add -g tokenmaxxing
|
|
|
25
25
|
tokenmaxxing init
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
Or with Nix (same source-run-by-Bun package; `init` still owns the stores, the `claude` shim, and settings merges). Install onto PATH first, then init: `nix run ... -- init` alone leaves supervisor shims without a stable `tokenmaxxing` on PATH after the ephemeral run exits.
|
|
29
|
-
|
|
30
|
-
```sh
|
|
31
|
-
nix profile install github:anaclumos/tokenmaxxing
|
|
32
|
-
tokenmaxxing init
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
nix-darwin:
|
|
36
|
-
|
|
37
|
-
```nix
|
|
38
|
-
inputs.tokenmaxxing.url = "github:anaclumos/tokenmaxxing";
|
|
39
|
-
modules = [
|
|
40
|
-
inputs.tokenmaxxing.darwinModules.withOverlay
|
|
41
|
-
{ programs.tokenmaxxing.enable = true; }
|
|
42
|
-
];
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Home Manager:
|
|
46
|
-
|
|
47
|
-
```nix
|
|
48
|
-
imports = [ inputs.tokenmaxxing.homeManagerModules.default ];
|
|
49
|
-
programs.tokenmaxxing.enable = true;
|
|
50
|
-
programs.tokenmaxxing.package = inputs.tokenmaxxing.packages.${pkgs.system}.default;
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
With either module, run `tokenmaxxing init` afterwards.
|
|
54
|
-
|
|
55
28
|
`init` verifies and pins the real `claude` binary, opens an isolated `claude` session for your first pooled account (run `/login` there, even if you are already signed in; the login you already have stays for sessions started outside the supervisor), installs the `claude` supervisor and the `xx` entry point, five `settings.json` entries (the tokenmaxxing statusLine, a subagentStatusLine, a Stop hook, a StopFailure hook, a SessionStart hook), the periodic check timer, and the usage hub service, and adds the supervisor's bin dir to PATH in your shell rc (idempotent; it must sit ahead of the real `claude` to intercept it). Restart your shell, then add more accounts and go:
|
|
56
29
|
|
|
57
30
|
```sh
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tokenmaxxing",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.169.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",
|
|
@@ -26,8 +26,7 @@
|
|
|
26
26
|
],
|
|
27
27
|
"scripts": {
|
|
28
28
|
"dev": "bun run src/main.ts",
|
|
29
|
-
"typecheck": "tsc --noEmit"
|
|
30
|
-
"nix:bun": "bunx bun2nix@2.1.2 -o bun.nix"
|
|
29
|
+
"typecheck": "tsc --noEmit"
|
|
31
30
|
},
|
|
32
31
|
"devDependencies": {
|
|
33
32
|
"@types/bun": "1.3.14",
|
package/src/lib/install.ts
CHANGED
|
@@ -28,15 +28,6 @@ export function isBinDirAhead(bin: { name: string; key: BinKey } = CLAUDE_BIN):
|
|
|
28
28
|
|
|
29
29
|
const envFlag = (name: string): boolean => z.stringbool().optional().parse(optionalEnv(name)) === true;
|
|
30
30
|
|
|
31
|
-
export function isNixPackaged(): boolean {
|
|
32
|
-
if (envFlag("TOKENMAXXING_NIX")) return true;
|
|
33
|
-
try {
|
|
34
|
-
return realpathSync(Bun.main).startsWith("/nix/store/");
|
|
35
|
-
} catch {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
31
|
function skipImperativeTimer(): boolean {
|
|
41
32
|
return envFlag("TOKENMAXXING_SKIP_TIMER");
|
|
42
33
|
}
|
|
@@ -45,13 +36,8 @@ function skipImperativeHub(): boolean {
|
|
|
45
36
|
return envFlag("TOKENMAXXING_SKIP_HUB");
|
|
46
37
|
}
|
|
47
38
|
|
|
48
|
-
function isNixStorePath(path: string): boolean {
|
|
49
|
-
return path === "/nix/store" || path.startsWith("/nix/store/");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
39
|
function cannotWriteRcTarget(target: string): boolean {
|
|
53
40
|
if (envFlag("TOKENMAXXING_SKIP_SHELL_RC")) return true;
|
|
54
|
-
if (isNixStorePath(target)) return true;
|
|
55
41
|
if (!existsSync(target)) return false;
|
|
56
42
|
try {
|
|
57
43
|
accessSync(target, constants.W_OK);
|
|
@@ -63,40 +49,16 @@ function cannotWriteRcTarget(target: string): boolean {
|
|
|
63
49
|
|
|
64
50
|
export function managedShellRcSkipLines(): { headline: string; detail: string; exportLine: string } {
|
|
65
51
|
return {
|
|
66
|
-
headline: "shell rc is
|
|
67
|
-
detail: `put ${paths.binDir} on PATH
|
|
68
|
-
exportLine: `
|
|
52
|
+
headline: "shell rc is not writable - PATH was not auto-edited",
|
|
53
|
+
detail: `put ${paths.binDir} on PATH ahead of the real claude, e.g.`,
|
|
54
|
+
exportLine: `export PATH="${paths.binDir}:$PATH"`,
|
|
69
55
|
};
|
|
70
56
|
}
|
|
71
57
|
|
|
72
|
-
function nixSupervisorShim(bun: string, entry: string): string {
|
|
73
|
-
return `#!/bin/sh
|
|
74
|
-
dir=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
|
|
75
|
-
old_ifs=$IFS
|
|
76
|
-
IFS=:
|
|
77
|
-
new_path=
|
|
78
|
-
for p in $PATH; do
|
|
79
|
-
[ "$p" = "$dir" ] && continue
|
|
80
|
-
if [ -n "$new_path" ]; then new_path="$new_path:$p"; else new_path="$p"; fi
|
|
81
|
-
done
|
|
82
|
-
IFS=$old_ifs
|
|
83
|
-
PATH=$new_path
|
|
84
|
-
export PATH
|
|
85
|
-
if command -v tokenmaxxing >/dev/null 2>&1; then
|
|
86
|
-
exec tokenmaxxing "$@"
|
|
87
|
-
fi
|
|
88
|
-
exec ${shellQuote(bun)} --no-env-file run ${shellQuote(entry)} "$@"
|
|
89
|
-
`;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
58
|
function installEntryPoints(): string {
|
|
93
59
|
const target = installedBin();
|
|
94
60
|
const entry = realpathSync(Bun.main);
|
|
95
|
-
|
|
96
|
-
writeFileAtomic(target, nixSupervisorShim(process.execPath, entry), 0o755);
|
|
97
|
-
} else {
|
|
98
|
-
writeFileAtomic(target, `#!/bin/sh\nexec ${shellQuote(process.execPath)} --no-env-file run ${shellQuote(entry)} "$@"\n`, 0o755);
|
|
99
|
-
}
|
|
61
|
+
writeFileAtomic(target, `#!/bin/sh\nexec ${shellQuote(process.execPath)} --no-env-file run ${shellQuote(entry)} "$@"\n`, 0o755);
|
|
100
62
|
writeFileAtomic(join(paths.binDir, "xx"), `#!/bin/sh\nexec ${shellQuote(target)} "$@"\n`, 0o755);
|
|
101
63
|
return target;
|
|
102
64
|
}
|
package/src/lib/update.ts
CHANGED
|
@@ -4,7 +4,6 @@ import { z } from "zod";
|
|
|
4
4
|
import { writeFileAtomic } from "./atomic.ts";
|
|
5
5
|
import { realpathOrNull } from "./claudebin.ts";
|
|
6
6
|
import { http } from "./http.ts";
|
|
7
|
-
import { isNixPackaged } from "./install.ts";
|
|
8
7
|
import { withLock } from "./lock.ts";
|
|
9
8
|
import { errorMessage, log } from "./log.ts";
|
|
10
9
|
import { env, HOME, optionalEnv, paths } from "./paths.ts";
|
|
@@ -56,7 +55,6 @@ function registryPackageDir(root: string): string | null {
|
|
|
56
55
|
}
|
|
57
56
|
|
|
58
57
|
function detectGlobalRoot(): string | null {
|
|
59
|
-
if (isNixPackaged()) return null;
|
|
60
58
|
const entry = realpathOrNull(Bun.main);
|
|
61
59
|
if (entry == null) return null;
|
|
62
60
|
return (
|