Show HN: ADHDev – one task queue per repo for any coding CLI, any machine or OS ADHDev launched as a control plane for AI coding agents that gives every machine a shared task queue and merges agent work into `main` only after the repository's own gates pass. The tool runs each task in its own git worktree and uses a Refinery component to gate, verify, and rebase finished work, merging only if `main` hasn't moved; in the private monorepo where ADHDev is developed, roughly one in six `main` commits is an `Auto-merge via Refinery` commit. A single-machine mesh runs fully local via `npx @adhdev/daemon-standalone` on port 3847, while cross-machine dispatch over the P2P mesh requires the cloud edition. The control plane for your coding agents: every agent on every machine in one view, one shared task queue, and only work that passes your tests reaches main . AI coding agents have become long-running background workers. ADHDev is the control plane for them: launch, watch, approve, and steer agent sessions from a web or mobile dashboard — Claude Code, Codex, Kimi, Cursor CLI, Antigravity CLI side by side, across every machine you own — and hand off convergence to an unattended pipeline that merges finished work into main . Parallel agents without the collisions. Every task runs in its own git worktree; the Refinery gates, verifies, and rebases finished work onto main, merging only if main hasn't moved — no merge-day hangover. Website: adhf.dev https://adhf.dev · Docs: docs.adhf.dev https://docs.adhf.dev Try it in one command: npx @adhdev/daemon-standalone , then open http://localhost:3847 http://localhost:3847 . The loop: describe a task in chat → the coordinator files it, tags it, queues it → an idle machine claims it into a fresh worktree → your repo's own gates decide → rebased onto main and merged only if main hasn't moved, worktree gone. Your phone only buzzed if something needed approving. ADHDev is built that way. In the private monorepo where ADHDev is developed — this engine is published from it as a submodule — roughly one in six main commits is an Auto-merge via Refinery commit: work that an agent finished, the repo's own gates approved, and Refinery landed without a human running git merge . That history lives in the upstream monorepo, so this public mirror's own log won't show those merge commits. A single-machine mesh runs fully local; spreading it across machines needs the cloud edition. Enqueue tasks with dependencies and let a coordinator dispatch them to whichever node has spare capacity — your laptop, a desktop, a build box. This is genuine multi-machine orchestration over a P2P mesh, not SSH into one host. Each task runs in its own worktree so agents never step on each other. The mesh and Refinery engine ships in this repo; cross-machine dispatch runs on the cloud edition. A mesh is bound to one git repository and owns the moving parts you'd otherwise coordinate by hand: | Task queue | Pull-based. pending → assigned → completed/failed , with depends on ordering and retries. Idle nodes claim work themselves — no push scheduler to get out of sync. | | Missions | A goal that groups many tasks, so a restarted coordinator picks up where the last one left off instead of re-queuing everything. | | Worktree nodes | An isolated branch checkout per parallel task, bootstrapped automatically install, native rebuilds, gitignored build outputs before any work is dispatched to it. | | Append-only ledger | Every dispatch, completion, failure, stall, and checkpoint as an append-only record in the mesh's local SQLite store — the audit trail that makes "what actually happened" answerable after the fact. | | Operating notes | Lessons recorded at runtime a provider quirk, a recovery procedure are injected into every future coordinator prompt, so knowledge outlives the session that learned it. | | Live-state prompt | The coordinator's system prompt isn't static text — at launch it's a render of live mesh state node health, active mission, recent failures, accumulated notes , and at runtime events are injected into its session instead of it polling. | | Difficulty + quota routing | Tag a task easy / medium / difficult and the node slot for that grade provider, model, thinking level, parallel cap takes it, so routine work runs on cheap models and only hard tasks reach for expensive ones. Each machine also reads the remaining 5-hour and weekly window of every CLI subscription: a plan that is nearly out is skipped the task waits or falls through to the node's next provider , and among the rest, quota that would expire unused at the next reset is spent first. You can see the routing forecast per difficulty in the dashboard before anything runs. | | Task chaining | Chain tasks with depends on : a dependent waits until its predecessors complete, then receives their completion summaries as an "Upstream results" appendix. A failed or cancelled predecessor holds or, by mesh policy, cancels the downstream chain and notifies the coordinator. mesh enqueue batch enqueues several already-confirmed tasks in one atomic call. | Every machine reads how much of each CLI subscription's 5-hour and weekly window is left. When a task is claimed, a plan that is nearly out is skipped the task waits or falls through to that machine's next CLI , and among the rest, quota that would expire unused at the next reset is spent first. The Machines page shows the whole fleet on one grid, and the mesh's Tasks tab forecasts which slot takes the next task at each difficulty before anything runs. Parallelism only pays off if the work actually merges. The Refinery converges finished tasks with per-repo validation gates, patch-equivalence checks, submodule-aware rebase-and-merge only if main hasn't moved , and automatic worktree cleanup — unattended. Agents finish; the Refinery lands them. The mesh board above surfaces the pipeline live: tasks moving through the queue, refine jobs while convergence is in flight, and every dispatch, completion, and stall in the activity feed. Parallel worktrees and unattended merges get fragile the moment git submodules enter the picture. ADHDev handles that case head-on — this very project is a submodule monorepo a root repo plus the AGPL engine and provider catalog as submodules , and we dogfood the mesh and Refinery on it every day. The Refinery treats submodules as first-class during convergence: - Reachability gate — before a root branch lands on main , it verifies the referenced submodule commits are reachable from the submodule's origin/main ; if not, the task is held as blocked until those commits are published. - Patch-equivalence detection — when a submodule commit is rebased or squashed and its SHA changes, the Refinery still determines whether the content already landed, so it won't double-merge or falsely flag a divergence. - Atomic pointer bumps — the submodule pointer bump converges together with the root change, so an unattended merge never leaves the root pointing at a broken or dangling submodule commit. You talk to one place. The coordinator orchestrates every worker and machine asynchronously — it waits on events, you don't. No session babysitting. Instead of sitting in front of each agent window watching for it to finish, you hand work to a single coordinator that drives all the workers in parallel and reacts only when a completion, approval, or status event actually arrives — no polling, no blocking waits. One conversation for you; a non-blocking event loop underneath. Your agents run locally; you watch and drive them from any browser. The dashboard is a real control surface — inspect active sessions, read chat and terminal state, approve or interrupt work, reopen the right history, and send the next instruction from a browser or your phone. No terminal babysitting. Approval pushes carry the start of the command itself, because approving rm -rf build/ and approving git push --force deserve different reaction times: the push arrives → tap it → approve in one tap push-to-phone ships with the cloud edition . | | | For a read-only investigation that matters — a bug RCA, a design review, an audit — ask the coordinator for a second opinion: it sends the same question to 2–3 workers on different providers, waits for their reports, and lays out where they agree, where they disagree, and which claims only one of them made. High agreement is not the same as being right — the same model with the same context repeats the same mistake — so the disagreements are the part worth reading. Chat, commands, screenshots, and remote input travel over an encrypted WebRTC data channel directly between your dashboard and your daemon. The server handles sign-in, signaling and lightweight metadata, plus one deliberate exception: on the cloud edition it receives the approval prompt the command and button labels to build the push notification, and the push shows up to 80 characters of it. Chat, terminal output and your code don't sit on someone else's box. It's a trust property of the design, not an upsell. - Claude Code Remote Control, Codex Remote: great for driving one vendor's session from your phone. ADHDev adds a queue several vendors and machines share, quota-aware routing between them, and test-gated merges. If you run one CLI on one machine, the built-in remote features may be all you need. - Paseo, Happy: open-source remote control and mobile apps for coding agents. ADHDev's focus is the work after the prompt: idle machines pull tasks, each in its own worktree, and only work that passes your tests lands on main . - Conductor, Superset, Vibe Kanban: parallel agents in worktrees, ending in a diff or a PR you review and merge. ADHDev runs one queue that your Mac, Windows and Linux machines pull from and merges for you when the gates pass. ADHDev doesn't replace your agents or spawn its own — it attaches to the ones already installed on your machine and gives them a control surface. browser / phone │ chat, commands, screenshots, remote input ▼ ┌───────────────┐ PTY ┌──────────────────────┐ │ daemon │────────────────────▶│ Claude Code, Codex, │ │ your machine │◀────────────────────│ Cursor CLI, … │ │ │ CDP ├──────────────────────┤ │ · providers │────────────────────▶│ Cursor, VS Code, │ │ · sessions │ │ Antigravity, … │ │ · mesh/queue │ └──────────────────────┘ │ · Refinery │ └───────────────┘ │ └── git worktrees ── one isolated checkout per parallel task - The daemon owns the integrations. Three provider categories: cli PTY , ide Chrome DevTools Protocol , extension CDP webview . - Long-lived runtimes are a separate process. adhdev-sessiond owns the PTYs, so your CLI sessions survive a daemon restart or upgrade. - Self-hosted talks straight to the daemon over HTTP + WebSocket on localhost:3847 . In the cloud edition the same data rides a WebRTC data channel browser↔daemon, with the server only doing signaling. mesh enqueue task → SQLite queue pending → an idle node claims it assigned → worker agent runs in its own git worktree → completed / failed → append-only ledger → Refinery: repo's own gates → patch equivalence → rebase → merge main unchanged → cleanup Four properties that shape everything else: 1. The coordinator routes, it doesn't implement. It orchestrates mesh tools instead of reading and editing code itself, so its context stays small and its ownership survives daemon restarts. 2. Nothing polls. Worker completion, approval, and refine reports are delivered straight into the coordinator's session as they happen — via a structured report completion call, not a screen-scrape. You wait on events; you don't ask for status in a loop. 3. Git is the proof, not the agent's word. "Done" is verified with real git state and commit checkpoints, not with a worker claiming success. 4. Ambiguity stops the pipeline. The Refinery never force-pushes; anything it can't decide is held for a human instead of merged. Deeper: Repo Mesh developer guide https://github.com/vilmire/adhdev/blob/main/docs/repo-mesh/DEVELOPER.md · session-host https://github.com/vilmire/adhdev/blob/main/docs/self-hosted/session-host.md Requirements: Node.js 20 or newer 22 LTS recommended; on Windows use 22.x — see the note below , git, and at least one coding agent already installed and authenticated — ADHDev drives the CLIs you already use. Recommended — the adhdev CLI: npm install -g adhdev adhdev standalone Open http://localhost:3847 . Self-host directly with the standalone package: npm install -g @adhdev/daemon-standalone adhdev-standalone Everything runs on your machine as a local daemon with an embedded dashboard — no cloud account required for the standalone path. Both packages install an adhdev command, so install one or the other, not both. Cloud edition several machines, push notifications : curl -fsSL https://adhf.dev/install | sh macOS / Linux irm https://adhf.dev/install.ps1 | iex Windows PowerShell adhdev setup sign in, then open https://adhf.dev Useful flags: adhdev standalone --host 0.0.0.0 allow other devices on the same LAN adhdev standalone --port 8080 custom port adhdev standalone --token mysecret token auth for scripts / operator access adhdev standalone --no-open don't auto-open the browser adhdev standalone --dev enable the DevServer API :19280 to debug and test providers adhdev-standalone --public