Connect coding agents
Connect a coding agent that speaks the Agent Client Protocol (ACP), such as Claude Code. An agent sends it a task. The coding agent works in a git worktree, asks before each change, and commits on a branch of its own.
This page runs Claude Code end to end. Requires Node.js, git, and Claude Code signed in or an Anthropic API key.
wardrik init offers steps 1 and 3 when it finds Claude Code: it shows the install command, and
writes the harness and a coding policy. Answer it without a terminal with
--set coding.claude=true.
1. Install the ACP adapter
Section titled “1. Install the ACP adapter”npm install -g @agentclientprotocol/claude-agent-acpclaude-agent-acp --version2. Make a repository
Section titled “2. Make a repository”mkdir -p ~/acp-demo && cd ~/acp-demogit init -b mainprintf 'defmodule Demo do\n def hello, do: "Hello"\nend\n' > demo.exprintf '# Demo\n\nOne module, demo.ex. Keep changes small.\n' > AGENTS.mdgit add . && git commit -m "First"3. Configure the harness
Section titled “3. Configure the harness”harnesses: claude: command: claude-agent-acp env: {ANTHROPIC_API_KEY: "${ANTHROPIC_API_KEY}"} meta: {claudeCode: {options: {settingSources: []}}} options: {mode: default} context: [CLAUDE.md, AGENTS.md]checkouts: demo: ~/acp-demosystemctl --user restart wardrikwardrik doctor # checks the command and each checkoutsettingSources: []stops Claude Code from loading~/.claude/settings.jsonand the repository's.claude/, so neither one can allow a tool.mode: defaultmakes Claude Code ask before each change. Its own default,auto, may not ask.- Without
env, Claude Code uses its own sign-in from~/.claude. - See all settings in
config.yaml› harnesses.
4. Define an agent
Section titled “4. Define an agent”---description: Sends coding work to Claude Code.tools: [claude]policy: coding---You send coding work to the claude tool, then say what it did.allow: ["claude/execute(command = mix test)"]deny: [claude/delete]default: {read_only: allow, else: ask}- Each harness is a tool of the same name.
- Each request from Claude Code is a call named by its ACP kind:
claude/read,claude/edit,claude/execute,claude/delete,claude/fetch, and so on. - A rule matches a request's input, such as
command, and its paths relative to the repository:claude/edit(lib/*).
5. Ask for a change
Section titled “5. Ask for a change”wardrik reloadwardrik ask builder "Use claude on the demo checkout, work add-greet: add greet/1 to demo.ex, returning \"Hello, NAME!\", then commit it."→ claude {"checkout":"demo","task":"Add greet/1 ...","work":"add-greet"}
╭─ claude__edit ─────────────────────────────────────────╮│ { ││ "file_path": ".../demo.ex", ││ "new_string": "...def greet(name), do: ...", ││ ... │╰────────────────────────────────────────────────────────╯Approve claude__edit? [y/n, Enter leaves it]Type y to approve each request. Type n to refuse one, with a reason Claude Code receives.
wardrik approvalgoes through the requests that wait, showing each one's arguments.- In Slack, a notice shows each request with Approve and Deny.
6. See the result
Section titled “6. See the result”wardrik agent show builder # its ID, agt_...cd ~/acp-demogit log --oneline main..wardrik/AGENT_ID/_/add-greet- The branch is
wardrik/<agent ID>/<conversation>/<work>, from the checkout'sbase.mainis unchanged. - The worktree is in
~/.local/share/wardrik/worktrees/claude/demo/. - Asking again with the same
workname continues the same session and branch.
7. Merge it
Section titled “7. Merge it”git merge --squash wardrik/AGENT_ID/_/add-greet && git commit -m "Add greet/1"A sweep runs each day. It removes each worktree whose work is in its checkout's base, and the
branch with it. Merged, squashed and cherry-picked work all count. Work with changes or untracked
files stays.
Run without asking
Section titled “Run without asking”A coding agent can work with no person in the loop, in one of two ways.
Wardrik decides each request. Claude Code still asks, and the policy answers:
allow: [claude/*]deny: [claude/delete, "claude/execute(command = git push*)"]---tools: [claude]policy: autonomous---- No request asks a person. Deny rules still refuse, and every decision is in the agent's events.
- After Claude Code fetches a web page, gated requests ask again. List under
allow_after.outsidethe ones that may still run. See Outside content. - The work stays on its branch until you merge it.
The coding agent decides each request. Set its own mode:
harnesses: claude-open: command: claude-agent-acp meta: {claudeCode: {options: {settingSources: []}}} options: {mode: bypassPermissions}- Claude Code sends no requests, so no policy sees its commands. The worktree, the branch, the timeout and the cost are its only limits.
acceptEditsallows edits and still asks before commands.- Claude Code refuses
bypassPermissionsas root outside a sandbox.
Start work from a remote branch
Section titled “Start work from a remote branch”checkouts: core: {path: ~/src/core, base: origin/main, fetch: true}baseis where each new branch starts, whatever branch the checkout is on.fetch: truerunsgit fetchbefore each new branch and before each sweep.
Which orgs can use a harness
Section titled “Which orgs can use a harness”A harness is available to the deployment's org. List it under orgs for other orgs:
orgs: globex: harnesses: [claude]A harness runs on the daemon's machine, with its checkouts. Give it only to orgs you trust with that machine.