The portfolio repo lives on my laptop. The Claude sandbox writing the about page lived somewhere else. It could read what I pasted in, generate files, and reason about my codebase, but it could not push to GitHub or even cd into ~/Documents/Github/rohan-portfolio-astro. So I needed a way to take its output and drop it into the repo without doing the busywork by hand.
The shape I landed on is what I now call a bundle shipper. Every shippable feature gets a folder on my Desktop. Inside that folder is one script, one source directory, and one README. The script is set -euo pipefail. The README opens with the one command I have to run when I’m back at my Mac. That command does the rest end to end.
The about-page-bundle is the canonical example. ship.sh validates the repo path, syncs master, cuts feat/about-page-photo-scrub, copies ten WebP frames into public/about/photo/, writes the component, writes the page, patches the nav best-effort, runs the build, makes three atomic commits, and pushes the branch. Vercel picks up the push and deploys a preview. I get a printed list of SHAs and the expected preview URL pattern.
The pattern works because it pushes the decision-making upstream (into the agent) and the side effects downstream (into the script). The agent never touches my filesystem. The script never makes design choices. The handoff is one paste, and the cleanup at the end is also a printed list of rm commands so nothing is auto-deleted.
The principle: an agent that can’t reach your machine is still useful if it can compose a script your machine will run. Treat the bundle as the contract.