What the agent does
The agent clones the app into its own cloud sandbox and reads what is already there, because a SvelteKit app is often halfway to a PWA. In an app like sveltejs/realworld, src/app.html already carries <link rel="manifest" href="/manifest.json" />, and static/manifest.json exists with name Svelte RealWorld, short_name RealWorld, display minimal-ui, theme_color #5cb85c, start_url / and a single icon, logo-256.png at 256x256. What is missing is the rest: there is no src/service-worker.js, no theme-color meta tag in app.html, and the manifest has no 192 or 512 pixel icons, which is what an install prompt looks for. package.json pins @sveltejs/kit ^2.52.2, Svelte ^5.55.7 with runes: true in svelte.config.js, Vite ^7.3.2 and packageManager pnpm@10.20.0; .nvmrc says Node 20 and .npmrc sets engine-strict=true, so the agent uses that Node and that pnpm.
Then it reads how the app talks to the world, because that decides what a service worker may cache. src/lib/api.js sends every request to https://api.realworld.show/api and src/hooks.server.js reads the signed-in user from a jwt cookie on every request, so API responses and server-rendered pages carry user state and must never be served from cache. src/app.html also loads Ionicons and Google Fonts from third-party CDNs, and static/conduit-theme.css is the stylesheet. The login form in src/routes/login/+page.server.js is a form action that sets the cookie and redirects, which a service worker must pass straight through.
The service worker it writes at src/service-worker.js uses the $service-worker module SvelteKit provides: build is the list of hashed files Vite emitted, files is everything under static/, and version changes on every build, so the cache name is derived from it. On install it caches build and files, on activate it deletes caches from earlier versions, and its fetch handler serves hashed build assets and static files from cache, lets any request whose method is not GET and any request to the API origin go to the network untouched, and uses network-first with a cached fallback for same-origin pages so a visited page still renders when the network is gone. SvelteKit registers a worker at that path automatically in production builds, so no registration code goes into +layout.svelte.
The manifest and shell get the small fixes that make the install prompt work: a theme-color meta in app.html matching the manifest, a 192 pixel icon resized from logo-256.png, and a note in the pull request that a 512 pixel icon needs the original artwork, since scaling the 256 pixel file up would blur it. The agent then runs pnpm build and pnpm preview, opens the preview in the sandbox browser, confirms the worker is registered and the manifest validates in the browser's application panel, loads the home page and an article, switches the browser offline and reloads both. pnpm lint, which is prettier --check ., runs last. The repository has no test suite and no workflow directory, so those two checks are the whole gate.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Add PWA support to this SvelteKit app. Read src/app.html, static/manifest.json, src/lib/api.js, src/hooks.server.js and src/routes/login/+page.server.js first. Write src/service-worker.js using build, files and version from $service-worker: precache the build and static files on install, delete older caches on activate, never cache non-GET requests or requests to the external API origin, and serve same-origin pages network-first with a cached fallback. Add a theme-color meta tag to app.html that matches the manifest, add a 192 pixel icon resized from the existing logo, and say in the pull request that a 512 pixel icon needs source artwork. Use the Node version in .nvmrc and the pnpm version in packageManager. Run pnpm build and pnpm preview, open the preview in the browser, check that the worker registers and the manifest validates, then go offline and reload the home page and an article page. Run pnpm lint. Open a pull request that describes each caching rule and why API responses and form actions are excluded, with a screenshot of the offline reload.",
"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 on its own branch that adds src/service-worker.js and a 192 pixel icon under static/, and changes static/manifest.json and src/app.html. The description lists the caching rules one by one: what is precached from build and files, why the cache name comes from version, why requests to the API origin and every non-GET request bypass the worker, and how same-origin pages fall back to cache. It carries the screenshot of the offline reload from the sandbox browser and the pnpm build and pnpm lint output.
The session read names the repository and the pull request URL, and the screenshot is one of the session's artifacts with a download link that lasts an hour per read. The transcript at GET /o/{org}/sessions/{id}/messages keeps the build, the preview start, each page the browser loaded and the offline reloads, so a reviewer can see the worker working without checking the branch out.
Before merging, a reviewer checks that no fetch handler branch can return a cached response for a request that carried the jwt cookie to the API, that the activate step really clears the previous version's cache so a deploy is not stuck on old assets, and that the manifest still parses. The deploy itself is unchanged: svelte.config.js keeps @sveltejs/adapter-vercel, and the worker is served as a static file the adapter already handles.
Run it on every new SvelteKit repository
A team that starts SvelteKit apps from a template can send this request once per new repository, from a script on the developer's machine or from the console, with resources pointing at the new repository. Each run makes its own branch and pull request, so several new apps can be set up in parallel without touching each other.
Set a webhook URL on the key and Rush POSTs run.completed when the turn ends, with data.session_url to read the pull request from. A follow-up to the same session, for instance to add the 512 pixel icon once design supplies it, wakes the parked sandbox with the build already in place.
The use case this job follows, with its automation and trigger: Hand off from your terminal.
Why run it on Rush?
Checking a service worker honestly means a production build, a preview server and a browser you can switch offline, then doing it again after every change to the fetch handler. The agent has all three in its sandbox, so the pull request arrives with an offline reload already seen rather than described, and your laptop never has a stale worker registered against localhost from a half-finished attempt.
The caching rules are the risk in this job, and the record shows them being exercised. Every build, every page load and the offline reloads are in the transcript, and the screenshot is an artifact on the session. When the review asks for a change, a follow-up to the same session picks up the same build and browser where they were left.
Frequently asked questions
Will it cache API responses or the signed-in user's pages?
No. src/lib/api.js sends requests to a separate origin and the agent excludes that origin in the fetch handler, and every non-GET request, including the login form action, passes through untouched. Same-origin pages are fetched from the network first and only fall back to a cached copy when the network fails.
Does the service worker run in pnpm dev?
Not by default. SvelteKit registers src/service-worker.js in production builds, which is why the agent checks it through pnpm build and pnpm preview rather than the dev server. The pull request says so, so nobody looks for it in development and thinks it is missing.
What happens to the icons?
The agent adds a 192 pixel icon by scaling the existing 256 pixel logo down, which keeps it sharp, and lists it in the manifest. It does not fabricate a 512 pixel icon from a smaller file; the pull request asks for source artwork for that one and the manifest entry is left for it.
Does this change the Vercel deployment?
No. svelte.config.js still uses @sveltejs/adapter-vercel, and the worker, manifest and icons are served the way the adapter serves other static files. Nothing in the build command or the environment changes.