What the agent does
The agent reads the issue, then finds the file the behaviour lives in, which in a file-based Vue app is a matter of convention. In an app like antfu-collective/vitesse, src/pages/ is the router: index.vue is /, hi/[name].vue is /hi/:name, about.md is a Markdown page at /about, and [...all].vue is the 404. Layouts are chosen per page with a <route lang="yaml"> block, as index.vue picks home. Components in src/components/ and composables in src/composables/ are auto-imported, so there is no import line to follow; vite.config.ts registers unplugin-auto-import with src/composables and src/stores as directories and unplugin-vue-components for .vue and .md. State is a Pinia store in src/stores/user.ts, whose setNewName moves the previous name into otherNames. Text comes from locales/*.yml through vue-i18n, loaded lazily by loadLanguageAsync in src/modules/i18n.ts.
That structure decides where the fix goes. An issue about the greeting goes to src/pages/hi/[name].vue, which sets the name from route.params.name in a watchEffect and lists user.otherNames as links. An issue about the name box is src/components/TheInput.vue (the id="input" element) and the go() function in index.vue, which encodeURIComponents the name before router.push. An issue about a missing translation is a key in locales/en.yml and the other 18 locale files, and an issue about the language switch is toggleLocales in src/components/TheFooter.vue, which steps through availableLocales in order. A dark mode issue is src/composables/dark.ts, three lines over useDark and useToggle from VueUse.
The reproduction uses the suite the app has. vite.config.ts points Vitest at test/**/*.test.ts in a jsdom environment, and test/component.test.ts shows the pattern: mount from @vue/test-utils, props passed in, wrapper.text() and wrapper.get('.inc').trigger('click'), plus a snapshot in test/__snapshots__/. A store bug gets a test that creates a fresh Pinia with setActivePinia(createPinia()) and calls setNewName twice. A page bug gets a mount with a router, or a case in cypress/e2e/basic.spec.ts, which visits http://localhost:3333, types into #input, expects the /hi/Vitesse URL and clicks [data-test-id="about"]. The new case fails first on the issue's input, and the pull request quotes that.
Then the agent runs the four jobs from .github/workflows/ci.yml with the pinned toolchain: pnpm@10.30.2 from packageManager, pnpm install --frozen-lockfile, pnpm run lint under @antfu/eslint-config, pnpm run typecheck with vue-tsc --noEmit, pnpm run test:unit --run and pnpm run build through vite-ssg build, and for a page change npx vite preview --port 3333 with cypress run. A new component or page regenerates src/components.d.ts or src/route-map.d.ts, and the agent commits the regenerated file so typecheck passes on a clean checkout. The pull request body says Closes #<issue> and explains the cause in the words of the file.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Fix the GitHub issue that follows this prompt in this Vue 3 app built with Vite, file-based routing in src/pages, auto-imported components and composables, a Pinia store in src/stores and vue-i18n locales in locales/*.yml. Find the page, component, store or locale file the behavior lives in. Reproduce the reported behavior first: a Vitest case in test/ using mount from @vue/test-utils and a fresh Pinia where the store is involved, or a case in cypress/e2e/basic.spec.ts for a routing or page behavior. Confirm it fails. Fix the cause, keep the diff small, and commit any regenerated src/components.d.ts or src/route-map.d.ts. Use pnpm 10.30.2 and pnpm install --frozen-lockfile, then run pnpm run lint, pnpm run typecheck, pnpm run test:unit --run and pnpm run build; for a page change also serve npx vite preview --port 3333 and run cypress run. Open a pull request whose description says Closes #<issue>, explains the cause and quotes the failing then passing test.\n\nIssue #31: Visiting /hi/Ana%20Lu shows the raw percent-encoded name in the greeting and in the Also known as list.",
"resources": [
{
"url": "https://github.com/your-org/your-app"
}
]
}- 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 with Closes #<issue> in its body. The diff holds the new test in test/ or cypress/e2e/, the change in the page, component, store or locale file, and any regenerated declaration file. The description names the cause in the file's own terms, such as the watchEffect in hi/[name].vue or the encodeURIComponent in index.vue, and quotes the test failing before the fix and the vitest summary after.
The reviewer reads the test first and confirms it fails on main. They check the fix stayed where the issue was: a locale change touches locales/en.yml and the matching key in the other files rather than hard-coding a string in a template, a store change keeps savedName and otherNames consistent, and a regenerated .d.ts adds only the new name. The push runs ci.yml on GitHub, so lint, typecheck, both test rows and test-e2e confirm the sandbox's result.
The session holds the whole record: the failing vitest run, the edits, each CI command and the Cypress output if a page changed. GET /o/{org}/sessions/{id} returns the pull request once the turn has finished, and a follow-up can ask the same sandbox to add a case for another locale.
Run it on every GitHub issue labelled agent
In the console, add an automation to the Project with this prompt and a github trigger on issues.labeled, filtered to the agent label in config.labels. The trigger appends the issue after the prompt, so leave the example issue out of the automation's prompt. Only labels added by an owner, member or collaborator fire it, by GitHub's author_association, so a stranger's issue cannot start a run. Each labelled issue gets its own sandbox, branch and pull request.
The same request can come from your own triage tool through POST /o/{org}/sessions, with the issue's text after the prompt and the delivery id as the Idempotency-Key. Set a webhook_url on the key and Rush POSTs run.completed when the turn finishes, with the session_url that reads the pull request.
The use case this job follows, with its automation and trigger: Turn a Linear label into a PR.
Why run it on Rush?
A Vue issue in a file-routed app is quick to fix and slow to prove: the right pnpm, a frozen install, vue-tsc, Vitest, an SSG build, and a browser running Cypress against vite preview, with generated declaration files that must be committed or typecheck fails only on CI. A Rush run does all of that in its own sandbox with a browser, from a clean clone, and keeps every command, so the pull request shows the failing test rather than describing it.
The fix is small because the agent reads the page, store and locale conventions before editing, and lands where the issue lives. Several labelled issues run at once, each on its own branch, and each ends in a pull request whose own four CI jobs confirm it, or in a note saying why the issue could not be reproduced.
Frequently asked questions
Where does a new test go?
In test/, matched by test/**/*.test.ts in vite.config.ts, next to basic.test.ts and component.test.ts, with mount from @vue/test-utils and a jsdom environment. A routing or whole-page behaviour goes into cypress/e2e/basic.spec.ts or a new spec matching cypress/e2e/**/*.spec.*.
Does it handle all 19 locales?
It adds a key to locales/en.yml and, when the issue is about a translation, to the file for that language; other locale files fall back as vue-i18n is configured. It does not machine-translate the key into every file, and the pull request lists the files it changed.
Why does the pull request include a .d.ts file?
Because src/components.d.ts, src/auto-imports.d.ts and src/route-map.d.ts are generated by the plugins in vite.config.ts and committed. A new component or page changes them, and pnpm run typecheck on CI fails on a clean checkout without the regenerated file.
Will it run Cypress for every issue?
Only when the fix touches a page, layout or route, since cypress/e2e/basic.spec.ts is the only spec and it covers navigation, the name form and the Markdown page. A store or composable fix is proven by Vitest, and the pull request says which it ran.
What if the issue is about the Netlify deploy?
netlify.toml builds with pnpm run build on Node 22 and redirects every path to index.html. The agent reproduces with the same vite-ssg build and vite preview; a redirect or header issue is a change to netlify.toml or public/_headers, which it makes and explains, but it cannot run Netlify itself.