tokenmaxxing 1.8.0 → 1.9.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.
Files changed (85) hide show
  1. package/DESIGN.md +2 -4
  2. package/README.md +1 -1
  3. package/agent-plugin/plugin.json +1 -1
  4. package/package.json +1 -1
  5. package/src/cli/add.ts +1 -8
  6. package/src/cli/auth.ts +0 -23
  7. package/src/cli/check.ts +19 -13
  8. package/src/cli/codexadd.ts +0 -17
  9. package/src/cli/codexinit.ts +0 -40
  10. package/src/cli/codexrm.ts +0 -13
  11. package/src/cli/codexswitch.ts +0 -15
  12. package/src/cli/config.ts +0 -30
  13. package/src/cli/doctor.ts +1 -14
  14. package/src/cli/init.ts +1 -33
  15. package/src/cli/ls.ts +0 -2
  16. package/src/cli/onboard.ts +0 -37
  17. package/src/cli/rename.ts +0 -19
  18. package/src/cli/render.ts +0 -23
  19. package/src/cli/rm.ts +0 -19
  20. package/src/cli/status.ts +0 -80
  21. package/src/cli/switch.ts +1 -49
  22. package/src/cli/watch.ts +0 -17
  23. package/src/entries/codexstophook.ts +2 -73
  24. package/src/entries/codexsupervisor.ts +1 -67
  25. package/src/entries/mcp.ts +0 -11
  26. package/src/entries/sessionstart.ts +1 -8
  27. package/src/entries/statusline.ts +0 -66
  28. package/src/entries/stopfailurehook.ts +93 -0
  29. package/src/entries/stophook.ts +3 -34
  30. package/src/entries/subagentstatusline.ts +0 -19
  31. package/src/entries/supervisor.ts +32 -132
  32. package/src/lib/atomic.ts +0 -16
  33. package/src/lib/claudebin.ts +4 -55
  34. package/src/lib/claudejson.ts +0 -10
  35. package/src/lib/claudelock.ts +13 -35
  36. package/src/lib/codexauth.ts +0 -29
  37. package/src/lib/codexbin.ts +0 -10
  38. package/src/lib/codexdecide.ts +1 -112
  39. package/src/lib/codexoauth.ts +0 -16
  40. package/src/lib/codexpick.ts +0 -31
  41. package/src/lib/codexpresence.ts +0 -35
  42. package/src/lib/codexsample.ts +0 -23
  43. package/src/lib/codexstate.ts +0 -7
  44. package/src/lib/codexswap.ts +0 -32
  45. package/src/lib/codexusage.ts +0 -28
  46. package/src/lib/credstore.ts +0 -24
  47. package/src/lib/decide.ts +127 -180
  48. package/src/lib/http.ts +0 -9
  49. package/src/lib/install.ts +6 -127
  50. package/src/lib/keychain.ts +1 -39
  51. package/src/lib/lock.ts +0 -24
  52. package/src/lib/log.ts +0 -14
  53. package/src/lib/oauth.ts +1 -31
  54. package/src/lib/paths.ts +1 -48
  55. package/src/lib/picker.ts +1 -84
  56. package/src/lib/proc.ts +0 -17
  57. package/src/lib/sample.ts +0 -68
  58. package/src/lib/sessions.ts +0 -13
  59. package/src/lib/settings.ts +15 -42
  60. package/src/lib/state.ts +23 -77
  61. package/src/lib/swap.ts +3 -87
  62. package/src/lib/tty.ts +0 -4
  63. package/src/lib/types.ts +13 -140
  64. package/src/lib/usage.ts +108 -196
  65. package/src/lib/worktree.ts +0 -8
  66. package/src/main.ts +5 -40
  67. package/src/sdk.ts +0 -59
  68. package/agent-plugin/agents/tokenmaxxing-claude.md +0 -43
  69. package/agent-plugin/agents/tokenmaxxing-codex.md +0 -40
  70. package/agent-plugin/hooks/cursor-relay.json +0 -14
  71. package/agent-plugin/skills/relay-session/SKILL.md +0 -118
  72. package/agent-plugin/skills/relay-session/references/ipc.md +0 -23
  73. package/src/cli/relay.ts +0 -323
  74. package/src/entries/relaypermission.ts +0 -105
  75. package/src/lib/relay/config.ts +0 -84
  76. package/src/lib/relay/decide.ts +0 -75
  77. package/src/lib/relay/gc.ts +0 -80
  78. package/src/lib/relay/install.ts +0 -143
  79. package/src/lib/relay/markers.ts +0 -148
  80. package/src/lib/relay/modes.ts +0 -82
  81. package/src/lib/relay/protocol.ts +0 -61
  82. package/src/lib/relay/registry.ts +0 -175
  83. package/src/lib/relay/tmux.ts +0 -109
  84. package/src/lib/relay/turn.ts +0 -137
  85. package/src/lib/relay/worker.ts +0 -141
@@ -1,141 +0,0 @@
1
- // Ensure a durable tmux worker for a relay session. Spawns tokenmaxxing-
2
- // supervised claude/codex via PATH shims with pooled env intact.
3
-
4
- import { join } from "node:path";
5
- import { paths } from "../paths.ts";
6
- import { claudeArgvForMode, codexArgvForMode, type ClaudePermissionMode } from "./modes.ts";
7
- import { loadRelayConfig, type RelayWorker } from "./config.ts";
8
- import {
9
- createEntry,
10
- readEntry,
11
- touchEntry,
12
- withSessionLock,
13
- type RelayRegistryEntry,
14
- } from "./registry.ts";
15
- import { getTmux } from "./tmux.ts";
16
- import { clearTurnDoneMarker } from "./markers.ts";
17
-
18
- export const RELAY_SESSION_ENV = "TOKENMAXXING_RELAY_SESSION";
19
-
20
- function shellQuote(input: { value: string }): string {
21
- return `'${input.value.replaceAll("'", `'\\''`)}'`;
22
- }
23
-
24
- export function buildWorkerCommand(input: {
25
- sessionId: string;
26
- worker: RelayWorker;
27
- permissionMode: ClaudePermissionMode;
28
- binDir?: string;
29
- }): string {
30
- const binDir = input.binDir ?? paths.binDir;
31
- // Keep $PATH expandable: only quote the binDir segment.
32
- const envPrefix = `TOKENMAXXING_RELAY_SESSION=${shellQuote({ value: input.sessionId })} PATH=${shellQuote({ value: binDir })}:"$PATH"`;
33
- if (input.worker === "claude") {
34
- const modeArgs = claudeArgvForMode({ mode: input.permissionMode }).map((a) => shellQuote({ value: a })).join(" ");
35
- // Interactive durable session pinned to the relay UUID as Claude session id.
36
- return `${envPrefix} claude --session-id ${shellQuote({ value: input.sessionId })} ${modeArgs}`;
37
- }
38
- const modeArgs = codexArgvForMode({ mode: input.permissionMode }).map((a) => shellQuote({ value: a })).join(" ");
39
- return `${envPrefix} codex ${modeArgs}`;
40
- }
41
-
42
- export async function ensureSession(input: {
43
- sessionId?: string;
44
- worker?: RelayWorker;
45
- permissionMode?: ClaudePermissionMode;
46
- cwd: string;
47
- now?: number;
48
- }): Promise<RelayRegistryEntry> {
49
- const cfg = loadRelayConfig();
50
- const sessionId = input.sessionId ?? crypto.randomUUID();
51
- const worker = input.worker ?? cfg.defaultWorker;
52
- const permissionMode = input.permissionMode ?? cfg.defaultPermissionMode;
53
-
54
- return withSessionLock({
55
- sessionId,
56
- fn: () => {
57
- const existing = readEntry({ sessionId });
58
- const tmux = getTmux();
59
- if (existing != null) {
60
- if (!tmux.hasSession({ name: existing.tmuxName })) {
61
- const command = buildWorkerCommand({
62
- sessionId,
63
- worker: existing.worker,
64
- permissionMode: input.permissionMode ?? existing.permissionMode,
65
- });
66
- tmux.newSession({ name: existing.tmuxName, cwd: existing.cwd, command });
67
- }
68
- return touchEntry({
69
- sessionId,
70
- permissionMode: input.permissionMode,
71
- state: "idle",
72
- now: input.now,
73
- });
74
- }
75
- const entry = createEntry({
76
- sessionId,
77
- worker,
78
- permissionMode,
79
- cwd: input.cwd,
80
- now: input.now,
81
- });
82
- const command = buildWorkerCommand({ sessionId, worker, permissionMode });
83
- tmux.newSession({ name: entry.tmuxName, cwd: input.cwd, command });
84
- return entry;
85
- },
86
- });
87
- }
88
-
89
- export async function sendPrompt(input: {
90
- sessionId: string;
91
- prompt: string;
92
- }): Promise<void> {
93
- await withSessionLock({
94
- sessionId: input.sessionId,
95
- fn: () => {
96
- const entry = readEntry({ sessionId: input.sessionId });
97
- if (entry == null) throw new Error(`relay session not found: ${input.sessionId}`);
98
- clearTurnDoneMarker({ sessionId: input.sessionId });
99
- getTmux().sendKeys({ name: entry.tmuxName, text: input.prompt, enter: true });
100
- touchEntry({ sessionId: input.sessionId, state: "running" });
101
- },
102
- });
103
- }
104
-
105
- export async function setLivePermissionMode(input: {
106
- sessionId: string;
107
- permissionMode: ClaudePermissionMode;
108
- }): Promise<RelayRegistryEntry> {
109
- return withSessionLock({
110
- sessionId: input.sessionId,
111
- fn: () => {
112
- const entry = readEntry({ sessionId: input.sessionId });
113
- if (entry == null) throw new Error(`relay session not found: ${input.sessionId}`);
114
- // Best-effort: cycle Claude's Shift+Tab equivalent via a slash command when
115
- // the worker is Claude. Codex needs a respawn for sandbox changes.
116
- if (entry.worker === "claude" && getTmux().hasSession({ name: entry.tmuxName })) {
117
- getTmux().sendKeys({
118
- name: entry.tmuxName,
119
- text: `/permissions ${input.permissionMode}`,
120
- enter: true,
121
- });
122
- } else if (entry.worker === "codex") {
123
- getTmux().killSession({ name: entry.tmuxName });
124
- const command = buildWorkerCommand({
125
- sessionId: input.sessionId,
126
- worker: "codex",
127
- permissionMode: input.permissionMode,
128
- });
129
- getTmux().newSession({ name: entry.tmuxName, cwd: entry.cwd, command });
130
- }
131
- return touchEntry({
132
- sessionId: input.sessionId,
133
- permissionMode: input.permissionMode,
134
- });
135
- },
136
- });
137
- }
138
-
139
- export function workerBinHint(): string {
140
- return join(paths.binDir, "claude");
141
- }