Any coding agent
Run a session and ask the person on the Omni page from any coding agent, Codex or another, on a laptop or in the cloud, with plain omni commands and no hook.
Claude Code runs the loop's session work through its hooks: the briefing when a session starts, the
questions sent to your ask page, the heartbeat the Omni page shows, the close when it ends. Any
other coding agent, such as Codex in a terminal or on chatgpt.com, does the same with five plain
omni commands it runs from its shell. Nothing reads stdin, needs a terminal or a home folder, so
they work on a laptop and in a cloud session alike.
This page lists them in the order an agent runs them. Paste it, or point your agent at it, at the start of a session.
Before you start
- The repository runs the loop: it has a
.omni-loop/folder at its root. Whereomniis not installed, as in a cloud session, the agent runs the repository's own copy,node .omni-loop/bin/omni.mjs, which takes the same commands. - You are signed in. On a laptop,
omni signinonce. In a cloud session, setOMNI_TOKEN, andOMNI_ASK=onfor the questions: Cloud sessions, step 2. - Ask mode is on, for the questions to reach your page:
omni ask onon a laptop, orOMNI_ASK=onin the environment, which needs no file and wins over whatomni ask onwrote.OMNI_ASK=offturns it off.
1. Start the session
The agent runs this first, before anything else:
omni session start
It prints the product's Statement and Never list, then the repository's briefing, then a last line
session: <id>. The id is OMNI_SESSION_ID when it is set, else CLAUDE_CODE_SESSION_ID, else the
one stored for this checkout; with none, it makes one and stores it, so every later omni command
of the checkout belongs to the same session. Set OMNI_SESSION_ID to tell apart two sessions that
share one checkout.
It always exits 0, the Omni page reachable or not.
2. Ask the person
When the agent has a question for you, it writes it to a file, in the shape Claude's
AskUserQuestion takes, then asks:
{
"questions": [
{
"question": "Which list should the export start from?",
"header": "Export",
"options": [
{ "label": "Open invoices", "description": "Only the invoices still to be paid." },
{ "label": "All invoices", "description": "Every invoice of the year." }
],
"multiSelect": false
}
],
"lead": "The spec does not say which invoices the export lists.",
"context": { "skill": "brainstorm", "model": "gpt-5-codex" }
}
omni ask question --file q.json
lead, the text the agent wrote before asking, and context, the skill and the model, are optional.
Any other field is refused, named. The question shows on your ask page; you answer it there. What
the command prints, and what the agent does next, depend on its exit code:
| Exit | What it means | What the agent does |
|---|---|---|
0 | you answered on the page | reads the one line of JSON it printed: { round, answers, shots }, answers by question, shots the paths of the screenshots you added |
4 | the wait ran out, the question still open | reads round <id> and resumes with omni ask wait (step 3) |
3 | the page is not used: ask mode off, no sign-in, the page unreachable, or the question closed | asks you in its own chat, then sends your answer (step 4). The reason is the one line on stderr |
2 | the command or the file is wrong | fixes the field the line names, and asks again |
It waits 110 seconds by default, so the call ends before a cloud shell gives up at two minutes.
--wait takes any number of seconds from 10 to 540:
omni ask question --file q.json --wait 300
3. Keep waiting
On exit 4, the question stays open on your page. The agent resumes the wait with the round it printed, as often as it is willing to wait:
omni ask wait <round>
It takes the same --wait and ends with the same exit codes: 0 with your answer, 4 still waiting,
3 to ask in its own chat.
4. Send an answer given in the chat
On exit 3 the agent asks you in its own chat. When the question had a round, the stderr line names
it: the agent then sends your answer to the page, so the page keeps it beside the question. It
writes the answers by question, as ask question printed them:
{ "answers": { "Which list should the export start from?": "Open invoices" } }
omni ask answer <round> --file a.json
The page shows the answer as given in the terminal. A question left empty is left out. It exits 0 even when the page cannot be reached, with one line on stderr: it never stops the agent.
5. End the session
The agent runs this last:
omni session end
It closes the session's questions on your ask page and tells the Omni page the session stopped. It always exits 0. An agent that never gets to run it does no harm: the page treats a session whose heartbeat stopped as gone.
The heartbeat
While the session runs, every omni command the agent runs tells the Omni page the session is
working, at most once a minute and in the background: the command neither waits for it nor fails
with it. Nothing to run for it. OMNI_HEARTBEAT=off stops it; omni heartbeat sends one by hand.