Run Ysra from a script
Run one task to the end with ysra exec, for scripts, CI and containers: choose the task and folder, output formats, approvals, limits and exit codes.
On this page
ysra exec runs one task in a folder from start to finish and exits, with no
screen and nothing to type. It is for scripts, CI jobs and containers;
ysra -p is the same command. This page covers the options,
what is printed, the exit codes and signing in; every option is also in the
command reference.
$ ysra exec "add a --verbose flag to the CLI and test it"
The rule#
A run leaves its work as changes in the folder’s files. Unless --allow
names them, it never creates a branch, commits, pushes, publishes or deploys,
and it never creates .git in a folder without Git. Anything that would need
a person either stops the run with exit 2 or, with --approval auto, is
decided by the rules below.
Give the task and the folder#
| To | Write |
|---|---|
| Give a task | ysra exec "<task>" |
| Give a task that starts with a dash | ysra exec -- "-v prints nothing: fix it" |
| Send input with the task | git diff | ysra exec "review this change" |
| Make the piped input the task | … | ysra exec - (or no task at all) |
| Work in another folder | -C <dir> or --cd <dir>: with Git or without; nothing is set up in it. Paths in the task are read against it |
| Go on in this folder’s last thread | --continue |
| Go on in a given thread | --resume <thread> |
$ ysra exec -C ./service --output-format json "why does the build fail?"
What is printed#
--output-format |
What it prints |
|---|---|
text (default) |
Ysra’s last message, on standard output. When standard error is a terminal, each step shows there as it happens |
json |
One JSON object at the end: the result |
stream-json |
One JSON object per line as Ysra works, each with its time (ts), ending with the result |
--trace <file.jsonl> also writes every raw event the CLI receives to that
file and keeps the local transcript (~/.ysra/transcript-….jsonl). Where the
API offers it, the server’s record of the run is saved beside it as
<file>.server.json, at most --trace-max-mb (default 512 MB). An API without it, or a record refused or cut short, is noted in the
result, never a failure.
The result#
The result object ends json and stream-json output.
| Field | What it holds |
|---|---|
type |
Always result |
status |
done, unverified, failed, refused, needs_approval, needs_input, out_of_credits, account_paused, interrupted, timeout, max_turns or stop_unconfirmed |
pause_reason |
Why the thread is paused, when it is: unverified, interrupted, out_of_budget (the credit limit was reached), cancelled, rewound. Otherwise null |
exit_code |
The exit code, as in Exit codes |
thread |
The thread’s id, to continue with --resume. Empty when the run never started |
result |
Ysra’s last message |
summary |
A summary of the work, when there is one |
question |
What Ysra needs, when it stopped for a decision or an answer |
credits_used |
Credits this run used |
decisions |
Each question met and the answer taken, with --approval auto |
errors |
What went wrong, if anything |
review, review_rounds |
With --review mayz (and ysra mayz --print): the last Mayz report, and how many reviews ran |
limit, stop, turns, max_turns_enforced_by |
With --timeout or --max-turns: what ended the run, whether the server confirmed the work stopped (confirmed, unknown, not_live), the model calls made, and whether the server or only this client enforced the turn limit |
computer_backups |
With --allow-computer-writes: each file overwritten and the copy kept first |
trace |
With --trace: where the run was kept |
notes |
Things worth knowing about how the run was done |
The events#
With stream-json, each line has a type. Only what a person would see on
screen is printed.
type |
What it is |
|---|---|
start |
The run started: the thread, the folder, the approval setting, and whether it continues a thread |
message |
Something Ysra says |
step |
Something Ysra did, and whether it failed |
note |
A status line, with its tone |
plan |
Ysra’s plan, as numbered steps |
question |
A question Ysra asks, with its choices when there are some |
decision |
A question and the answer taken for it |
error |
An error |
result |
The last line: the result above |
Who decides when nobody is there#
| Setting | When Ysra would ask |
|---|---|
--approval ask (default) |
The run stops at the first decision, leaves it open, prints the question and exits 2. With --approve-plan, a plan is accepted instead of stopping there |
--approval auto |
Ysra goes ahead with what the work in the folder needs: plans, commands, installs, Docker for this thread, deleting files in the folder. It declines what reaches outside the folder: commits, pull requests, pushes, publishes, deploys and remote machines. On Windows, commands that delete never run |
--approval read-only |
Ysra only looks: nothing in the folder is changed, installed or deleted. Use it for questions, reviews and reports |
--approval auto --allow <kinds> |
The same, and also goes ahead with the kinds named: commit, push, deliver (a draft pull request), deploy, publish, undo. Interrupting the work, remote machines and the whole computer stay off |
What --approval auto needs, and what it still won’t do:
| Situation | What happens |
|---|---|
Not in a container, no --yes-i-am-sandboxed |
--approval auto is refused. Add --yes-i-am-sandboxed on a disposable machine (a VM, a CI runner) |
A command would run the project’s code (tests, scripts, builds) uncontained, without --yes-i-am-sandboxed |
The run stops with exit 2 |
| A question needs a typed answer, or a sign-in only a person can do | Not guessed: the run stops with that question |
| A stop that asks nothing, or whose only choice is Carry on | Continued, a few times at most |
Running as root (or with password-free sudo) in a container or with --yes-i-am-sandboxed |
Missing packages are installed with apt-get, apk, dnf or yum, without prompts; Git too |
| Git is missing otherwise | The run stops before it starts and says what to install |
ysra started as root or an elevated Administrator |
Refused, unless YSRA_ALLOW_ROOT=1 (a container made for the run) |
| An organisation policy file turns an option off | That option is refused; nothing on the command line turns it back on. See Environment |
$ ysra exec --approval auto --output-format stream-json -C /app "make the tests pass"
$ ysra exec --approval auto --yes-i-am-sandboxed --allow commit,push "fix it and push"
The home folder or the whole disk#
--allow-home lets the folder be the home folder or the top of the disk,
where the service offers it. There, commands only read and can't reach the
network; where that isn't possible, commands are refused. With nobody at the
keyboard only plain looks run; anything else stops the run with exit 2.
Commands never write there.
--allow-computer-writes <path>,… adds file creates and edits through Ysra’s
own write tool, inside those paths only, with --approval auto:
| Rule | Value |
|---|---|
| Paths | Absolute, inside your home folder |
| Per write | At most 20 files, 5 MB a file |
| Backups | Each edited file is copied first to ~/.ysra/computer-backups/<run>/ |
| Never | Deletes, moves, installs, upgrades or permission changes; keys, credentials, shell start-up files and system places, even when listed |
With --approval ask |
Every write still asks |
Limits on a run#
| Option | What happens when it is reached |
|---|---|
--max-credits <n> (1 to 50,000) |
Ysra stops before the thread uses more than n credits; exit 3 |
--timeout <dur> (90s, 15m, 2h, 1h30m; a plain number is seconds) |
The work is interrupted at its next safe point and kept; exit 8 |
--max-turns <n> |
Once the thread has made n model calls in this run, the work is interrupted at its next safe point and kept; exit 9 |
| Either limit, and the server doesn’t confirm in time that the work stopped | Exit 10, status stop_unconfirmed: the work may still be running on the server |
Have Mayz review the work#
--review mayz has Mayz review the work in the same
thread when it is done. While Mayz says it needs work (or is unsafe), Ysra
fixes the findings and Mayz reviews again, up to --review-rounds reviews in
all (1 to 5, default 2: a review, the fixes, a review of the fixes). The exit
code then carries the last verdict (5, 6 or 7).
$ ysra exec --approval auto --review mayz --timeout 30m --trace run.jsonl "build the API"
Model and effort#
| Option | What it does |
|---|---|
--mode spark|forge|summit |
A Code mode: Spark for small, clear jobs, Forge for everyday building (the default), Summit for large or tricky work. --model and --effort win over it |
--model <name> |
Use this model. An unknown one stops the run: “There’s no model called … Choose one of: …” |
--effort quick|balanced|thorough |
How hard Ysra thinks (low, medium, high work too). Default: your setting |
Answer and continue#
When a run stops for a decision or an answer, the text output ends with the question and the command to answer it:
$ ysra exec "upgrade the date library"
…
Ysra needs a decision: Run the migration on the test database?
Answer with: ysra exec --resume 5f0c… "<your answer>"
$ ysra exec --resume 5f0c… "yes, go ahead with the plan"
Exit codes#
| Code | Status | What it means | What to do |
|---|---|---|---|
0 |
done |
Done, and every check passed. With --review mayz: Mayz says ready |
Review the changes and keep them |
1 |
failed, interrupted |
Failed, or stopped with Ctrl+C. Also: the folder couldn’t be connected, the place to run it wasn’t ready, the device was unavailable, or Git is missing; the reason is printed | Read errors; fix the cause and run again |
2 |
needs_approval, needs_input |
Needs an approval or an answer. The question is printed | Answer and continue with --resume |
3 |
out_of_credits, account_paused |
Out of credits, or the account is paused | See When credits run out |
4 |
refused |
The task was declined | See When a session stops by itself |
5 |
done or unverified |
--review mayz: Mayz still says it needs work after the last review |
Read review; run again with --resume or more --review-rounds |
6 |
done or unverified |
--review mayz: Mayz says it’s unsafe after the last review |
Read review before using the change |
7 |
done or unverified |
--review mayz: the review didn’t finish, or no report came |
Run the review again |
8 |
timeout |
--timeout was reached; the work is kept |
Continue with --resume, or allow more time |
9 |
max_turns |
--max-turns was reached; the work is kept |
Continue with --resume, or allow more turns |
10 |
stop_unconfirmed |
A limit was reached but the server didn’t confirm the work stopped | Check the thread before starting another run on the same folder |
11 |
unverified |
Finished and the changes are written, but not every check finished. The result says which | Check what is unproven before keeping the change. CLIs before 1.12 returned 0 here |
12 |
folder_missing |
The thread’s folder has been deleted or moved: “That folder isn't there any more.” | Run again with -C pointing at the folder where it is now |
$ ysra exec --output-format json "update the changelog" > result.json
$ echo $?
0
Sign in from a script#
Run ysra login once on a computer you use yourself. In CI, a container or
any place without a browser, set FORGE_API_TOKEN to a Ysra API token
instead: nothing is saved on that computer.
$ FORGE_API_TOKEN=… ysra exec "make the tests pass"
The token is used only to reach Ysra. The commands a run starts don’t get it in their environment.
A token from this computer’s sign-in#
ysra auth token prints a short-lived access token from this computer’s
sign-in, and nothing else, for a program that runs Ysra where you aren’t
signed in, such as a container. Sign in once with ysra login, or
ysra login --device on a machine without a browser.
$ FORGE_API_TOKEN="$(ysra auth token)" ysra exec -C /work "fix the build"
| Rule | Value |
|---|---|
| Lifetime of the printed token | At least 30 more minutes (Ysra refreshes the sign-in first when needed) |
| What is printed | Only the short-lived token; the refresh token stays on this computer |
| Not signed in | Exit 1, with the reason |
If it doesn’t work#
| Symptom | Likely cause | What to do |
|---|---|---|
--approval auto is refused |
Not in a container | Add --yes-i-am-sandboxed on a disposable machine only |
Exit 2 at a test or build command with --approval auto |
Project code would run uncontained | Run in a container, or add --yes-i-am-sandboxed |
Exit 1, “needs Git on this machine” |
Git is missing | Install Git (apt-get install -y git) and run again |
Exit 1 before a start event |
Not signed in, or the token expired | ysra login, or pass a fresh FORGE_API_TOKEN |
Exit 10 |
The server didn’t confirm the stop | Open the thread and check it has stopped |
Related#
- Command reference — every option of
ysra execin one table. - How a Code thread works — the task states behind
done,unverifiedand the rest. - Mayz — what a review checks and how verdicts are reached.