{"id":50619066,"url":"https://github.com/mathijs81/inca","last_synced_at":"2026-06-11T14:01:13.209Z","repository":{"id":362653973,"uuid":"1260138096","full_name":"mathijs81/inca","owner":"mathijs81","description":"Run coding agents (Claude Code, Cursor, Copilot CLI) in disposable Incus VMs. Let your agents work unsupervised in no-permissions mode without having access to your whole machine.","archived":false,"fork":false,"pushed_at":"2026-06-10T12:57:54.000Z","size":42,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-10T13:22:50.124Z","etag":null,"topics":["ai-agents","claude-code","coding-agents","cursor","developer-tools","devtools","github-copilot","incus","linux","sandbox","vm"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mathijs81.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-05T07:34:49.000Z","updated_at":"2026-06-10T12:57:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mathijs81/inca","commit_stats":null,"previous_names":["mathijs81/incus-agents","mathijs81/inca"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mathijs81/inca","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathijs81%2Finca","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathijs81%2Finca/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathijs81%2Finca/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathijs81%2Finca/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mathijs81","download_url":"https://codeload.github.com/mathijs81/inca/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathijs81%2Finca/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34201842,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-11T02:00:06.485Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agents","claude-code","coding-agents","cursor","developer-tools","devtools","github-copilot","incus","linux","sandbox","vm"],"created_at":"2026-06-06T09:02:50.327Z","updated_at":"2026-06-11T14:01:13.141Z","avatar_url":"https://github.com/mathijs81.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Inca\n\n**INC**us **A**gents — run coding agents (Claude Code, Cursor CLI, GitHub Copilot\nCLI) in disposable [Incus](https://linuxcontainers.org/incus/) VMs, so you can let\nthem work in `--dangerously-skip-permissions` / no-confirmation mode without giving\nthem your laptop. Each instance is a throwaway VM cloned from a baked golden image;\nyour real machine only ever talks to it over SSH and a shared project directory.\n\nEverything is gated through a [`just`](https://github.com/casey/just) file — no\nhidden state, just readable recipes.\n\n## Why\n\nAgents are most useful when they can run commands, edit files, and install\nthings without asking. That's also exactly when you don't want them on your host.\nThis gives each agent a real Linux box (own kernel, Docker, sudo) that you can\nreset to a clean state in seconds and whose only window onto your host is the\nproject directories you explicitly share into it.\n\n## How it works\n\n1. A **builder** VM is provisioned from a cloud Ubuntu image via cloud-init,\n   then your toolchain (mise + the agents) is installed into it.\n2. That builder is **baked** into a reusable golden image — tools included, **no\n   credentials**.\n3. Each `just up` launches a fresh **instance** from the golden image, injects\n   your SSH key, replays saved agent credentials, and re-shares your projects.\n4. Your code lives on the **host** at `~/inca-work/\u003cvm\u003e/\u003cproject\u003e` and is shared\n   into the VM over virtiofs at `work/\u003cproject\u003e` — near-native speed, no rsync\n   round-trips. You edit and run git on the host; the agent works the same files\n   live inside the VM. `just reset` for a clean slate; the host copy survives.\n\nCredentials are captured **once** to `~/.config/inca-creds` (chmod 700,\noutside this repo) and replayed into each instance. They're never baked into the\nimage.\n\n## Requirements\n\n- Linux host with **Incus \u003e= 7.0** and hardware virtualization (`/dev/kvm`). On a\n  virtualized host you need nested virt, or you can fall back to system\n  containers (weaker isolation). The distro package is usually older than 7.0 and\n  ignores `io.cache` on virtiofs shares (breaking `mmap`, e.g. JVM/JaCoCo), so\n  install from the upstream LTS repo — see the\n  [install guide](https://linuxcontainers.org/incus/docs/main/installing/) and\n  [upstream packages](https://github.com/zabbly/incus).\n- `rsync` and `ssh` (and `sshfs` only for the deprecated `just mount`).\n- An SSH keypair (`~/.ssh/id_ed25519`).\n\nRun `just doctor` — it checks all of the above and prints actionable hints.\n\n## Quick start\n\n```sh\njust doctor            # preflight: incus, KVM/nested virt, RAM, tooling, base image\njust provision         # build + install tools into a builder VM\njust bake              # publish the builder as the golden image\njust up inca-vm        # launch a fresh instance from the golden image\njust login inca-vm     # one-time: run each agent's /login flow inside the VM\njust save-creds inca-vm # capture agent creds to the host (do this once)\n```\n\nFrom then on, spinning up a ready-to-go agent box is just:\n\n```sh\njust up another-box  # fresh VM, your creds already inside\n```\n\n## Daily use\n\nYour projects live on the host at `~/inca-work/\u003cvm\u003e/\u003cproject\u003e` and are shared into\nthe VM over virtiofs at `work/\u003cproject\u003e`. Get a project in one of two ways:\n\n```sh\njust clone \u003cgit-url\u003e inca-vm          # clone host-side (your creds) into inca-work, then share\njust take ~/code/myproject inca-vm    # copy an existing dir into inca-work, then share\n```\n\nThen work — editing and git happen on the **host**; the agent sees the same files\nlive in the VM:\n\n```sh\njust ssh inca-vm                      # shell in and turn the agent loose\njust forward 3000 5173                # forward guest dev-server ports to localhost\ngit gui                               # …or just run your tools natively against ~/inca-work/inca-vm/myproject\n```\n\nManage shares directly when you need to:\n\n```sh\njust share myproject inca-vm          # (re)attach ~/inca-work/inca-vm/myproject\njust unshare myproject inca-vm        # detach (host copy untouched)\njust reshare inca-vm                  # re-attach everything under ~/inca-work/inca-vm/ (run by `up`)\n```\n\nLifecycle:\n\n```sh\njust list             # all instances\njust stop inca-vm     # freeze (keeps disk state)\njust start inca-vm    # resume\njust reset inca-vm    # destroy + relaunch clean from golden (host projects re-shared on boot)\njust destroy inca-vm  # delete for good\n```\n\nRun `just` with no arguments for the full grouped list. The old rsync/sshfs\nrecipes (`sync-in`, `sync-out`, `mount`) live in a `deprecated` group — use them\nonly when you deliberately don't want to share host files into an untrusted VM.\n\n\u003e **Trust note:** a shared dir gives the (untrusted) VM read-write access to that\n\u003e host directory. Only share repos you'd push anyway. Everything else on your host\n\u003e stays out of reach. Host uid 1000 maps to the VM's `dev` user, so ownership lines\n\u003e up without extra config.\n\n## Configuration\n\nDefaults live in [`config/vm.env`](config/vm.env) and are safe to override per\nhost (VM name, image, CPU/RAM, user, storage pool, network, golden-image alias).\nOther knobs:\n\n- [`config/mise-global.toml`](config/mise-global.toml) — toolchain mirrored into\n  the VM (node, java, tmux, …). Keep roughly in sync with your host config.\n- [`config/cred-paths.txt`](config/cred-paths.txt) — which agent auth files get\n  captured and replayed. Add a line when you adopt another agent.\n- [`config/rsync-excludes.txt`](config/rsync-excludes.txt) — reconstructable\n  artifacts the guest rebuilds locally (not synced).\n- [`config/cloud-init.yaml`](config/cloud-init.yaml) — machine-level provisioning\n  (packages, swap, Docker, the `dev` user).\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmathijs81%2Finca","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmathijs81%2Finca","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmathijs81%2Finca/lists"}