@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.
- package/LICENSE +21 -0
- package/README.md +213 -0
- package/dist/cli.js +8771 -0
- 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.
|