Project-agnostic orchestration for dispatching autonomous coding agents to a fleet of machines.
Why the name? I know. It stuck: agentic dev farming across many isolated slots. Naming is harder than scheduling the agents.
Warning
Active development preview. Farmslot is moving quickly while the product is finalized in this repo. Expect experimental features, rough edges, changing APIs, large/transient files, and docs that may lead the implementation in some areas. Use it as an early operator/developer tool, not as a stable production dependency yet.
Manages a pool of machines (local or remote), each with one or more slots — isolated environments where an AI coding agent runs a task autonomously. Handles the full lifecycle: prepare, dispatch, monitor, recycle.
farmslot/
packages/cli/ # `farmslot` CLI for gateway, fleet, slot, dispatch, and RPC control
scripts/ # Lower-level lifecycle scripts used by the gateway and CLI
pool/ # Machine registry — slots, ports, devices
projects/ # Project configs (separate git repos, user-managed)
<name>-farm/
project.json # Hooks, health checks, fixture mappings
fixtures/ # Env templates, config files, test data
templates/ # Task templates (worker + orchestrator)
docs/ # Architecture, protocols, reference
bash scripts/dev.shOpen http://localhost:7777 to use Command Center with the local fake-runner demo slot. For CLI and agent access, see Local demo and CLI access.
- Documentation website
- What is Farmslot?
- Adoption path
- Local demo and CLI access
- Gateway API capability surface
- Reference integrations
Farmslot is designed to be project-agnostic: each repository keeps its own runner hooks, fixtures, recipes, and domain actions behind project.json. Two useful reference integrations are:
- AudioLab — github.com/deeeed/audiolab is a public Expo/React Native monorepo that uses Recipe Protocol v1 to expose app-specific audio and native-module probes through a project-owned recipe runner. It is the best public example for adapting an existing app without moving app semantics into Farmslot core.
- Farmslot itself — this repo includes
projects/farmslot-farm/project.jsonandpool/farmslot-demo.json, so Farmslot can dispatch, validate, and dogfood work against its own monorepo using the same pool/project model as any imported project.
Each project is a separate git repo inside projects/:
cd projects/
mkdir my-app-farm && cd my-app-farm
git initCreate project.json:
{
"name": "my-app-farm",
"default_branch": "main",
"hooks": {
"preflight": "npm install && npm start &",
"health_check": "curl -s http://localhost:{{METRO_PORT}}/health",
"dev_server_check": "lsof -i :{{METRO_PORT}} >/dev/null 2>&1"
},
"health": {
"ready_indicator": "ok",
"parse_health": "python3 -c \"import json,sys; print(json.load(sys.stdin).get('status',''))\"",
"dev_server_name": "DevServer"
},
"fixtures": {
"templates": [{ "src": ".env.template", "dst": ".env", "vars": ["PORT"] }],
"files": []
},
"platforms": {}
}Then reference it in your pool JSON:
{ "machine": "my-server", "project": "my-app-farm", ... }No lifecycle script changes needed.
Create pool/<machine>.json:
{
"machine": "my-server",
"project": "my-app-farm",
"platform": "linux",
"host": "my-server.local",
"ssh_user": "deploy",
"dispatch_cmd": "cd {repo} && {claude_path} --dangerously-skip-permissions",
"slots": [
{
"id": "my-server-1",
"repo": "~/dev/my-app",
"metro_port": 3000,
"session": "my-server-1",
"slot_vars": { "PORT": "3000" }
}
]
}Multiple farmslot worktrees can run dev servers simultaneously using per-worktree port config.
Setup:
- Copy
.env.ports.exampleto.env.portsat the repo root - Set unique ports per worktree (main worktree uses defaults, no file needed):
GATEWAY_PORT=7778 VITE_PORT=5175
- Start:
bash scripts/dev.sh(required — runningyarn devdirectly won't load port overrides)
Port allocation:
| Worktree | Gateway | Vite UI |
|---|---|---|
| main | 7777 | 5174 |
| farm | 7778 | 5175 |
| (next) | 7779 | 5176 |
Limitations: Remote node agents connect to one gateway only (the main one on 7777). The worktree gateway gets fleet data via SSH-based refresh on first boot, but won't have real-time node connections — so live exec and tmux streaming only work on the main gateway.
See docs/README.md and docs/adr/ for the full design.
Key decisions:
- Pool JSON owns machine config — SSH, ports, devices
- Project JSON owns app config — how to boot, health-check, recycle
- Scripts are project-agnostic — all project-specific logic comes from
project.json - Local slots run without SSH — auto-detected via hostname
- Project configs are separate git repos — each
projects/<name>-farm/is independently tracked
Farmslot separates product surfaces, runtime services, and reusable toolkit packages:
apps/*contains user-facing product surfaces:apps/command-center— web control surface plus repo-level quality scripts.apps/companion— mobile companion app.apps/docs— Docusaurus reader-facing documentation site.
services/gatewayandservices/nodeare long-running runtime services: Gateway owns control-plane orchestration; Node owns machine-local capabilities.- Other
packages/*entries are shared libraries or CLIs: protocol contracts, recipe tooling, theming, Expo recipe support, and the Farmslot CLI. - Keep code with its owner. UI-only code belongs under the app that renders it; reusable protocol/toolkit code belongs under a package; service/runtime policy belongs in Gateway; machine-local execution belongs in Node.
- Keep package names stable when moving implementation roots. Workspace location communicates repository ownership; the
@farmslot/*package name communicates import/runtime identity.
Created by Arthur Breton