All jobs

Turn GitHub Issues into Pull Requests for a Go Project

Yes. Label a GitHub issue on a Go project and an agent reads it, adds a test, runs go test, and opens a pull request that links the issue.

Run this on RushIn a Project that has your repository.

What the agent does

The agent starts from the labelled issue, not from a generic Go layout. In a command-line repository shaped like charmbracelet/glow it opens go.mod and reads the module path charm.land/glow/v3 and the directive go 1.26.7, then the require block: github.com/spf13/cobra v1.10.2, charm.land/glamour/v2 and charm.land/bubbletea/v2. The command surface is the Cobra tree in main.go. rootCmd is declared with Use glow [SOURCE|DIR], and the only subcommands added are configCmd and manCmd. Flags such as pager, style and width live as package variables beside that command. The issue text decides the file: a flag bug sits next to those variables, a URL bug sits in github.go, and a rendering bug sits under ui/.

github.go is a concrete example of how small the change usually is. findGitHubREADME splits the URL path into owner and repo, then GETs https://api./repos///readme and unmarshals download_url. A README-URL bug is a change in that function plus a test, not a new HTTP client. url.go and url_test.go already cover argument parsing, so the new case goes there when the issue is about how a path or a URL becomes a source.

The test suite is short, and the agent treats that as part of the job rather than a reason to skip tests. The tree contains glow_test.go, url_test.go, ui/ui_test.go, ui/pager_test.go, ui/rawpaint_test.go and utils/textsize_test.go. glow_test.go's TestGlowFlags is a table of rootCmd.ParseFlags cases for -p, -s light and -w 40. A new flag gets a row in that table. Anything else gets a Test function in the same package as the code it covers. Taskfile.yaml names the command the repository already uses: the test task runs go test ./... and the lint task runs golangci-lint run. The agent runs go test ./... so ui and utils are included, and it does not add a second task runner.

It leaves the release wiring alone. .github/workflows/build.yml does not invoke go test itself. The build, snapshot, govulncheck, semgrep and ruleguard jobs call reusable workflows in charmbracelet/meta, and the ruleguard job passes go-version 1.26. The agent keeps the go directive at 1.26.7 and does not bump a dependency to make a test compile. When the new test fails for a reason the issue did not describe, the pull request says so and stops, instead of rewriting style.go or the pager to force a green suite.

Start it with one API call

POST https://api.prix.dev/o/{org}/sessions with this body:

{
  "agent": "claude",
  "input": "Resolve GitHub issue #ISSUE in this repository. Read the issue and its comments first. In a repo laid out like charmbracelet/glow, start from go.mod (module charm.land/glow/v3, Go 1.26.7) and the Cobra commands in main.go. Make the change the issue asks for, add a test beside the code you change (extend TestGlowFlags in glow_test.go when it is a flag, otherwise a test in the same package), and run go test ./... as Taskfile.yaml's test task does. Do not bump the go directive, do not edit .github/workflows, and do not retitle goreleaser. Open a pull request whose body says Fixes and the issue number, and include the test command output.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
  1. 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.
  2. 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.
  3. 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 on a new branch. The diff is the production file the issue pointed at, often main.go, github.go, url.go or a file under ui/, plus one test file. The body starts with Fixes and the issue number, lists the files, and quotes the go test ./... output from the sandbox. Existing workflow files and go.mod's go directive are unchanged unless the issue itself asked for them.

The session read names the repository and the pull request URL. The transcript at GET /o/{org}/sessions/{id}/messages keeps each tool call: the issue read, the files opened, the go test ./... invocation and its output. A reviewer does not have to re-run the suite to see what the agent ran.

Before merging, a reviewer checks that the new test fails on the old code and passes on the branch, that the Go version is still 1.26.7, and that the pull request does not quietly upgrade cobra, glamour or bubbletea. The GitHub keyword Fixes closes the issue when the pull request merges, so the link in the body is the check that the right issue is attached.

Run it on every labelled GitHub issue

Point a GitHub webhook at your server for issues. On issues.labeled, and only for the label you reserve for the agent, POST this body to https://api.prix.dev/o/{org}/sessions with the repository in resources and the issue number written into input in place of #ISSUE. Send an Idempotency-Key derived from the delivery id so a retried webhook returns the same session instead of opening a second pull request. The Rush GitHub App has to be installed on the repository or resources answers 422 RESOURCE_NOT_ACCESSIBLE.

Set a webhook URL on the API key. When the turn finishes, Rush POSTs run.completed, run.failed or run.cancelled to that URL, signed with the whsec_ secret, and data.session_url is the session to read for the pull request. A key allows at most max_concurrent runs at once, 4 by default, and answers 429 past that, so a label applied across an old backlog should be queued rather than fired all at once.

The use case this job follows, with its automation and trigger: Turn a Linear label into a PR.

Why run it on Rush?

Fixing a Glow-sized issue on a laptop means checking out a branch, remembering that the suite is go test ./... from the Taskfile rather than a single package, and pushing before you know whether ui/ still compiles. The agent does that in its own sandbox, with its own clone, and the sandbox parks with its disk when the turn ends. Closing the laptop does not drop the branch.

The proof is the pull request plus the transcript, not a claim that the tests passed. You can see the exact go test ./... output and which file the new test landed in. Several labelled issues can run at once, each in its own sandbox and each with its own pull request, up to the key's max_concurrent limit.

Frequently asked questions

Will it rewrite the goreleaser or meta workflows?

No. The prompt tells it to leave .github/workflows alone. build.yml only calls charmbracelet/meta reusable workflows, and a fix for an issue does not belong there. If the issue is itself about CI, say so in the prompt or the agent will refuse that part and still avoid a drive-by edit.

The repository has only a handful of tests. Does it still add one?

Yes. Glow's own tree is the pattern: six test files, and TestGlowFlags is a small table. The agent adds a case in that table or a new Test in the same package as the change. It does not import a new testing framework, and it does not skip the test because coverage is thin.

Does it run golangci-lint as well as go test?

The suite it must run is go test ./..., which is the test task in Taskfile.yaml. The lint task is golangci-lint run. Ask for lint in the prompt when you want that too. A lint failure on code the issue did not touch is reported in the pull request rather than cleaned up across the module.

Which Go version does the sandbox use?

The one go.mod declares. In Glow that is 1.26.7, and the ruleguard workflow pins 1.26, so the agent does not pick a newer toolchain to make a test compile. If that toolchain is not available, the answer says so instead of rewriting the go directive.

How does the issue text reach the agent?

Your server copies the issue number, title and body into input when it handles issues.labeled. resources only clones the repository. The agent then reads the issue and its comments with the GitHub credentials the App installation provides. A delivery you retry with the same Idempotency-Key and the same body returns the original session.