tokenmaxxing 0.13.0 → 0.13.1

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/lib/install.ts +23 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokenmaxxing",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "Automatic Claude Code account switching: pool multiple accounts and hot-swap when quota fills, resuming your session on the fresh account.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -58,11 +58,19 @@ export function installSupervisor(): InstallOutcome {
58
58
 
59
59
  // ---- codex supervisor + Stop hook -------------------------------------------
60
60
 
61
- /** Codex hook declarations we merge into. Loose everywhere: every other event
62
- * and every foreign Stop entry rides along verbatim. */
63
- const CodexHooksFileSchema = z.looseObject({
61
+ /** Codex hook declarations we merge into. The FILE nests the event map under a
62
+ * `hooks` field (`struct HooksFile { description?, hooks }`, binary-verified
63
+ * 0.144.4 after a live parse failure proved the docs' claude-style top-level
64
+ * event map wrong: "unknown field Stop, expected description or hooks").
65
+ * Loose everywhere: every other event and every foreign Stop entry rides
66
+ * along verbatim. */
67
+ const CodexHookEventsSchema = z.looseObject({
64
68
  Stop: z.array(z.looseObject({ hooks: z.array(z.looseObject({ command: z.string().optional() })).default([]) })).default([]),
65
69
  });
70
+ const CodexHooksFileSchema = z.looseObject({
71
+ description: z.string().optional(),
72
+ hooks: CodexHookEventsSchema.default({ Stop: [] }),
73
+ });
66
74
 
67
75
  const CODEX_STOP_HOOK_SUBCOMMAND = "__codex-stop-hook";
68
76
 
@@ -80,15 +88,18 @@ export function installCodexStopHook(): void {
80
88
  const current = existsSync(codexPaths.hooksJson)
81
89
  ? CodexHooksFileSchema.parse(JSON.parse(readFileSync(codexPaths.hooksJson, "utf8")))
82
90
  : CodexHooksFileSchema.parse({});
83
- const foreign = current.Stop.filter(
91
+ const foreign = current.hooks.Stop.filter(
84
92
  (group) => !group.hooks.some((hook) => hook.command?.includes(CODEX_STOP_HOOK_SUBCOMMAND)),
85
93
  );
86
94
  const next = {
87
95
  ...current,
88
- Stop: [
89
- ...foreign,
90
- { hooks: [{ type: "command", command: codexStopHookCommand(), timeout: 120, statusMessage: "tokenmaxxing switch check" }] },
91
- ],
96
+ hooks: {
97
+ ...current.hooks,
98
+ Stop: [
99
+ ...foreign,
100
+ { hooks: [{ type: "command", command: codexStopHookCommand(), timeout: 120, statusMessage: "tokenmaxxing switch check" }] },
101
+ ],
102
+ },
92
103
  };
93
104
  mkdirSync(codexPaths.home, { recursive: true });
94
105
  writeFileAtomic(codexPaths.hooksJson, JSON.stringify(next, null, 2) + "\n");
@@ -99,7 +110,10 @@ export function uninstallCodexStopHook(): void {
99
110
  const current = CodexHooksFileSchema.parse(JSON.parse(readFileSync(codexPaths.hooksJson, "utf8")));
100
111
  const next = {
101
112
  ...current,
102
- Stop: current.Stop.filter((group) => !group.hooks.some((hook) => hook.command?.includes(CODEX_STOP_HOOK_SUBCOMMAND))),
113
+ hooks: {
114
+ ...current.hooks,
115
+ Stop: current.hooks.Stop.filter((group) => !group.hooks.some((hook) => hook.command?.includes(CODEX_STOP_HOOK_SUBCOMMAND))),
116
+ },
103
117
  };
104
118
  writeFileAtomic(codexPaths.hooksJson, JSON.stringify(next, null, 2) + "\n");
105
119
  }