Commit fdad58f8133a
tarball16 files changed+84-84
@@ -8,7 +8,7 @@ license = "EUPL-1.2"
88
rust-version = "1.91"99
1010
[[bin]]11
-name = "rabt"11
+name = "roundabout"1212
path = "src/main.rs"1313
1414
[dependencies]@@ -6,27 +6,27 @@ agents say roughly how big a build is. a tiny daemon, started on demand and gone
66
77
## use88
9
-the cli is `rabt`, short enough that agents don't mind typing it9
+the cli is `roundabout`, short enough that agents don't mind typing it1010
1111
```12
-rabt run --size m -- cargo build13
-rabt run --ram 6G --cores 8 --time 10m -- nix build .#thing14
-rabt status15
-rabt suggest -- cargo build --release16
-rabt expect --size l # building soon, save me a seat17
-rabt watch 7 # exits when lease 7 is done or overdue18
-rabt kill 719
-rabt extend 7 10m20
-rabt artifacts check | list | gc [--cap] [--project] | pin <path>12
+roundabout run --size m -- cargo build13
+roundabout run --ram 6G --cores 8 --time 10m -- nix build .#thing14
+roundabout status15
+roundabout suggest -- cargo build --release16
+roundabout expect --size l # building soon, save me a seat17
+roundabout watch 7 # exits when lease 7 is done or overdue18
+roundabout kill 719
+roundabout extend 7 10m20
+roundabout artifacts check | list | gc [--cap] [--project] | pin <path>2121
```2222
2323
`run` exits with the build's code, 124 if `--deadline` killed it, 75 if `--max-wait` ran out.2424
2525
a granted build gets `CARGO_BUILD_JOBS`, `MAKEFLAGS`, `CMAKE_BUILD_PARALLEL_LEVEL` and a `NIX_CONFIG` with `cores`/`max-jobs` to match its grant.2626
27
-on linux, `rabt` creates a transient scope through the systemd user manager's D-Bus `StartTransientUnit` method. the command waits until its scope is active, then runs with its original environment and terminal I/O. `CPUQuotaPerSecUSec` caps CPU time at the granted core count, and `MemoryMax` caps the whole build at its granted RAM multiplied by `overrun.ram_slack`, with at least the granted RAM available. these limits cover descendants too, even when a tool ignores the job-count environment variables. linux requires a running systemd user manager and user bus, a failed scope refuses the build rather than running it without limits. other platforms retain the job-count environment variables without cgroup enforcement.27
+on linux, `roundabout` creates a transient scope through the systemd user manager's D-Bus `StartTransientUnit` method. the command waits until its scope is active, then runs with its original environment and terminal I/O. `CPUQuotaPerSecUSec` caps CPU time at the granted core count, and `MemoryMax` caps the whole build at its granted RAM multiplied by `overrun.ram_slack`, with at least the granted RAM available. these limits cover descendants too, even when a tool ignores the job-count environment variables. linux requires a running systemd user manager and user bus, a failed scope refuses the build rather than running it without limits. other platforms retain the job-count environment variables without cgroup enforcement.2828
29
-the grant can be bigger than the ask. idle cores go to whoever's building, minus what other sessions have said they'll want via `rabt expect`. spare cores never hold up admission, oversubscribing cpu only slows things down, but each one is charged ram at the build's own ram per core since more jobs eat more memory. a session's build counts as an `expect` too, so agents that forget still leave a mark. `--exact` opts out.29
+the grant can be bigger than the ask. idle cores go to whoever's building, minus what other sessions have said they'll want via `roundabout expect`. spare cores never hold up admission, oversubscribing cpu only slows things down, but each one is charged ram at the build's own ram per core since more jobs eat more memory. a session's build counts as an `expect` too, so agents that forget still leave a mark. `--exact` opts out.3030
3131
## claude code3232
@@ -46,7 +46,7 @@ programs.roundabout.settings.budget.ram = "16GiB"; # lands in /etc/roundabout/
4646
4747
that installs roundabout and a socket-activated systemd user unit for the daemon (`socketActivation = false` to let clients spawn it instead). `programs.roundabout.claude` has read-only `hooks`, `skill` and `plugin` for whatever writes your claude config, e.g. `settings.hooks = config.programs.roundabout.claude.hooks`.4848
49
-the plugin brings a skill and hooks. unwrapped builds get bounced back with instructions, overdue builds get mentioned to the agent that started them, and agents over their artifact cap get told to tidy up before they stop. `rabt` needs to be on PATH for the agent too, so install `.#roundabout` alongside.49
+the plugin brings a skill and hooks. unwrapped builds get bounced back with instructions, overdue builds get mentioned to the agent that started them, and agents over their artifact cap get told to tidy up before they stop. `roundabout` needs to be on PATH for the agent too, so install `.#roundabout` alongside.5050
5151
## codex5252
@@ -56,9 +56,9 @@ codex plugin marketplace add ./result
5656
codex plugin add roundabout@roundabout5757
```5858
59
-restart codex and review the plugin hooks with `/hooks` before using them. install `.#roundabout` as well so `rabt run` and `rabt expect` are on PATH. codex can also load the hooks directly from `~/.codex/hooks.json` or a trusted project's `.codex/hooks.json` using the `hooks` object in `result/plugins/roundabout/hooks/hooks.json`. use one installation route to avoid duplicate reminders.59
+restart codex and review the plugin hooks with `/hooks` before using them. install `.#roundabout` as well so `roundabout run` and `roundabout expect` are on PATH. codex can also load the hooks directly from `~/.codex/hooks.json` or a trusted project's `.codex/hooks.json` using the `hooks` object in `result/plugins/roundabout/hooks/hooks.json`. use one installation route to avoid duplicate reminders.6060
61
-on nixos, `programs.roundabout.codex` exposes read-only `hooks`, `skill` and `plugin`, alongside the claude options. the codex hooks deny unwrapped builds and suggest `rabt run` instead of silently rewriting the command, which keeps the normal tool approval flow intact even when `enforce.unwrapped` is set to `wrap`. `rabt run` and `rabt expect` associate builds with the current codex session, and session-end hooks release its expectation.61
+on nixos, `programs.roundabout.codex` exposes read-only `hooks`, `skill` and `plugin`, alongside the claude options. the codex hooks deny unwrapped builds and suggest `roundabout run` instead of silently rewriting the command, which keeps the normal tool approval flow intact even when `enforce.unwrapped` is set to `wrap`. `roundabout run` and `roundabout expect` associate builds with the current codex session, and session-end hooks release its expectation.6262
6363
## omp6464
@@ -67,7 +67,7 @@ nix build .#omp-plugin
6767
omp plugin link ./result6868
```6969
70
-restart omp after linking. install `.#roundabout` on PATH for the agent's bash tool, or set `ROUNDABOUT_CLI` to the `rabt` binary for the extension. the plugin bundles the skill and checks shell builds before they run. it also delivers overdue reminders, checks artifact caps before the main agent stops, and releases expectations when a session closes or switches. wrapped builds and `rabt expect` inherit the omp session id through the bash tool's environment. on nixos, `programs.roundabout.omp` exposes read-only `plugin` and `skill` options.70
+restart omp after linking. install `.#roundabout` on PATH for the agent's bash tool, or set `ROUNDABOUT_CLI` to the `roundabout` binary for the extension. the plugin bundles the skill and checks shell builds before they run. it also delivers overdue reminders, checks artifact caps before the main agent stops, and releases expectations when a session closes or switches. wrapped builds and `roundabout expect` inherit the omp session id through the bash tool's environment. on nixos, `programs.roundabout.omp` exposes read-only `plugin` and `skill` options.7171
7272
## config7373
@@ -98,7 +98,7 @@ linger = "5s"
9898
backfill_max_time = "2m"9999
# max_wait = "30m"100100
elastic = true # hand idle cores to whoever's building101
-intent_ttl = "20m" # how long a `rabt expect` or a build keeps its claim101
+intent_ttl = "20m" # how long a `roundabout expect` or a build keeps its claim102102
103103
[overrun]104104
ram = "warn" # or "throttle", MemoryHigh at granted RAM on linux@@ -9,5 +9,5 @@ runCommand "roundabout-omp-plugin-${roundabout.version}" { } ''
99
cp ${../plugin/omp/package.json} $out/package.json1010
cp ${../plugin/omp/index.js} $out/index.js1111
cp -r ${../plugin/skills}/. $out/skills/12
- ln -s ${lib.getExe roundabout} $out/bin/rabt12
+ ln -s ${lib.getExe roundabout} $out/bin/roundabout1313
''@@ -17,7 +17,7 @@ let
1717
};1818
mockCli = writeScript "roundabout-test-cli" ''1919
#!${lib.getExe nushell} --stdin20
- ${builtins.readFile ../tests/mock-rabt.nu}20
+ ${builtins.readFile ../tests/mock-roundabout.nu}2121
'';2222
in2323
runCommand "roundabout-omp-tests"@@ -18,7 +18,7 @@ rustPlatform.buildRustPackage {
1818
1919
meta = {2020
description = "build admission for agents that can't share";21
- mainProgram = "rabt";21
+ mainProgram = "roundabout";2222
license = lib.licenses.eupl12;2323
platforms = lib.platforms.unix;2424
};@@ -42,5 +42,5 @@ runCommand "roundabout-plugin-${roundabout.version}" { } ''
4242
cp ${plugin} $p/.claude-plugin/plugin.json4343
cp ${hooks} $p/hooks/hooks.json4444
cp -r ${../plugin/skills}/. $p/skills/45
- ln -s ${lib.getExe roundabout} $p/bin/rabt45
+ ln -s ${lib.getExe roundabout} $p/bin/roundabout4646
''@@ -2,10 +2,10 @@ import { spawn } from "node:child_process";
22
import { existsSync } from "node:fs";33
import { fileURLToPath } from "node:url";44
5
-const packagedCli = fileURLToPath(new URL("./bin/rabt", import.meta.url));5
+const packagedCli = fileURLToPath(new URL("./bin/roundabout", import.meta.url));66
77
function cli() {8
- return process.env.ROUNDABOUT_CLI || (existsSync(packagedCli) ? packagedCli : "rabt");8
+ return process.env.ROUNDABOUT_CLI || (existsSync(packagedCli) ? packagedCli : "roundabout");99
}1010
1111
function invoke(event, context, input = {}) {@@ -5,26 +5,26 @@ description: use before running any build, test suite or other heavy command (ca
55
66
# roundabout77
8
-this box is shared with other agents and a human who'd like their video to keep playing. builds queue through roundabout, whose cli is `rabt`, and only run when there's room.8
+this box is shared with other agents and a human who'd like their video to keep playing. builds queue through roundabout, whose cli is `roundabout`, and only run when there's room.99
1010
## first, say you're coming1111
1212
when you pick up a task that'll involve building, before you start editing1313
1414
```15
-rabt expect --size m15
+roundabout expect --size m1616
```1717
18
-sized like the biggest build you expect to run. idle cores get handed out to whoever's building, and this is how the others know to leave you some. it lapses 20 minutes after your last build or `expect`, so one call covers an edit-compile loop. `rabt expect --done` if the plan changes.18
+sized like the biggest build you expect to run. idle cores get handed out to whoever's building, and this is how the others know to leave you some. it lapses 20 minutes after your last build or `expect`, so one call covers an edit-compile loop. `roundabout expect --done` if the plan changes.1919
2020
## running something2121
2222
```23
-rabt run --size m -- cargo build24
-rabt run --ram 6G --cores 8 --time 10m --disk 4G -- nix build .#thing23
+roundabout run --size m -- cargo build24
+roundabout run --ram 6G --cores 8 --time 10m --disk 4G -- nix build .#thing2525
```2626
27
-wrap the build, not the whole pipeline. `cd x && rabt run -s m -- cargo test 2>&1 | tail` is fine.27
+wrap the build, not the whole pipeline. `cd x && roundabout run -s m -- cargo test 2>&1 | tail` is fine.2828
2929
sizes out of the box3030
@@ -35,7 +35,7 @@ sizes out of the box
3535
| l | 6G | 5G | half | 15m | release builds, big workspaces, nix closures |3636
| xl | 12G | 20G | all | 45m | rebuilding the world |3737
38
-`rabt suggest -- <cmd>` has numbers from previous runs of that command in this project. use them.38
+`roundabout suggest -- <cmd>` has numbers from previous runs of that command in this project. use them.3939
4040
guess honestly. under-asking is how the box ooms, and an honest `--time` is what lets small jobs slip past big ones. it tells you afterwards if you were off.4141
@@ -46,12 +46,12 @@ you may get more cores than you asked for when the box is quiet, `CARGO_BUILD_JO
4646
a queued build prints its place and why to stderr. for anything likely over a couple of minutes4747
4848
1. run the build with `run_in_background`49
-2. read the lease id from `rabt: lease N go`50
-3. also start `rabt watch N` with `run_in_background`. it exits when the build finishes or goes overdue, which wakes you up49
+2. read the lease id from `roundabout: lease N go`50
+3. also start `roundabout watch N` with `run_in_background`. it exits when the build finishes or goes overdue, which wakes you up5151
52
-in codex, use `exec_command` with a short `yield_time_ms` for the build, then poll its `session_id` with `write_stdin`. use another `exec_command` for `rabt watch N` if the build is likely to take longer. don't launch the build a second time while polling.52
+in codex, use `exec_command` with a short `yield_time_ms` for the build, then poll its `session_id` with `write_stdin`. use another `exec_command` for `roundabout watch N` if the build is likely to take longer. don't launch the build a second time while polling.5353
54
-in omp, use the bash tool's `async` option for the build and `omp ps` to follow its output. use another bash call for `rabt watch N` if you need an overdue reminder.54
+in omp, use the bash tool's `async` option for the build and `omp ps` to follow its output. use another bash call for `roundabout watch N` if you need an overdue reminder.5555
5656
`--max-wait 10m` gives up queueing after that (exit 75). `--deadline 30m` kills the build if it's still going (exit 124). only use a deadline when a late result is useless.5757
@@ -59,14 +59,14 @@ in omp, use the bash tool's `async` option for the build and `omp ps` to follow
5959
6060
you'll get told when a build is well past its time estimate. decide, don't ignore it6161
62
-- `rabt kill N` if it's stuck or not worth it63
-- `rabt extend N 15m` if it's making progress62
+- `roundabout kill N` if it's stuck or not worth it63
+- `roundabout extend N 15m` if it's making progress6464
65
-`rabt status` shows everything running and queued.65
+`roundabout status` shows everything running and queued.6666
6767
## artifacts6868
69
-build output is capped per project and in total. `rabt artifacts check` compares, `list` shows the offenders, `gc` clears idle stuff, `gc --cap` keeps going until under, `--project` leaves everyone else's stuff alone. `pin <path>` protects something you need.69
+build output is capped per project and in total. `roundabout artifacts check` compares, `list` shows the offenders, `gc` clears idle stuff, `gc --cap` keeps going until under, `--project` leaves everyone else's stuff alone. `pin <path>` protects something you need.7070
7171
if told you're over, clean up before you finish. scratch dirs full of `target/` and `result` links count too.7272
@@ -178,9 +178,9 @@ impl Report {
178178
179179
pub const fn remedy(&self) -> &'static str {180180
if self.over_global {181
- "rabt artifacts gc --cap"181
+ "roundabout artifacts gc --cap"182182
} else {183
- "rabt artifacts gc --project --cap"183
+ "roundabout artifacts gc --project --cap"184184
}185185
}186186
@@ -13,7 +13,7 @@ use crate::{
1313
1414
/// one build at a time, please1515
#[derive(Parse)]16
-#[pound(name = "rabt", version = env!("CARGO_PKG_VERSION"))]16
+#[pound(name = "roundabout", version = env!("CARGO_PKG_VERSION"))]1717
pub enum Rabt {1818
/// wait your turn, then run the thing1919
Run {@@ -167,7 +167,7 @@ fn artifacts(cfg: &Config, action: Artifacts) -> i32 {
167167
);168168
}169169
for f in &g.failed {170
- eprintln!("rabt: {f}");170
+ eprintln!("roundabout: {f}");171171
}172172
println!(173173
"{} {}",@@ -177,7 +177,7 @@ fn artifacts(cfg: &Config, action: Artifacts) -> i32 {
177177
i32::from(!g.failed.is_empty())178178
}179179
Artifacts::Pin { path } | Artifacts::Unpin { path } if !path.exists() => {180
- eprintln!("rabt: {} doesn't exist", path.display());180
+ eprintln!("roundabout: {} doesn't exist", path.display());181181
1182182
}183183
Artifacts::Pin { path } => report(artifacts::pin(&path, true)),@@ -188,7 +188,7 @@ fn artifacts(cfg: &Config, action: Artifacts) -> i32 {
188188
fn report(r: Result<(), String>) -> i32 {189189
r.map_or_else(190190
|e| {191
- eprintln!("rabt: {e}");191
+ eprintln!("roundabout: {e}");192192
1193193
},194194
|()| 0,@@ -207,16 +207,16 @@ fn reply(ev: io::Result<Option<Event>>) -> i32 {
207207
match ev {208208
Ok(Some(Event::Ok)) => 0,209209
Ok(Some(Event::Err { msg })) => {210
- eprintln!("rabt: {msg}");210
+ eprintln!("roundabout: {msg}");211211
1212212
}213213
Ok(None) => {214
- eprintln!("rabt: nothing running");214
+ eprintln!("roundabout: nothing running");215215
1216216
}217217
Ok(Some(_)) => 1,218218
Err(e) => {219
- eprintln!("rabt: {e}");219
+ eprintln!("roundabout: {e}");220220
1221221
}222222
}@@ -237,7 +237,7 @@ fn agent_session(session: Option<String>) -> Option<String> {
237237
238238
fn expect(cfg: &Config, session: Option<String>, done: bool, a: &run::Args) -> i32 {239239
let Some(session) = session.filter(|s| !s.is_empty()) else {240
- eprintln!("rabt: no agent session id, use --session to name one");240
+ eprintln!("roundabout: no agent session id, use --session to name one");241241
return 2;242242
};243243
let need = if done {@@ -246,7 +246,7 @@ fn expect(cfg: &Config, session: Option<String>, done: bool, a: &run::Args) -> i
246246
match run::need(cfg, a) {247247
Ok(n) => Some(n),248248
Err(e) => {249
- eprintln!("rabt: {e}");249
+ eprintln!("roundabout: {e}");250250
return 2;251251
}252252
}@@ -254,12 +254,12 @@ fn expect(cfg: &Config, session: Option<String>, done: bool, a: &run::Args) -> i
254254
let mut s = match client::connect_or_spawn() {255255
Ok(s) => s,256256
Err(e) => {257
- eprintln!("rabt: can't reach the daemon: {e}");257
+ eprintln!("roundabout: can't reach the daemon: {e}");258258
return 1;259259
}260260
};261261
if let Err(e) = proto::send(&mut s, &Request::Expect { session, need }) {262
- eprintln!("rabt: {e}");262
+ eprintln!("roundabout: {e}");263263
return 1;264264
}265265
reply(Reader::new(&s).and_then(|mut r| r.recv()))@@ -335,7 +335,7 @@ fn suggest(cfg: &Config, cmd: &[String]) -> i32 {
335335
let base = match run::base(cfg) {336336
Ok(b) => b,337337
Err(e) => {338
- eprintln!("rabt: {e}");338
+ eprintln!("roundabout: {e}");339339
return 2;340340
}341341
};@@ -361,7 +361,7 @@ fn watch(lease: u64) -> i32 {
361361
Reader::new(&s).and_then(|mut r| r.recv::<Event>()),362362
Ok(Some(Event::Fired { overdue: true }))363363
) {364
- println!("lease {lease} is overdue, `rabt kill {lease}` or `rabt extend {lease} <dur>`");364
+ println!("lease {lease} is overdue, `roundabout kill {lease}` or `roundabout extend {lease} <dur>`");365365
3366366
} else {367367
println!("lease {lease} is done");@@ -99,8 +99,8 @@ fn head(seg: &[String]) -> &[String] {
9999
}100100
}101101
102
-fn is_rabt(word: &str) -> bool {103
- word == "rabt" || word.ends_with("/rabt")102
+fn is_roundabout(word: &str) -> bool {103
+ word == "roundabout" || word.ends_with("/roundabout")104104
}105105
106106
fn matches_pattern(seg: &[String], pattern: &str) -> bool {@@ -124,7 +124,7 @@ fn scan(cfg: &Config, cmd: &str) -> Scan {
124124
let mut found = Vec::new();125125
for seg in segments(cmd) {126126
let seg = head(&seg);127
- if seg.first().is_some_and(|w| is_rabt(w)) {127
+ if seg.first().is_some_and(|w| is_roundabout(w)) {128128
continue;129129
}130130
if cfg.detect_patterns().any(|p| matches_pattern(seg, p)) {@@ -186,9 +186,9 @@ fn pre_tool_use(cfg: &Config, input: Input) {
186186
let hint = guess(cfg, &cwd, &first);187187
let reason = format!(188188
"builds go through roundabout here so parallel agents don't oom the box. wrap each build \189
- in `rabt run <size> -- <cmd>`, e.g. `rabt run {hint} -- {}`. sizes are {}, or \189
+ in `roundabout run <size> -- <cmd>`, e.g. `roundabout run {hint} -- {}`. sizes are {}, or \190190
give --ram/--disk/--cores/--time yourself. for anything long use \191
- run_in_background and start `rabt watch <lease>` in the background too so you \191
+ run_in_background and start `roundabout watch <lease>` in the background too so you \192192
hear if it drags. see the roundabout skill",193193
found[0],194194
cfg.sizes.keys().cloned().collect::<Vec<_>>().join("/"),@@ -204,7 +204,7 @@ fn pre_tool_use(cfg: &Config, input: Input) {
204204
(Scan::Unwrapped(_), Unwrapped::Wrap) => {205205
let hint = guess(cfg, &cwd, std::slice::from_ref(&cmd));206206
tool_input["command"] =207
- Value::String(format!("rabt run {hint} -- bash -c {}", shell_quote(&cmd)));207
+ Value::String(format!("roundabout run {hint} -- bash -c {}", shell_quote(&cmd)));208208
// no permissionDecision on purpose. allow would skip the user's209209
// prompt for whatever the agent wrote, rewriting shouldn't210210
emit(&json!({@@ -232,7 +232,7 @@ fn codex_pre_tool_use(cfg: &Config, input: Input) -> Option<Value> {
232232
let first: Vec<String> = found[0].split_whitespace().map(Into::into).collect();233233
let hint = guess(cfg, &cwd, &first);234234
let reason = format!(235
- "builds go through roundabout here so parallel agents don't oom the box. run `rabt run {hint} -- {}` instead. see the roundabout skill",235
+ "builds go through roundabout here so parallel agents don't oom the box. run `roundabout run {hint} -- {}` instead. see the roundabout skill",236236
found[0]237237
);238238
Some(json!({@@ -267,7 +267,7 @@ fn overdue(session: &str) -> Vec<LeaseInfo> {
267267
}268268
}269269
270
-/// same source `rabt run` reads. after `--continue` the env var can keep the270
+/// same source `roundabout run` reads. after `--continue` the env var can keep the271271
/// startup id while the json moves on, and we need both ends to agree272272
fn session(input: &Input, codex: bool) -> String {273273
if codex {@@ -307,8 +307,8 @@ fn remind(event: &str, input: &Input, codex: bool) {
307307
.iter()308308
.map(|l| {309309
format!(310
- "roundabout lease {} (`{}`) has run {} against a {} estimate. `rabt kill {}` to stop it, \311
- `rabt extend {} <dur>` if it's worth the wait",310
+ "roundabout lease {} (`{}`) has run {} against a {} estimate. `roundabout kill {}` to stop it, \311
+ `roundabout extend {} <dur>` if it's worth the wait",312312
l.id,313313
l.cmd.join(" "),314314
Dur::secs(l.elapsed),@@ -336,7 +336,7 @@ fn stop(cfg: &Config, event: &str, input: &Input) {
336336
return;337337
}338338
let msg = format!(339
- "{}. run `{}`, or `rabt artifacts list` and clear out what you don't need",339
+ "{}. run `{}`, or `roundabout artifacts list` and clear out what you don't need",340340
report.describe(cfg),341341
report.remedy()342342
);@@ -373,7 +373,7 @@ pub fn main(cfg: &Config, event: &str) -> i32 {
373373
"post-tool-use" => remind("PostToolUse", &input, false),374374
"prompt-submit" => remind("UserPromptSubmit", &input, false),375375
"session-end" => session_end(&input, false),376
- other => eprintln!("rabt: unknown hook {other}"),376
+ other => eprintln!("roundabout: unknown hook {other}"),377377
}378378
0379379
}@@ -400,7 +400,7 @@ mod tests {
400400
output["hookSpecificOutput"]["permissionDecisionReason"]401401
.as_str()402402
.unwrap()403
- .contains("rabt run")403
+ .contains("roundabout run")404404
);405405
}406406
@@ -416,7 +416,7 @@ mod tests {
416416
#[test]417417
fn codex_ignores_other_tools_and_wrapped_builds() {418418
assert!(419
- codex_pre_tool_use(&Config::default(), bash("rabt run -s m -- cargo build")).is_none()419
+ codex_pre_tool_use(&Config::default(), bash("roundabout run -s m -- cargo build")).is_none()420420
);421421
let mut input = bash("cargo build");422422
input.tool_name = Some("apply_patch".into());@@ -25,7 +25,7 @@ fn main() {
2525
// a typo must not exit 2, that's a blocking pretooluse verdict and would2626
// wall off every bash call in every session2727
let cfg = config::Config::load().unwrap_or_else(|e| {28
- eprintln!("rabt: bad config, using defaults. {e}");28
+ eprintln!("roundabout: bad config, using defaults. {e}");2929
config::Config::default()3030
});3131
std::process::exit(cli::dispatch(&cfg, cli::Rabt::parse()));@@ -52,7 +52,7 @@ extern "C" fn forward(sig: libc::c_int) {
5252
}5353
5454
fn say(msg: &str) {55
- eprintln!("rabt: {msg}");55
+ eprintln!("roundabout: {msg}");5656
}5757
5858
pub fn need(cfg: &Config, a: &Args) -> Result<Need, String> {@@ -209,7 +209,7 @@ pub fn run(cfg: &Config, a: &Args) -> i32 {
209209
if a.size.is_none() && a.ram.is_none() {210210
let sizes: Vec<_> = cfg.sizes.keys().map(String::as_str).collect();211211
say(&format!(212
- "how big is it? pass --size {} or --ram and friends. `rabt suggest -- <cmd>` has a guess",212
+ "how big is it? pass --size {} or --ram and friends. `roundabout suggest -- <cmd>` has a guess",213213
sizes.join("|")214214
));215215
return 2;@@ -247,7 +247,7 @@ pub fn exec() -> Option<i32> {
247247
};248248
let error = Command::new(&program).args(arguments).exec();249249
eprintln!(250
- "rabt: couldn't start {}: {error}",250
+ "roundabout: couldn't start {}: {error}",251251
program.to_string_lossy()252252
);253253
Some(127)@@ -42,14 +42,14 @@ function input() {
4242
}4343
4444
test("maps build guards and preserves wrapped command arguments", async () => {45
- output({ hookSpecificOutput: { permissionDecision: "deny", permissionDecisionReason: "use rabt run" } });46
- assert.deepEqual(await handlers.get("tool_call")(bash, context), { block: true, reason: "use rabt run" });45
+ output({ hookSpecificOutput: { permissionDecision: "deny", permissionDecisionReason: "use roundabout run" } });46
+ assert.deepEqual(await handlers.get("tool_call")(bash, context), { block: true, reason: "use roundabout run" });4747
assert.equal(input().event, "omp-pre-tool-use");4848
assert.equal(input().input.tool_name, "Bash");49
- output({ hookSpecificOutput: { updatedInput: { command: "rabt run -s m -- cargo build" } } });49
+ output({ hookSpecificOutput: { updatedInput: { command: "roundabout run -s m -- cargo build" } } });5050
const result = await handlers.get("tool_call")({ ...bash, input: { ...bash.input, cwd: "/project" } }, context);5151
assert.equal(input().input.cwd, "/project");52
- assert.equal(result.input.command, "rabt run -s m -- cargo build");52
+ assert.equal(result.input.command, "roundabout run -s m -- cargo build");5353
assert.equal(result.input.async, true);5454
assert.deepEqual(result.input.env, { KEEP: "yes", ROUNDABOUT_SESSION_ID: "omp-session" });5555
});@@ -60,7 +60,7 @@ test("fails open for malformed output, nonzero exits and missing CLI", async ()
6060
output({ hookSpecificOutput: { permissionDecision: "deny" } });6161
process.env.ROUNDABOUT_TEST_EXIT = "1";6262
assert.equal((await handlers.get("tool_call")(bash, context)).block, undefined);63
- process.env.ROUNDABOUT_CLI = join(temporary, "missing-rabt");63
+ process.env.ROUNDABOUT_CLI = join(temporary, "missing-roundabout");6464
assert.equal((await handlers.get("tool_call")(bash, context)).block, undefined);6565
});6666
@@ -80,7 +80,7 @@ test("maps artifact policies and bounds advisory continuations", async () => {
8080
});8181
8282
test("the CLI tracks OMP sessions ahead of inherited agent identities", () => {83
- const rabt = process.env.ROUNDABOUT_TEST_RABT;83
+ const roundabout = process.env.ROUNDABOUT_TEST_RABT;8484
const config = join(temporary, "config.toml");8585
writeFileSync(config, '[queue]\nlinger = "1s"\n');8686
const env = {@@ -93,7 +93,7 @@ test("the CLI tracks OMP sessions ahead of inherited agent identities", () => {
9393
CODEX_THREAD_ID: "inherited-codex",9494
};9595
function run(args, payload) {96
- const result = spawnSync(rabt, args, { env, input: payload, encoding: "utf8", timeout: 10000 });96
+ const result = spawnSync(roundabout, args, { env, input: payload, encoding: "utf8", timeout: 10000 });9797
assert.equal(result.status, 0, result.stderr);9898
return result.stdout;9999
}@@ -18,7 +18,7 @@ fn gated_command(program: &str, arguments: &[&str]) -> (Child, OwnedFd) {
1818
let read = unsafe { OwnedFd::from_raw_fd(descriptors[0]) };1919
let write = unsafe { OwnedFd::from_raw_fd(descriptors[1]) };2020
let descriptor = read.as_raw_fd();21
- let mut command = Command::new(env!("CARGO_BIN_EXE_rabt"));21
+ let mut command = Command::new(env!("CARGO_BIN_EXE_roundabout"));2222
command2323
.args(["__roundabout_exec", &descriptor.to_string(), program])2424
.args(arguments)@@ -39,7 +39,7 @@ fn gated_command(program: &str, arguments: &[&str]) -> (Child, OwnedFd) {
3939
4040
#[test]4141
fn command_waits_for_scope_setup() {42
- let (mut child, gate) = gated_command(env!("CARGO_BIN_EXE_rabt"), &["--version"]);42
+ let (mut child, gate) = gated_command(env!("CARGO_BIN_EXE_roundabout"), &["--version"]);4343
let mut output = libc::pollfd {4444
fd: child.stdout.as_ref().unwrap().as_raw_fd(),4545
events: libc::POLLIN,@@ -53,13 +53,13 @@ fn command_waits_for_scope_setup() {
5353
assert!(5454
String::from_utf8(output.stdout)5555
.unwrap()56
- .starts_with("rabt ")56
+ .starts_with("roundabout ")5757
);5858
}5959
6060
#[test]6161
fn failed_scope_setup_never_executes_the_command() {62
- let (child, gate) = gated_command(env!("CARGO_BIN_EXE_rabt"), &["--version"]);62
+ let (child, gate) = gated_command(env!("CARGO_BIN_EXE_roundabout"), &["--version"]);6363
drop(gate);6464
let output = child.wait_with_output().unwrap();6565
assert_eq!(output.status.code(), Some(1));@@ -118,7 +118,7 @@ fn transient_scope_enforces_the_grant() {
118118
"[overrun]\nram = \"throttle\"\n[queue]\nlinger = \"0s\"\n",119119
)120120
.unwrap();121
- let output = Command::new(env!("CARGO_BIN_EXE_rabt"))121
+ let output = Command::new(env!("CARGO_BIN_EXE_roundabout"))122122
.args([123123
"run", "--ram", "64M", "--disk", "0", "--cores", "1", "--time", "5s", "--exact", "--",124124
])