{"id":47685723,"url":"https://github.com/arielarevalo/swapclaw","last_synced_at":"2026-04-02T14:49:23.566Z","repository":{"id":347214730,"uuid":"1192386515","full_name":"arielarevalo/swapclaw","owner":"arielarevalo","description":"Container-isolated agent runtime over the Agent Client Protocol (ACP)","archived":false,"fork":false,"pushed_at":"2026-03-27T06:09:28.000Z","size":100,"stargazers_count":1,"open_issues_count":4,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-27T14:58:04.957Z","etag":null,"topics":["acp","agent","agent-protocol","cli","container","devtools","docker","isolation","runtime","sandbox","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/arielarevalo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-26T06:54:58.000Z","updated_at":"2026-03-27T05:49:07.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/arielarevalo/swapclaw","commit_stats":null,"previous_names":["arielarevalo/swapclaw"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/arielarevalo/swapclaw","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arielarevalo%2Fswapclaw","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arielarevalo%2Fswapclaw/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arielarevalo%2Fswapclaw/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arielarevalo%2Fswapclaw/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arielarevalo","download_url":"https://codeload.github.com/arielarevalo/swapclaw/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arielarevalo%2Fswapclaw/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31308446,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["acp","agent","agent-protocol","cli","container","devtools","docker","isolation","runtime","sandbox","typescript"],"created_at":"2026-04-02T14:49:22.526Z","updated_at":"2026-04-02T14:49:23.556Z","avatar_url":"https://github.com/arielarevalo.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# swapclaw\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![CI](https://github.com/arielarevalo/swapclaw/actions/workflows/ci.yml/badge.svg)](https://github.com/arielarevalo/swapclaw/actions/workflows/ci.yml)\n[![Node](https://img.shields.io/badge/node-%3E%3D22-brightgreen)](https://nodejs.org)\n\nContainer-isolated agent runtime over the\n[Agent Client Protocol](https://github.com/agentclientprotocol/agent-client-protocol)\n(ACP).\n\n## Overview\n\nA \"claw\" is an agent runtime that manages container sandboxes where work\nhappens. A typical claw bundles an embedded agent SDK — swapclaw replaces the\nSDK with an ACP client. The client connects to any external ACP agent, and that\nagent becomes the brain that drives the containers.\n\nThe agent doesn't know or care that it's driving a claw. It just sees a standard\nACP interface that happens to route terminal and filesystem requests into\nisolated containers.\n\n## Architecture\n\n```\nExternal ACP Agent (the brain — any ACP-compatible agent)\n  ↕ ACP\nswapclaw (the body — session + container management)\n  ↕ manages\nDocker or Apple Containers (execution sandboxes)\n  ├── /project (working directory, read-only mount)\n  └── /session (scratch space, read-write)\n```\n\n1. swapclaw connects to an ACP agent over stdio\n2. Sends prompts to the agent via ACP\n3. The agent requests terminal access, file reads/writes — swapclaw routes these\n   into containers\n4. Session updates stream back to the external ACP client in real time\n\n## Features\n\n- **Agent-agnostic** — works with any ACP-compatible agent\n- **Container isolation** — each session gets its own Docker or Apple Container\n- **Session persistence** — SQLite-backed sessions survive restarts\n- **Crash recovery** — clears stale containers on startup\n- **Idle timeout** — containers tear down automatically when unused\n- **Concurrency control** — configurable maximum concurrent sessions\n- **Session modes** — code / ask / architect modes via ACP extensions\n- **Task scheduling** — once / interval / cron execution via ACP extensions\n- **MCP passthrough** — stdio-transport MCP servers forwarded into containers\n- **Streaming** — real-time session update forwarding to external clients\n\n## Security Model\n\nswapclaw relies on container isolation as its primary security boundary. Each\nsession runs in a dedicated Docker or Apple Container with the project directory\nmounted read-only. All terminal commands and file operations execute inside the\nsandbox — the host is never exposed. See [AGENTS.md](AGENTS.md) for details.\n\n## Prerequisites\n\n- [Bun](https://bun.sh) (or Node.js \u003e= 22)\n- [Docker](https://www.docker.com) or Apple Containers (macOS)\n- An ACP-compatible agent\n\n## Installation\n\n```bash\nnpm install swapclaw\n```\n\nOr from source:\n\n```bash\ngit clone https://github.com/arielarevalo/swapclaw.git\ncd swapclaw\nbun install\nbun run build\n```\n\n## Usage\n\nswapclaw runs as an ACP agent on stdio. Point it at an external agent:\n\n```bash\nSWAPCLAW_AGENT_COMMAND=claude swapclaw\n```\n\nWith arguments:\n\n```bash\nSWAPCLAW_AGENT_COMMAND=claude SWAPCLAW_AGENT_ARGS=\"--model opus\" swapclaw\n```\n\n## Configuration\n\nAll configuration is via environment variables:\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `SWAPCLAW_AGENT_COMMAND` | *(required)* | Command to spawn the ACP agent |\n| `SWAPCLAW_AGENT_ARGS` | | Space-separated arguments for the agent |\n| `SWAPCLAW_DATA_DIR` | `~/.swapclaw` | Session data and database directory |\n| `SWAPCLAW_CONTAINER_IMAGE` | `alpine:latest` | Docker image for containers |\n| `SWAPCLAW_CONTAINER_TIMEOUT` | `300000` | Prompt timeout (ms) |\n| `SWAPCLAW_IDLE_TIMEOUT` | `60000` | Container idle timeout (ms) |\n| `SWAPCLAW_MAX_CONCURRENT` | `3` | Maximum concurrent sessions |\n| `SWAPCLAW_TIMEZONE` | *(system)* | Timezone for sessions |\n\n## ACP Extensions\n\nCustom functionality exposed via ACP `extMethod`:\n\n| Method | Description |\n|--------|-------------|\n| `swapclaw/getSessionMode` | Get current session mode |\n| `swapclaw/setSessionMode` | Set mode (code / ask / architect) |\n| `swapclaw/createTask` | Schedule a task (once / interval / cron) |\n| `swapclaw/listTasks` | List scheduled tasks |\n| `swapclaw/cancelTask` | Cancel a scheduled task |\n\n## Operations\n\n- **Crash recovery** — on startup, stale containers from previous crashes are\n  automatically cleaned up\n- **Idle timeout** — containers tear down after 60 seconds of inactivity (configurable)\n- **Capacity** — new sessions are rejected when at `SWAPCLAW_MAX_CONCURRENT`; no queuing\n- **Logging** — structured JSON to stderr\n\nSee [AGENTS.md](AGENTS.md) for the full operations guide.\n\n## Development\n\n```bash\nbun install          # Install dependencies\nbun run build        # Compile TypeScript\nbun test             # Run tests\nbun run test:watch   # Watch mode\nbun run lint         # Check lint + formatting\nbun run lint:fix     # Auto-fix\nbun run format       # Auto-format\n```\n\nTests are organized in three tiers:\n- **Unit** (`tests/\u003cmodule\u003e.test.ts`) — single class, deps mocked\n- **Integration** (`tests/integration_\u003cflow\u003e.test.ts`) — multiple real classes\n- **E2E** (`tests/e2e_\u003cscenario\u003e.test.ts`) — full application with Docker\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farielarevalo%2Fswapclaw","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farielarevalo%2Fswapclaw","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farielarevalo%2Fswapclaw/lists"}