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.
Goal: run this adapter at an HTTPS endpoint that Millwork can reach, then
connect it to a GitHub repository in Settings → Integrations.
You are done when: your coding agent shows Connected after you save its
key on the private page and return to Integrations. Select Check for entered key
if offered, then open the agent’s row menu and select Test and connect.
Copy the adapter
Copy this complete file intoserver.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.
server.mjs
server.mjs
Prepare
Use Node.js 20 or later, Git, and a working coding agent. The default command iscodex 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. Open Millwork Settings → Integrations
to connect the repository, then select Register agent under Coding agents.
The equivalent API flow registers 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 acceptsstart, 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.