What the agent does
The agent reads the alert payload after the prompt, then opens the issue and its latest event through the Sentry connection. For a command-line tool the event carries a panic message with its frames, or an error the tool reported itself, plus whatever the CLI attached as tags: the subcommand and arguments, the shell, the operating system. It keeps the frame's file and line and the command line as the two facts the test must reproduce.
Then it reads the crate. In ajeetdsouza/zoxide, Cargo.toml names version 0.10.0, edition 2024 and rust-version 1.88.0, with anyhow for errors, clap 4.3 with derive for the commands in src/cmd/cmd.rs, askama 0.16 for the shell templates under templates/, bincode 1.3 for the database file, glob for exclude patterns and ouroboros for the self-referential database; dev-dependencies are assert_cmd, rstest, rstest_reuse and tempfile. src/main.rs is 35 lines: it removes RUST_BACKTRACE, runs Cmd::parse().run(), turns a SilentExit into its exit code and prints anything else as zoxide: {e:?} to stderr. Errors are anyhow contexts such as _ZO_DATA_DIR must be an absolute path in src/config.rs, not a directory: {path} in src/cmd/add.rs and could not write to stdout from the BrokenPipeHandler in src/error.rs, so an event message usually points straight at the line.
The agent picks the test shape from the module. A ranking or matching bug lives in src/db/: src/db/dir.rs scores an entry at rank times 4, 2, 0.5 or 0.25 depending on whether it was used within the hour, the day, the week or longer ago, and src/db/stream.rs filters by base directory, exclude globs, existence (with symlink_metadata when symlinks are resolved) and keywords, where the last keyword must match inside the last path component. Those modules already have tests: mod tests in src/db/mod.rs opens a database in a tempfile::tempdir() at epoch 946684800 and checks add and remove, and src/db/stream.rs has an rstest table of keyword cases such as ["foo", "/"] against /foo/bar. The agent adds a case with the path and keywords from the event. A shell integration bug lives in templates/posix.txt and its siblings, where __zoxide_z falls through to zoxide query --exclude "$(__zoxide_pwd)" -- "$@"; src/shell.rs renders each template under an rstest template over the cmd, hook, echo and resolve_symlinks options and runs it through bash, dash, shellcheck, shfmt, fish, nu, pwsh, zsh and xonsh, so a new case there proves a fix in the template.
With the test failing for the same reason the event shows, the agent changes the one function or template and runs what justfile runs in CI: cargo clippy --all-features --all-targets -- -Dwarnings, cargo fmt --all --check, cargo msrv verify against 1.88.0, and the tests with cargo nextest run --all-features --no-fail-fast --workspace, or cargo test where nextest is unavailable. The shell tests need the shells installed, and the repository runs them inside nix-shell, so the agent installs the shells the failing case needs and says in the description which ones ran.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "A Sentry alert fired for this Rust CLI; its payload follows this prompt. Use the Sentry connection to read the issue, its latest event, the panic or error message, the frames with their file and line, and the tags that carry the command line and the shell. In a crate shaped like ajeetdsouza/zoxide, find the function the frames point at under src/cmd/, src/db/, src/config.rs or src/util.rs, or the shell template under templates/ when the shell integration misbehaved. Write a test in the style the module already has: an rstest case in src/db/stream.rs or src/shell.rs, a tempdir-based test in src/db/mod.rs, or an assert_cmd test against the built binary with _ZO_DATA_DIR pointed at a temporary directory. Confirm it fails with the same message as the event, then fix the cause in that one function or template without catching the panic or hiding the error. Run cargo clippy --all-features --all-targets -- -Dwarnings, cargo fmt --all --check, cargo msrv verify and cargo test --all-features --no-fail-fast, installing any shell a new shell test needs. Open a pull request that links the Sentry issue, quotes the message and frames and the failing test output, and explains the cause. If it does not reproduce, stop and report what you tried.\n\nAlert payload:\n{payload}",
"resources": [
{
"url": "https://github.com/your-org/your-app"
}
],
"connections": [
"sentry"
]
}- Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
- Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
- Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.
What comes back
What comes back is a pull request that changes one function under src/ or one template under templates/ and adds a test case beside the existing ones. Its description links the Sentry issue, quotes the message and the frames or the command line, shows the new case failing before the change and passing after, and gives the cargo test, clippy, fmt and cargo msrv verify results, naming which shells were installed for a shell test. Cargo.toml and Cargo.lock do not change.
Before merging, a reviewer checks that a scoring or matching change keeps the existing rstest cases green, since those encode what users expect from z foo, that a template change passes shellcheck and shfmt the way src/shell.rs demands, and that the fix changes the decision rather than wrapping it in a fallback. If the event came from a release older than main and the line already changed, the description says so and the test pins the current behavior.
Run it on every Sentry issue alert
Create an alert rule in the Sentry project for the CLI with a webhook action pointed at a handler on your server; Sentry signs its own requests and cannot add the Authorization: Bearer header a Rush webhook trigger needs. The handler places the alert JSON after the prompt and sends this request with the Sentry issue id as Idempotency-Key, so the same issue redelivered returns the run already started.
Set a webhook URL on the API key and Rush POSTs run.completed with session_url when the turn ends; the handler can comment the pull request link on the issue. A CLI reports the same crash from many machines, and Sentry folds those into one issue, so one issue is one run; the handler can also skip issues that already have an open pull request.
The use case this job follows, with its automation and trigger: Fix a bug from an alert.
Why run it on Rush?
A CLI bug depends on a shell, a data directory, a symlink or a pipe, and a laptop has one shell configured one way. On Rush the agent sets those conditions in a test in its own sandbox, installs fish or nu or pwsh when the case needs it, points _ZO_DATA_DIR at a temporary directory so no real database is touched, and runs the one test that matters before the whole suite.
The pull request carries its own proof: the Sentry event the agent read, the case failing with the event's message and passing after the change, and the exact clippy, fmt and MSRV output in the transcript. Several alerts are several sandboxes at once, and a reviewer judges a diff instead of reconstructing someone else's terminal.
Frequently asked questions
A terminal tool reporting to Sentry? What is in the event?
Whatever your CLI's Sentry setup sends: the panic message and frames from the panic integration, and the tags you attach, such as the subcommand, the arguments and the shell. The agent uses the frames to find the function and the tags to build the input; a CLI that only sends the message still gives it the line through anyhow's context text.
Will the tests touch my real zoxide database?
No. The existing tests open the database in a tempfile::tempdir(), and a binary-level test sets _ZO_DATA_DIR to a temporary directory, which src/config.rs requires to be absolute. The sandbox has no user data in any case.
Does it need every shell installed?
Only the shells the failing case runs through. src/shell.rs tests each template with its own interpreter plus shellcheck and shfmt, and the repository runs them in nix-shell; the agent installs what the new case needs and lists in the description which shell tests ran.
What about cargo msrv verify and udeps?
cargo msrv verify checks the crate still builds on rust-version 1.88.0 and the agent runs it; cargo udeps needs a nightly toolchain and is run when the fix touched Cargo.toml, which a Sentry fix normally does not. The description names which lint steps ran.
What if the fix is in the fzf interaction?
src/util.rs wraps fzf in the Fzf and FzfChild types, and query_interactive in src/cmd/query.rs reads the selection from it. The agent installs fzf in the sandbox, writes a test that feeds it a known list, and if the behavior depends on a specific fzf version it says so and pins the version in the test.