jouet pronounced “zhweh” · French for “toy”Wind-up tools for coding agents
jouet tells an agent which builds and tests are slow before it runs them, and turns what keeps going wrong into rules, tasks and routines for later sessions. It also has commands for the edits, searches, CI waits and PR reviews that agents otherwise script by hand.
Early development. How much jouet helps depends on your project, and yours may need some configuration, or a fix in jouet, before it does. Commands and output may change incompatibly until 1.0. What to expect →
How it works
Learning from past sessions
jouet keeps the timings, failures and corrections from past sessions, and uses them to steer the next one.
jouet also has commands for work agents usually script by hand: a code graph, searches and reads that stay within a budget, only the tests a change affects, edits that check before they write, and waits that poll for you. Three of them, next to the scripts they replace:
beforeA Python heredoc edits one file at a time
CheckWritesrc/main.rs1 assert passes2 writtenCargo.toml3 AssertionError never runs
Each file is written as soon as its own assert passes.
exit 1Half edited. src/main.rs changed, Cargo.toml did not, and the error does not say so.
inside python3 - <<'EOF'
python
for path, old, new in edits: s = Path(path).read_text() assert s.count(old) == 1, path Path(path).write_text(s.replace(old, new))
output
Traceback (most recent call last): File "<stdin>", line 7, in <module>AssertionError: Cargo.toml
afterjouet edit checks every edit, then writes all or none
1 · Check every edit2 · Write all or nonesrc/main.rs1 matches once3 not writtenCargo.toml2 no match3 failed
1 of 2 edits failed, so no file is written.
exit 4Refused, so nothing changed. The closest match shows that Cargo.toml moved on to 0.1.1.
the spec, on stdin
spec
=== src/main.rs<<<<<<< SEARCH let x = 1;======= let x = 2;>>>>>>> REPLACE=== Cargo.toml<<<<<<< SEARCHversion = "0.1.0"=======version = "0.2.0">>>>>>> REPLACE
output
not written src/main.rs 1 edit +1 -1failed Cargo.toml 1 edit edit 1: no match closest at line 3 (94% similar), - spec / + file: -version = "0.1.0" +version = "0.1.1"0 of 2 files written
beforeA grep loop reads the whole log, the last run included
app.log
Starting server
Listening on http://localhost:3000 matched at 0s, from the last run
Shutting down
server restarts
Starting server
Listening on http://localhost:3000
grep reads from the top, so the last run's line counts.
done at 0sToo early: the old line matches before this server is up. If the line never comes, the loop never ends.
sh
until grep -q 'Listening on' app.log; do sleep 2done
afterjouet wait log reads only lines written after it starts
app.log
Starting server
Listening on http://localhost:3000
Shutting down
the wait starts
Starting server
Listening on http://localhost:3000 matched at 10s
Lines already in the file are skipped.
met at 10sIt prints the line that matched. If none comes by --timeout, it exits 124 instead of hanging.
beforeThe agent polls, and every check costs a model turn
7 model turns log read at 7 min
1234567
0m2m4m6m8mcheck fails
1–2 pending
3 a check failed
4–6 --log-failed refuses: the run is still going
7 the run ends; the log, at last
7 turnsEach turn re-reads the whole conversation. The failed job's log stays locked until the entire run ends, and a conflicted PR never gets CI, so the polling never stops.
sh
sleep 60; gh pr checks 42# …next turn: the same againgh run view 41083340820 --log-failed
afterjouet wait ci blocks in one call and returns at the first failure
1 model turn log read at 3 min
jouet wait ci1
0m2m4m6m8mcheck fails
1 returns at the failure, with the failed step's log
no turns spent while it waits
1 turnIt returns with the failed step's log while the run is still going, and exits 4 straight away for a conflicted PR.
sh
jouet wait ci 15195 --repo jdx/mise --check release
output
FAIL jdx/mise#15195 @ 843cc16 0 pass, 1 fail, 0 skipped, 0 pending (3s)FAIL release step "Require auto-merge on the release PR" required https://github.com/jdx/mise/actions/runs/41083340820/job/124157989724 ##[error]Enable auto-merge on this pull request to build and test the release tarballs. ##[error]Process completed with exit code 1. full log: ~/.local/state/jouet/logs/jdx-mise-job-124157989724.log
Illustrative timing: 60-second polls, a check that fails 3 minutes in, and a run that ends at 7.
Reference
Commands
Each replaces a script or loop that agents commonly write. When an agent writes one anyway, a hook points it to the command.