DocsOpen the app →

Switch to game mode?

The arcade opens on its menu.

Switch

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. Where omni is 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 signin once. In a cloud session, set OMNI_TOKEN, and OMNI_ASK=on for the questions: Cloud sessions, step 2.
  • Ask mode is on, for the questions to reach your page: omni ask on on a laptop, or OMNI_ASK=on in the environment, which needs no file and wins over what omni ask on wrote. OMNI_ASK=off turns it off.

1. Start the session

The agent runs this first, before anything else:

CODING AGENT
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:

FILE · q.json
{
  "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" }
}
CODING AGENT
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:

ExitWhat it meansWhat the agent does
0you answered on the pagereads the one line of JSON it printed: { round, answers, shots }, answers by question, shots the paths of the screenshots you added
4the wait ran out, the question still openreads round <id> and resumes with omni ask wait (step 3)
3the page is not used: ask mode off, no sign-in, the page unreachable, or the question closedasks you in its own chat, then sends your answer (step 4). The reason is the one line on stderr
2the command or the file is wrongfixes 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:

CODING AGENT
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:

CODING AGENT
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:

FILE · a.json
{ "answers": { "Which list should the export start from?": "Open invoices" } }
CODING AGENT
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:

CODING AGENT
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.

Next → How the loop works