What the agent does
The agent reads the command's surface before the diff, because in a CLI the review is mostly about what a flag does and what the user sees. In charmbracelet/glow, module charm.land/glow/v3 on Go 1.26.7, main.go defines rootCmd with Use: "glow [SOURCE|DIR]", Args: cobra.MaximumNArgs(1), and the flags --config, -p/--pager, -t/--tui, -s/--style, -w/--width, -a/--all, -l/--line-numbers, -n/--preserve-new-lines and a hidden -m/--mouse, each bound to Viper so glow.yml and GLOW_* environment variables can set it. validateOptions reads those values back, refuses --pager with --tui, checks a custom style path exists, switches to the notty style when stdout is not a terminal and no --style was passed, and caps auto-detected width at 120 with a fallback of 80. sourceFromArg turns - into stdin, a github:// or gitlab:// or bare host path into a README URL through url.go, an http or https URL into a fetched body, a directory into the first README it finds, and anything else into a file. config_cmd.go writes a defaultConfig and opens it in EDITOR.
Then it reads what the repository already checks. .github/workflows/coverage.yml runs go test -race -covermode atomic -coverprofile=profile.cov ./...; lint.yml runs golangci-lint with --issues-exit-code=0 and only-new-issues, so lint never fails the build; build.yml calls Charm's shared workflows for build, snapshot, govulncheck, semgrep and ruleguard with Go 1.26. .golangci.yml is a version 2 config with run.tests: false and enables bodyclose, exhaustive, goconst, godot, gosec, misspell, nilerr, noctx, revive, wrapcheck and others, with gofumpt and goimports as formatters; main.go already carries //nolint:gosec, //nolint:nestif and //nolint: noctx,bodyclose where it knows it breaks them. Taskfile.yaml has lint as golangci-lint run and test as go test ./.... The agent runs go vet ./..., go test -race ./..., golangci-lint run and gofumpt -l . in the sandbox and quotes each.
The tests are few and specific, which shapes what the agent can prove. glow_test.go parses -p, -s light and -w 40 through rootCmd.ParseFlags and checks the package-level variables; url_test.go maps github.com/charmbracelet/glow, github://caarlos0/dotfiles.fish and GitLab forms to raw README URLs but is skipped because it uses the network; ui/pager_test.go sets GLOW_TEXT_SIZING=on and asserts that an H2 is wrapped in the OSC 66 s=2 escape while an H1 with a background is not; ui/ui_test.go, ui/rawpaint_test.go and utils/textsize_test.go cover the rest. A pull request that adds a flag without a case in TestGlowFlags, or changes rendering without a case beside TestGlamourRenderTextSizing, gets a finding that names the test to extend, and the agent writes that case in the sandbox to confirm the behaviour before it says so.
The diff is read with the three questions the prompt names. Flag handling: a new flag needs a BindPFlag line, a viper.SetDefault where the config file should carry it, a mention in defaultConfig, and a read in validateOptions, since the flag variables are overwritten from Viper there; a flag read directly from its variable skips the config file. Terminal output: executeCLI builds a glamour.TermRenderer with the style, WithWordWrap(width), a base URL for relative links and WithPreservedNewLines, wraps non-markdown sources in a code block by extension, and pipes to PAGER or less -r through shell.Fields; a change that writes to os.Stdout directly instead of the io.Writer passed in, or that ignores the notty style, is a finding. Error messages: the repository wraps every error with fmt.Errorf("...: %w", err) and wrapcheck enforces it, rootCmd.Execute exits 1 after closing the log, and sourceFromArg returns missing markdown source for a directory with no README; a bare return err, a log.Fatal inside the TUI, or a message that prints a raw path the user did not type is flagged with the line. One GitHub review is posted per run and nothing is pushed.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Review this pull request on a Go CLI built with Cobra, Viper and Bubble Tea. Check it out, run go vet ./..., go test -race ./..., golangci-lint run with the repository's .golangci.yml and gofumpt -l ., and read the diff with main.go, config_cmd.go, url.go, ui/config.go and the tests beside them. Look for flags added without a BindPFlag, a default, a defaultConfig entry and a read in validateOptions; output written straight to os.Stdout instead of the writer the function takes, or rendering that ignores the notty style when stdout is not a terminal; errors returned unwrapped where wrapcheck expects fmt.Errorf with %w, or messages that leak internal paths; and behaviour changes with no case in glow_test.go, url_test.go or ui/pager_test.go. Confirm a finding with a short test in the sandbox where you can, but do not add it to the branch. Post one GitHub review that quotes the vet, race, lint and gofumpt results, separates blocking issues from suggestions, and cites file and line for every finding. Do not push commits.",
"resources": [
{
"url": "https://github.com/your-org/your-app/pull/42"
}
]
}- 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 review on the pull request. Its summary quotes go vet ./..., go test -race ./... with any race report, golangci-lint run with the linters that fired, and the files gofumpt -l listed. Findings follow with file and line in main.go, ui/ or utils/, marked blocking or suggestion, and a flag finding lists the four places the flag must be wired through.
The transcript keeps the module download, every command with its output, and the short tests the agent wrote to confirm a finding, so when the review says a new flag is ignored when set from glow.yml, the parse that proved it is in the record.
Before merging, a reviewer runs go test -race ./... on the branch, tries the new flag from a terminal and from a pipe, and opens each cited line. A race report, a wrapcheck failure or a flag that skips Viper is blocking by default; a godot or misspell note is not, which matches the repository's own --issues-exit-code=0.
Run it on every pull request opened
Create an automation in the Project with a github trigger on pull_request.opened and pull_request.synchronize, branch_patterns set to main, and this prompt. The trigger adds the pull request after the prompt, so every pull request and every push to it gets its own sandbox, its own module cache and its own review, and a read_only automation comments without pushing.
The review is the result on the pull request and the run is listed in the Project. max_runs_per_hour, 1 to 30, keeps the monthly grouped Dependabot update that .github/dependabot.yml configures to a bounded number of runs; a fire past the cap is skipped as rate_limited and the pull request is reviewed on its next push.
The use case this job follows, with its automation and trigger: Review every pull request.
Why run it on Rush?
A CLI change is judged by what the user sees, and that depends on whether stdout is a terminal, what PAGER is set to, whether a config file exists and how wide the window is. Reading the diff tells a reviewer none of that; running the binary from a pipe and from a pty with a glow.yml in XDG_CONFIG_HOME does. On Rush the agent has its own sandbox with a terminal, builds the branch, runs the race detector and the linters the repository configures, and keeps every command's output, so the review of a flag or a rendering change rests on something that ran.
One sandbox per pull request keeps reviews parallel and the branch untouched; the author keeps their checkout and the reviewer gets findings with the go test -race and golangci-lint output attached, in the same form the repository's coverage.yml and lint.yml would report later.
Frequently asked questions
Does it run golangci-lint the way the repository does?
It uses .golangci.yml, a version 2 config with run.tests: false, so test files are not linted. The repository's lint.yml passes --issues-exit-code=0 and only-new-issues, so the review quotes the findings but blocks only on ones the pull request introduced.
Can it test the TUI?
The unit tests in ui/ render a pager model without a terminal, and the agent can extend those in the sandbox. A full glow session in TUI mode is started from a pty in the sandbox to check it draws and quits, and the review labels anything observed that way as a manual check rather than a test.
What about the skipped URL test?
url_test.go is skipped because it fetches README URLs from GitHub and GitLab. A change to url.go, github.go or gitlab.go is confirmed by a table test of the URL construction alone, written in the sandbox, so the review does not depend on the network.
Which Go version does it build with?
go.mod says 1.26.7 and build.yml runs ruleguard with Go 1.26, so the agent uses that toolchain. A diff that raises the go directive or depends on a newer standard library API is a finding with the line.