@codeprakhar25/agent-baton 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.
Files changed (4) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +213 -0
  3. package/dist/cli.js +8771 -0
  4. package/package.json +33 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Prakhar Khatri
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,213 @@
1
+ # agent-baton
2
+
3
+ Transfer work between AI coding agents when a usage limit is close to being reached.
4
+
5
+ `baton` checks agent usage-limit signals, warns before the configured handoff point, and writes a Markdown handoff with transcript and git state when the user or configuration chooses a transfer.
6
+
7
+ ## Supported Signals
8
+
9
+ | Agent | Usage-limit source | Status |
10
+ |-------|--------------------|--------|
11
+ | Codex | `~/.codex/sessions/**/rollout-*.jsonl` `token_count.rate_limits` events | Implemented |
12
+ | Claude Code | `~/.claude/.credentials.json` OAuth token + Claude usage API | Implemented |
13
+ | Cursor | Transcript regex fallback for hard limit errors | Partial |
14
+ | Gemini CLI | Transcript regex fallback for hard limit errors | Partial |
15
+
16
+ This tool does not monitor context-window fullness and does not install context hooks. The Claude hooks are only usage-limit guards.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ npm install -g @codeprakhar25/agent-baton
22
+ ```
23
+
24
+ ## Setup
25
+
26
+ Run once per project:
27
+
28
+ ```bash
29
+ baton init
30
+ ```
31
+
32
+ This creates global Baton config/state, updates `.gitignore` for local overrides, and installs Claude project hooks that run `baton guard --from claude --hook`.
33
+
34
+ ## Commands
35
+
36
+ ### `baton usage --from <agent>`
37
+
38
+ Print current usage-limit status.
39
+
40
+ ```bash
41
+ baton usage --from claude
42
+ baton usage --from claude --json
43
+ baton usage --from claude --refresh
44
+ baton usage --from codex
45
+ ```
46
+
47
+ For Claude, `usage` reads `~/.claude/.credentials.json`, calls `https://api.anthropic.com/api/oauth/usage`, and caches normalized status in the project state directory under the global Baton state root.
48
+
49
+ ### `baton guard --from claude --hook`
50
+
51
+ Command used by Claude hooks. `SessionStart` fetches Claude usage once and writes `usage-cache.json` in the project state directory. Prompt and tool hooks read only the cache; they do one confirmatory refresh only if cached usage has already crossed `limits.handoff_percent`.
52
+
53
+ In the default `limits.mode: "ask"` mode:
54
+
55
+ - `UserPromptSubmit` adds context telling Claude to ask whether to continue or write a handoff.
56
+ - `PreToolUse` denies the tool call until Claude asks that same choice, so edits do not continue silently past the warning.
57
+ - Baton writes `pending-transfer.json` only when a handoff is actually created, for example with `baton handoff --from claude --reason rate-limit`.
58
+
59
+ Installed Claude hook events:
60
+
61
+ - `SessionStart` for `startup|resume`
62
+ - `UserPromptSubmit`
63
+ - `PreToolUse` for `Bash|Edit|Write|MultiEdit`
64
+
65
+ ### `baton watch --from <agent>`
66
+
67
+ Run beside the active agent. It monitors usage limits and warns when the configured threshold is crossed. It writes a handoff automatically only in `limits.mode: "auto_handoff"` or when hard-limit text is detected and `limits.auto_handoff_on_hard_limit` is enabled.
68
+
69
+ ```bash
70
+ baton watch --from codex
71
+ ```
72
+
73
+ For Codex, `watch` reads the active rollout JSONL and checks:
74
+
75
+ - `primary.used_percent`
76
+ - `secondary.used_percent`
77
+ - `window_minutes: 300` as 5-hour
78
+ - `window_minutes: 10080` as weekly
79
+ - `rate_limit_reached_type`
80
+
81
+ For all agents, it also scans new transcript bytes for hard-limit errors such as `usage limit`, `quota exceeded`, and `429`. Claude should normally use the hook-driven `guard` path instead of `watch`.
82
+
83
+ ### `baton codex [-- <codex args>] [prompt]`
84
+
85
+ Preflight Codex usage before launching Codex.
86
+
87
+ ```bash
88
+ baton codex
89
+ baton codex "continue the current task"
90
+ baton codex -- --model gpt-5.1
91
+ ```
92
+
93
+ If Codex usage is below `limits.handoff_percent`, Baton launches Codex normally. If usage is above the threshold, Baton asks whether to continue in Codex, create a handoff now, or run `baton pickup`. Continuing injects a first prompt warning Codex to ask the user before doing more work.
94
+
95
+ ### `baton handoff --from <agent> [--reason <reason>] [--launch]`
96
+
97
+ Manually write a handoff from the current transcript and git state.
98
+
99
+ ```bash
100
+ baton handoff --from codex
101
+ baton handoff --from claude --reason rate-limit
102
+ baton handoff --from claude --launch
103
+ ```
104
+
105
+ Creating a handoff also writes `pending-transfer.json` in the project state directory, which `baton pickup` clears after launching the next agent.
106
+
107
+ ### `baton pickup [--to <agent>]`
108
+
109
+ Launch another agent with a prompt that tells it to read the latest handoff file.
110
+
111
+ ```bash
112
+ baton pickup
113
+ baton pickup --to claude
114
+ baton pickup --to codex
115
+ ```
116
+
117
+ ### `baton init`
118
+
119
+ Create global Baton config/state and install project-local hooks.
120
+
121
+ ```bash
122
+ baton init
123
+ ```
124
+
125
+ ## Configuration
126
+
127
+ Global config is written to:
128
+
129
+ ```text
130
+ ~/.config/agent-baton/config.json
131
+ ```
132
+
133
+ Runtime state is written per project to:
134
+
135
+ ```text
136
+ ~/.local/state/agent-baton/projects/<project-slug>-<hash>/
137
+ ```
138
+
139
+ Baton also respects these environment overrides:
140
+
141
+ - `AGENT_BATON_CONFIG_HOME`
142
+ - `AGENT_BATON_STATE_HOME`
143
+ - `XDG_CONFIG_HOME`
144
+ - `XDG_STATE_HOME`
145
+
146
+ Optional per-project overrides can live in `.baton/config.json`; `baton init` adds `.baton/` to `.gitignore` so those overrides stay local.
147
+
148
+ Config shape:
149
+
150
+ ```json
151
+ {
152
+ "agents": {
153
+ "cursor": { "enabled": true, "priority": 1 },
154
+ "claude": { "enabled": true, "priority": 2 },
155
+ "codex": { "enabled": true, "priority": 3 },
156
+ "gemini": { "enabled": true, "priority": 4 }
157
+ },
158
+ "thresholds": {
159
+ "rate_limit_percent": 95
160
+ },
161
+ "limits": {
162
+ "mode": "ask",
163
+ "handoff_percent": 95,
164
+ "auto_handoff_on_hard_limit": true
165
+ },
166
+ "storage": {
167
+ "state_root": "~/.local/state/agent-baton",
168
+ "config_root": "~/.config/agent-baton",
169
+ "project_id_strategy": "slug_hash"
170
+ },
171
+ "usage_cache": {
172
+ "safe_ttl_ms": 900000,
173
+ "near_limit_ttl_ms": 60000,
174
+ "near_limit_percent": 75
175
+ },
176
+ "usage_sources": {
177
+ "claude": {
178
+ "oauth_credentials_path": "~/.claude/.credentials.json"
179
+ }
180
+ },
181
+ "handoff_dir": "handoffs",
182
+ "handoff_extraction": {
183
+ "max_transcript_lines": 100,
184
+ "include_git_diff": true,
185
+ "max_diff_chars": 8000,
186
+ "scan_secrets": true
187
+ },
188
+ "watch": {
189
+ "poll_interval_ms": 3000
190
+ }
191
+ }
192
+ ```
193
+
194
+ `thresholds.rate_limit_percent` is kept for older configs. New configs should use `limits.handoff_percent`. Relative `handoff_dir` values resolve under the per-project state directory.
195
+
196
+ ## Handoff Files
197
+
198
+ Handoffs are written to each project state directory:
199
+
200
+ ```text
201
+ ~/.local/state/agent-baton/projects/<project-slug>-<hash>/handoffs/
202
+ HANDOFF-latest.md
203
+ HANDOFF-<timestamp>.md
204
+ ```
205
+
206
+ Each handoff includes task state from the transcript plus git status, diff stat, recent commits, and the uncommitted diff.
207
+
208
+ ## Current Limits
209
+
210
+ - Claude proactive usage detection is hook-driven and uses Claude Code OAuth credentials.
211
+ - Codex proactive usage detection reads rollout JSONL events.
212
+ - Cursor and Gemini currently rely on hard-limit text appearing in transcripts.
213
+ - There is no context-window handoff path.