Skip to main content
This maintained Node.js example serves Millwork’s async_job_v1 agent protocol. Millwork creates a branch, calls this adapter with a stable attempt identity, and later reads the branch head from its GitHub App. The adapter checks out that branch, runs a coding agent, commits its work, and pushes without force. Millwork does not trust the SHA returned by the adapter as final artifact proof.

Copy the adapter

Copy this complete file into server.mjs on your agent host. Mintlify’s code block has a copy button. The setup below explains the required Git access, token, and HTTPS ingress.

Prepare

Use Node.js 20 or later, Git, and a working coding agent. The default command is codex exec --approve-for-me -; sign in to Codex on the adapter host first. The host needs Git access to the selected repository through SSH or its credential helper. Grant only the repository it will edit. Set up an HTTPS ingress that forwards Millwork’s authenticated HEAD and POST requests to this local process. Set these variables on the adapter host, never in a Millwork task or receipt:
REVIEW_AGENT_ARGV_JSON optionally replaces the agent command with a JSON argv array such as ["codex","exec","--approve-for-me","-"]. At startup the adapter checks that a configured Codex command accepts its flags, before any agent job can start. The adapter sends the objective on standard input, not in process arguments or a shell command. A different configured agent command must read its prompt from standard input. Keep the token in your secret manager. Connect your repository in Millwork settings, then register this endpoint with POST /v1/review-composer/agents and endpoint.auth_ref: "". The response includes the agent ID. Start the private handoff with POST /v1/review-composer/agents/{arm_id}/connection/intents and a stop_choice, then open its continue_url in your signed-in browser. Enter the same token you set on this host. Read GET /v1/review-composer/agents/{arm_id}/connection for the pending cred_a_ handle and captured_generation; send both to POST /v1/review-composer/agents/{arm_id}/connection/test. A successful authenticated HEAD makes the agent ready. See the step-by-step guide for request bodies and SDK methods. An existing agent registered with an operator-provisioned cred_ handle cannot use this browser handoff: its connection-intent request returns a conflict. Register a new Review Composer agent with an empty auth_ref and follow the private handoff above. Do not send the token in registration or run requests. The adapter binds to 127.0.0.1; your ingress owns TLS.

Protocol and recovery

The adapter accepts start, status, and cancel messages at one URL. start returns a durable job_id before agent work begins. A retry with the same job_attempt_id and idempotency_key returns that ID and cannot launch another attempt. Changing the request under the same identity is rejected. The job record is persisted under REVIEW_WORK_ROOT/jobs; protect this directory and back it up according to your retention policy. Run one adapter instance per work root. The protocol’s job not found answer is reserved for a start that was never accepted. Persist the job record before starting agent work. Once accepted, status must find the same job after a process restart, even when the restart turns an interrupted attempt into a terminal failure. Millwork reissues start with the original key only after that explicit answer. If the process restarts while an attempt is active, the adapter reports failed when that job is inspected. It does not silently restart the agent. A failed push, moved branch, or timeout likewise reports failure. Millwork reads the remote branch itself before registering an artifact. Its final GitHub SHA, not the adapter’s claimed SHA, is what review sources evaluate. The protocol currently requires usage_usd. This example reports 0 because the Codex CLI does not provide a verified per-job bill to this adapter. Your agent provider’s invoice remains separate; Millwork records every attempted start and its reported usage rather than treating zero as proof of no cost.

Test without an external call

In a checkout of the source example, run:
The tests create a temporary local bare Git repository, run a fixture agent, verify the pushed final commit, replay and restart behavior, and exercise the authenticated HTTP endpoint. No GitHub, CodeRabbit, Codex, or Millwork call is made.