nc://openai-codex-device

v0.1.0Pinned
Backnodecode-ai
pomterrecells: thirty-three cells, ported from oh-my-pi -- providers oh-my-pi carries (can1357/oh-my-pi at c9383c1, MIT, credited in each folder's NOTICE), each as a cell of its own: Alibaba's Coding and Token Plans, Amazon Bedrock, Anthropic's Pro/Max sign-in, Apple's on-device Foundation Models (macOS), Azure OpenAI, ClinePass, Cloudflare AI Gateway, Cursor, Devin, Factory Droid, GitHub Copilot, GitLab Duo and its agent, Antigravity, the Gemini CLI's Cloud Code Assist, Vertex AI, Kilo, Kimi Code, local ONNX and MLX workers, Muse Code, Ollama Cloud, ChatGPT's Codex sign-in and its device-code variant, OpenRouter, Snowflake Cortex, xAI's SuperGrok sign-in, Xiaomi MiMo and Z.AI's Coding Plan; and four that are not chat providers: language servers (nodecode-lsp), Perplexity search, keyless web search engines (nodecode-web-provider) and TypeSafe judgments. Each stands alone: it loads, starts, stops and tests by itself, depends only on nodecode, and shares no code with another; one whose wire none of the four lanes speaks registers a lane of its own. Written against the cell contract (src/CELLS.md) at nodecode fb4bdabc1. Their tests ran green against that tree with no network (~/nodecode-cells/tools/test-cell.sh, 663 tests over the 33, 0 failed).914a3fe· 8 Oct1 commit
test1 filecell.lisp7.3 KBprovider.lisp19.9 KBsignin.lisp18.9 KB

nodecode-openai-codex-device

A Nodecode cell that signs in to a ChatGPT Plus or Pro subscription (the Codex subscription) with a device code. Use it on a machine with no browser, or one whose browser cannot reach the machine's own loopback, such as a server over SSH. Once you are signed in, /models lists the Codex models under openai-codex/, and a turn on one of them goes to the ChatGPT backend the way the Codex CLI sends it.

Ported from oh-my-pi's openai-codex-device sign-in and the openai-codex provider it signs in to. See NOTICE.

Sign in

/openai-codex-device login

The command answers with https://auth.openai.com/codex/device and a code. Open the address on any device, phone included, sign in, and type the code. This machine asks OpenAI every few seconds (OpenAI's interval plus three), up to 120 times, and a notice says when you are signed in. Nothing listens on this machine.

Where the sign-in is kept

omp keeps a device sign-in as openai-codex, not under a name of its own (store-as "openai-codex" in its rule). It is the same subscription however you signed in, so this cell does the same. The token goes into Nodecode's shared auth.json under oauth_tokens.openai-codex:

{"provider": "openai-codex", "access_token": "...", "refresh_token": "...",
 "id_token": "...", "expires_at": 1791234567, "account_id": "...",
 "email": "...", "org_id": "...", "org_name": "plus", "installation_id": "..."}

expires_at is in epoch seconds. A token that expires within a minute is refreshed before a round sends it, and the refreshed entry is written back. Every other field of auth.json is kept, and the file stays mode 0600. /openai-codex-device status says who is signed in, and /openai-codex-device logout takes the entry out.

This cell also serves the openai-codex provider itself: the catalog row, the Codex lane, the credential with its refresh, and the request shape. So it works alone. The wire is the one nodecode-openai-codex carries. See that cell's README for what a round carries and what is not ported.

Beside nodecode-openai-codex

You can install both and sign in with whichever suits the machine. Both read and refresh the one oauth_tokens.openai-codex entry by the same rule. Whichever cell's hook runs first answers the credential, and the other is never asked. Each registers a lane of its own name and shapes only the rounds on it. While nodecode-openai-codex runs, the provider rides its lane, openai-codex. Otherwise it rides this cell's lane, openai-codex-device. A round is shaped once. If you set base_url, set it in both sections.

Beside nodecode-codex-auth

This cell's lane has the family :openai-codex. codex-auth answers only OpenAI-family lanes, so it never answers for openai-codex.

Install

Copy this folder into ~/.nodecode/cells/nodecode-openai-codex-device/ and restart Nodecode, or run (restart-cells).

Configure

Optional. The section is on unless it says "enabled": false:

{
  "openai-codex-device": {
    // the Codex backend: its root, its /codex, or its /codex/responses
    "base_url": "https://chatgpt.com/backend-api",
    // the client name every request carries
    "originator": "codex_cli_rs"
  }
}

Not ported

Everything nodecode-openai-codex leaves out, for the same reasons: usage and quota, the WebSocket transport, zstd bodies, the attestation header, provider-native compaction, live model discovery, and stable effort updates.

Gaps

  • Response headers. As in nodecode-openai-codex, the turn's sticky-routing token and models etag are read by advising NLE::NOTE-BODY-WIRE. The seam it stands in for is a :response-headers keyword on NLE::WALK-PROVIDER-STREAM.

Test

From this repository's root:

tools/test-cell.sh nodecode-openai-codex-device

Every OpenAI endpoint is a stubbed dex:post, and the wait between two polls is stubbed out, so nothing reaches OpenAI and nothing sleeps.

MIT licensed.

Add nc://openai-codex-device

  1. 1

    Install Nodecode

    Once per machine.

    $ curl -fsSL https://nodecode.ai/install.sh | sh
  2. 2

    Add the cell

    Pinned at 914a3fe.

    $ nodecode add nc://openai-codex-device

    Or tell the agent add the openai codex device cell.

  3. 3

    Sign in

    Run /openai-codex-device login, then type the code it shows on any device.