Skip to content

Repository files navigation

all-code (alc)

Run Claude Code on the Codex/ChatGPT subscription you already pay for — and seven other coding agents besides, on that same login or on any provider you point them at. Any session can be mirrored to a browser page and driven from another device.

CI Latest release License: MIT Platforms

📖 Documentation · 🇹🇼 繁體中文

Claude Code on your ChatGPT plan, in three commands

curl -fsSL https://raw.githubusercontent.com/treeleaves30760/all-code/main/install.sh | sh
codex login
alc --codex claude

Windows PowerShell: irm https://raw.githubusercontent.com/treeleaves30760/all-code/main/install.ps1 | iex

There is no configuration step. No alc config init, no file to edit. The starter configuration is compiled into the binary and already carries a Codex profile; alc --codex claude reads it in memory and writes no configuration file of its own. The only thing it leaves in ~/.config/alc is the Codex model catalog, re-cached at most once a day.

What it needs is the auth.json that codex login writes, and claude on PATH — alc launches coding agents, it does not bundle them. What it does not need is an API key, an alc configuration file, or the codex binary at launch; that one is for running codex login itself and for keeping the model catalog fresh. alc checks the login before it looks for the agent, so somebody missing both is told about codex login first:

error: Codex credentials were not found at ~/.codex/auth.json; run `codex login` and retry
error: 'claude' is not installed or not on PATH; install it first, then retry `alc claude`: cannot find binary path

What you get. Claude Code starts on gpt-6.1-sol at low effort — or on whatever model and effort your own ~/.codex/config.toml already names, if you have used Codex CLI before — with the real 272k Codex context window rather than the 200k Claude Code assumes for a model ID it does not recognize, and every GPT model Codex serves in its own /model picker:

Model Beginner-friendly use case Codex default effort
gpt-6.1-sol GPT-6.1 Sol. Latest workhorse for coding and everyday work; recommended starting point low
gpt-6-astra GPT-6. Complex, demanding work medium
gpt-6-sol GPT-6. Everyday coding and agentic work medium
gpt-5.6-sol Previous generation; complex professional work low
gpt-5.6-terra Previous generation; balanced everyday coding medium
gpt-5.6-luna Previous generation; fast, affordable work medium
gpt-6-luna GPT-6. Fast and the cheapest; quick fixes and high-volume work medium

Inside the session, /model switches the model and its left/right arrows move the effort slider; /effort sets a level directly. To start somewhere else for one run, or in scripts:

alc --codex claude --model gpt-6-luna --effort low

Your plain claude still reaches Anthropic afterwards. That picker writes its choice to ~/.claude/settings.json, which every Claude Code session on the machine reads — including the ones alc did not start, which have no adapter in front of them. alc reads that one key before the launch and puts it back when the session exits. Codex bridge has the details, and the two cases where it deliberately leaves the file alone.

alc prints nothing at launch — bar one note when an ultra effort from your Codex config is clamped to max — so what you are looking at is Claude Code. The adapter in between is a third-party compatibility layer, not an official OpenAI or Anthropic integration — review THIRD_PARTY.md and your provider terms before routing subscription credentials through it.

One login, every agent

The same codex login drives every agent alc launches. No second key, no per-agent setup.

alc --codex claude       # in-session /model picker
alc --codex opencode
alc --codex pi
alc --codex copilot
alc --codex goose
alc --codex qwen
alc --codex kimi
alc codex                # Codex CLI itself, on its own login, no adapter
Agent Reaches the bridge over Switching models
Claude Code Anthropic Messages /model picker, mid-session
OpenCode, Pi, Kimi Code CLI OpenAI Responses one model, chosen at launch
Copilot CLI, Goose, Qwen Code OpenAI Chat Completions one model, chosen at launch
Codex CLI native, no bridge Codex's own picker

alc starts its own Codex adapter on a loopback port and points only the launched agent's process at it — three wire protocols, one login. For Claude Code the adapter is a background process its sessions share (see Background sessions); for the others it lives inside alc and stops when the session does. Claude Code is the only agent that can switch mid-session, because it sends the model and effort with every request, so alc never pins either on the adapter; the others pick one model and one reasoning effort at launch.

Codex bridge, below, has the model catalog, the effort tiers, and what the adapter does with your credentials.

Drive it from your phone

Any session, any agent, any provider — mirrored to a browser page you can open from anywhere that can reach the machine.

alc --share claude          # or: alc share claude
alc session claude-7QK2M9XB4T (claude@all-code)
  open  http://127.0.0.1:8787/#k=…
  hub   127.0.0.1:8787 · loopback only (pid 48213) · this link grants input; keep it to yourself
  keys  ctrl-\ then d detaches; the session keeps running

Your terminal keeps working. Sharing mirrors a session, it does not take it away. What is mirrored is the terminal itself, which is why every agent and every provider works the same way — there is nothing per-agent to support.

What the page gives you is the session list, the live screen, a key bar for the keys a phone keyboard does not have (Esc, Tab, Shift+Tab, Ctrl, arrows), and a composer that sends a whole prompt as one block instead of fighting a mobile keyboard inside a raw terminal. On a wide screen with a session open, a button beside Back folds the session list away so the terminal gets the full width — a --tmux session gets the extra columns, a plain one is drawn larger — and that browser remembers the choice.

Sessions outlive the terminal that started them, because a background hub owns them:

alc sessions               # the link, then what is running
alc attach 7QK2            # back on it, from any terminal
alc kill 7QK2

Ids can be given as any unambiguous prefix, git-short-hash style. alc sessions leads with the link because the one --share printed scrolls away the moment the agent draws its own interface.

What the link can do. A shared Claude Code, Codex, or OpenCode session starts in ask mode — alc passes the flag itself, so the link does not hand anyone an autonomous agent. The other five agents start on their own defaults unless you name a rung with --permission. Loosening a session past the ceiling you configure needs alc confirm <ticket> typed at a terminal on the host machine. Remote control has the permission ladder and the threat model.

Remote control works on Windows 10 and 11 as it does on macOS and Linux; --tmux there needs the native Windows port of tmux, covered in Who owns the size.

Background sessions

Claude Code's agent view runs sessions in the background - claude agents, claude --bg, and ← on an empty prompt - under a supervisor of its own that outlives the terminal. Every Claude Code session alc starts works there, on the provider alc gave it:

alc --codex claude agents                     # agent view; every dispatch runs on Codex
alc --codex claude --bg "fix the flaky test"  # straight to the background
alc --codex claude                            # ← on an empty prompt: still on Codex

How. alc hands Claude Code its provider in a settings file, passed with --settings, which Claude Code keeps for a background session and reads again each time it restarts one. The file holds no key: where the provider needs one, Claude Code asks alc for it through its apiKeyHelper setting, and alc reads it from where it always has. On Claude Code's own login the login answers, and the file carries the endpoint and the model.

The Codex bridge runs on its own now. A background session outlives the alc that started it, so the adapter has to as well: one small alc process on a loopback port it keeps, answering only requests that carry its token. A session that needs it starts it, and it stops after an hour with nothing to do.

alc bridge          # running or not, and where
alc bridge stop     # stop it now; the next session that needs it starts it

Every Claude model becomes a Codex model. Under alc --codex claude no request reaches a Claude model. The /model picker lists Codex models only; every alias (opus, sonnet, haiku, fable, best, opusplan) and Claude Code's background work land on Codex models; and a Claude model named in full - /model claude-opus-5, a subagent's model:, a fallback chain - is answered by the Codex model of the same tier. Fast mode and the advisor exist only on Claude models, so they are off in these sessions. claude ultrareview and cloud sessions run on Anthropic's servers and stay Anthropic features.

alc claude attach, logs, stop, respawn and rm go straight to Claude Code, and so does plain claude attach: the session already carries its settings file. So do the commands that never reach a model - mcp, doctor, plugin, update and the like - which start no bridge and count no session.

Any provider, not just Codex

codex login is the shortest path, not the only one. Point any of the eight agents at Anthropic, the OpenAI API, OpenRouter, a local Ollama, llama.cpp or vLLM server, DeepSeek, Moonshot, Z.ai, MiniMax, Groq, xAI, Google, or a custom endpoint — and change it for a single run without editing anything.

alc config                 # keys and per-agent defaults live here
alc claude                 # each agent on its configured default
alc --openrouter codex
alc --deepseek pi
alc --ollama claude
alc --llamacpp claude
alc -p local-vllm opencode

--provider (or -p) takes a profile name, or a provider kind when only one profile of that kind exists. The shortcut flags --anthropic, --openai, --openrouter, --codex, --ollama, --vllm, --llamacpp, --deepseek, --moonshot, --zai, --minimax, --groq, --xai, and --google are equivalent. The starter configuration ships Anthropic, OpenAI, OpenRouter, Codex, Ollama, and a disabled vLLM template; keys are saved locally or read from environment variables, and environment variables win.

The eight agents do not all speak the same model protocol, and the fifteen provider kinds do not all expose the same one, so alc checks the combination before launch instead of sending a request that cannot work. Providers and agents has the endpoint, key variable, and protocol for every kind.

Command reference

Command What it does
alc claude, codex, opencode, pi, copilot, goose, qwen, kimi Launch that agent on its configured provider
alc config The configuration TUI; also init, show, path, upsert, key, set-default, remove
alc doctor Binaries, credentials, compatibility, defaults, bridge and remote state
alc models The GPT models the Codex bridge offers; --refresh, --json
alc usage What is left on each Claude/Codex login and API-key balance, and usage per provider and agent; --json
alc update Update alc in place; --check, --force
alc share <agent> Launch with the session mirrored to a browser page
alc sessions The page link, then the shared sessions (tmux ones marked)
alc attach <id> Put this terminal back on a shared session
alc rename <id> <name> Rename a session's card on the page
alc kill <id> Stop a shared session
alc hub status, start, stop --drain for the process that owns sessions
alc bridge The background bridge Claude Code sessions reach the Codex login through; status, stop
alc remote status, url, on/off, auto-share, allow-host, token --rotate
alc confirm <ticket> Approve a permission change a shared session asked for

alc <command> --help has the flags for each.

Running agents

Forwarding. Apart from Claude's alc-specific --model, --effort, and --save, arguments after the agent name are forwarded unchanged:

alc --codex codex exec "review this repository"
alc --openrouter claude --print "summarize the diff"
alc --ollama opencode run "fix the failing test"

To pass an option with one of those same names to Claude itself, put it after --: alc claude -- --model sonnet. A --settings you pass is merged into alc's, yours winning, because Claude Code reads only one.

alc's own flags — --share, --no-share, --bind-lan, --name, --permission, --tmux, -t — have to come before the agent name. After it they would be handed to the agent as prompt text, so alc stops and says so instead — unless you put -- straight after the agent name, which says you meant the agent's own flag:

alc --codex claude -- -p "fix the flaky test"
alc --codex claude -- --bg --name nightly "run the slow suite"

The -- goes straight after the agent's name, before all of its flags; later in the line it reaches the agent as an argument of its own.

Previewing. alc --codex --dry-run claude prints the resolved agent and provider, the command with secrets redacted, a line for the built-in adapter when the launch uses one, and every file it would write — and says when a launch would be refused rather than only what would succeed.

Diagnostics

alc doctor

alc doctor reports the environment and credential paths, all eight agent binaries, every provider profile against all eight agents, the resolved per-agent defaults, a leftover GPT model pinned in ~/.claude/settings.json, the Codex bridge's model, effort, and codex login state, an enabled Ollama, llama.cpp or vLLM profile checked against its running server, and the remote-control posture — then a summary of issues with a fix for each. It exits non-zero when it finds one.

For named errors and their fixes, see the troubleshooting guide.

What is left, and where it went

alc usage
Accounts
     PROFILE     ACCOUNT                  PLAN  REMAINING
  ✓  anthropic   ~/.claude                max   5h 97% left, resets in 2h 53m — week 79% left, resets in 6d 4h — Fable week 62% left, resets in 6d 4h
  ✓  codex       [email protected]          pro   week 66% left, resets in 5d 9h — no credits
  ·  ollama      —                        —     no quota API
  ·  openrouter  —                        —     no API key; run `alc config key openrouter`

Usage by provider and agent
  PROVIDER  AGENT     LAUNCHES  TURNS  INPUT  CACHED  CACHE %  OUTPUT  LAST
  codex     claude    1         1      20.8K  15.4K   74%      35      7m ago
  ollama    opencode  1         —      —      —        —       —       12m ago
  source: ~/.config/alc/usage.jsonl — tokens are counted only where alc carries the traffic; a direct launch counts as a launch alone

✓ ready

alc asks each login's own vendor what is left: chatgpt.com for a Codex login, api.anthropic.com for Claude Code's, and the published balance endpoint for an OpenRouter, DeepSeek, Moonshot, MiniMax or Z.ai key. Nothing is ever written back and no token is refreshed, so a status command cannot invalidate the credential a running session is holding.

Two logins of one kind are two profiles. codex_home and claude_config_dir pin the directory a profile's credentials live in, and every launch through that profile uses that account — so the row you read is the account you spend:

CODEX_HOME=~/.codex-work codex login
alc config upsert codex-work --kind codex --codex-home ~/.codex-work
alc --provider codex-work claude

The second table comes from usage.jsonl in the config directory: one line per launch, and one per turn the Codex bridge carried. CACHED is the part of INPUT served from Codex's prompt cache; CACHE % is that token share, rounded to a whole percent. For traffic alc did not carry, token columns show — because the values are unknown, not zero. The remote-control page shows the same two sections behind the usage button in its header.

Usage has the whole thing.

Providers and agents

The two lookup tables, resolved for your own configuration by alc doctor.

Provider kinds

Kind Default endpoint Key env Protocols Claude-ready?
anthropic https://api.anthropic.com ANTHROPIC_API_KEY anthropic Yes
openai https://api.openai.com/v1 OPENAI_API_KEY responses, chat No
openrouter https://openrouter.ai/api/v1 OPENROUTER_API_KEY anthropic, responses, chat Yes
codex — (native codex login) — native Yes (bridge)
ollama http://localhost:11434 — anthropic, responses, chat Yes
vllm http://localhost:8000/v1 — responses, chat (+ anthropic) Yes
llamacpp http://localhost:8080/v1 LLAMA_API_KEY anthropic, responses, chat Yes
deepseek https://api.deepseek.com/v1 DEEPSEEK_API_KEY chat (+ anthropic) Yes
moonshot https://api.moonshot.ai/v1 MOONSHOT_API_KEY chat (+ anthropic) Yes
zai https://api.z.ai/api/paas/v4 ZAI_API_KEY chat (+ anthropic) Yes
minimax https://api.minimax.io/v1 MINIMAX_API_KEY chat (+ anthropic) Yes
groq https://api.groq.com/openai/v1 GROQ_API_KEY chat No
xai https://api.x.ai/v1 XAI_API_KEY chat No
google https://generativelanguage.googleapis.com/v1beta/openai GEMINI_API_KEY chat No
custom user-defined user-defined (--api-key-env) configurable No, unless configured

deepseek, moonshot, zai, and minimax each also ship a separate Anthropic-compatible base URL alongside their primary OpenAI-chat one (see alc config show) — that is what makes those four "Claude-ready" without any extra configuration. ollama, vllm, and llamacpp are local servers: each answers Anthropic Messages at its root, beside the OpenAI routes under /v1, so Claude Code runs on them whichever protocol a profile names for the other agents (Local models). Presets are starting values: run alc config show to see the exact model ID a profile currently uses, and edit it with alc config upsert when upstream renames or retires a model.

Agents

Agent Binary Accepts alc injects Codex bridge
Claude Code claude Anthropic-compatible endpoint --settings file (endpoint, model aliases, picker) + apiKeyHelper Yes (/model picker)
Codex CLI codex OpenAI Responses API flags + --config overrides Yes (native login)
OpenCode opencode Any API-compatible provider inline OPENCODE_CONFIG_CONTENT env Yes
Pi pi Anthropic-, OpenAI-, or OpenAI-compatible endpoint models.json merge + flags Yes
Copilot CLI copilot OpenAI- or Anthropic-compatible endpoint COPILOT_PROVIDER_* env Yes
Goose goose OpenAI- or Anthropic-compatible endpoint GOOSE_* + provider key env Yes
Qwen Code qwen OpenAI-, Anthropic-, or Gemini-compatible endpoint --auth-type flag + env Yes
Kimi Code CLI kimi OpenAI- or Anthropic-compatible endpoint temp --config-file (merged TOML, deleted after the run) Yes

alc launches agents that are already installed — install the ones you plan to use from the links above (Pi is npm install -g @earendil-works/pi-coding-agent). Every agent reaches the Codex bridge with one codex login whatever it accepts natively, and ALC_CLAUDE_BIN and its siblings override a binary path.

Codex bridge

alc tracks seven Codex models — the ones in the table above — and syncs their details from your ChatGPT account. The bridge itself keeps no allowlist: whatever slug it is handed goes upstream, and chatgpt.com decides, so a model alc has not been taught about is still reachable by naming it with --model on the day Codex ships it. That is what made gpt-6-astra usable in 1.5.0, when the hard-coded list in the bridge alc used to depend on was a release behind.

Effort. Every model accepts low, medium, high, xhigh, or max. Higher effort gives the model more room to reason, but can take longer and use more quota. Every model but the two Lunas also offers an ultra tier above max. That tier is reachable with native alc codex, but not through the bridge: the built-in helper's own effort range stops at max, so alc clamps it there and says so at launch rather than letting the request be refused mid-session.

See OpenAI's model selection guide, GPT-6.1 Sol reference, and Luna reference for current upstream details.

Choosing the defaults. GPT-6.1 Sol at low is the fallback only when no model or effort has been chosen; your saved selections stay as they are.

alc --codex claude --model gpt-6.1-sol --effort low --save

--save stores both in the selected alc provider. Without them the session starts on the alc provider's values, then the selected Codex profile's, then the model's documented default. A --model or --effort placed after -- is forwarded to Claude Code untouched and wins over what alc would inject; a --settings of your own is merged into alc's, yours winning, because Claude Code reads only one. A model chosen with /model applies to that session only; the next launch starts from the alc default again, so alc config stays the source of truth.

Auto mode and caching. No extra setup is needed. Auto mode still works; its classifier calls use Codex quota. alc also keeps each session on a stable cache route automatically, and alc usage shows how much input Codex actually reused. Cache reuse is best-effort, not guaranteed quota or billing savings. See Codex through Claude Code for details. Your own --settings still wins over alc's Claude Code defaults.

The picker. alc passes the model list through Claude Code's modelPicker setting, added in Claude Code 2.1.243. The picker shows only these GPT models and the Default row, because Claude's own lineup cannot be served through the adapter; older clients ignore the setting and still get the launch default as a selectable entry. Claude Code's built-in aliases stay on Codex as well: the Default row follows the alc default, haiku and background work use GPT-6 Luna, sonnet follows the session's starting model, and opus and fable use GPT-6.1 Sol, the first catalog entry.

Your Claude Code default. One thing to know about that picker, because it is Claude Code's and not alc's: the model it settles on is also written to ~/.claude/settings.json as your default for new sessions. That file is read by every Claude Code session on the machine, including the ones alc did not start, and those have no adapter in front of them — a plain claude afterwards would ask Anthropic for a GPT model and be told it does not exist.

alc puts that one key back when the session exits. It reads the value before the launch and restores it afterwards, so your own default survives a trip through the adapter. Two things it deliberately leaves alone: a real Claude model you switched to mid-session, which is your choice and not alc's to overrule, and a session that was killed outright, where nothing ran to restore anything. For that last case alc doctor still reports the file and the line — and the next alc --codex claude clears it, because a value that is already one only the adapter can serve is removed rather than put back.

Every other agent

OpenCode, Pi, and Kimi Code CLI speak the adapter's OpenAI Responses surface directly; Copilot CLI, Goose, and Qwen Code speak its OpenAI Chat Completions surface. Each is wired in with its own mechanism (alc-codex in OPENCODE_CONFIG_CONTENT, an alc-codex models.json entry, an alc-codex temp config, or the same BYOK environment variables and --auth-type each already uses for the openai kind) pointed at the loopback adapter instead of an in-session picker.

The model catalog comes from your ChatGPT account - the same party the adapter posts every turn to - so a model that account can drive shows up even when the installed Codex CLI has never heard of it. codex debug models is the fallback when that fetch cannot happen, and the catalog bundled into the binary is a floor neither of them can drop below: a discovered list may add models, never remove one. alc syncs once a day, and again immediately after Codex is upgraded:

alc models
alc models --refresh
alc models --json

The synchronized Codex context window is also passed to Claude Code through its documented CLAUDE_CODE_MAX_CONTEXT_TOKENS gateway setting, so unknown GPT IDs compact at the correct Codex limit instead of Claude's generic fallback.

How the bridge works

The bridge is alc's own code (src/bridge/). For Claude Code it runs as a background process of its own on a loopback port it keeps (alc bridge); for every other agent it runs inside the alc process on a random port and stops when that session ends. It reads and may refresh ~/.codex/auth.json; credentials are never copied into the alc config.

Local models

alc --ollama claude, alc --llamacpp claude and alc --vllm claude point Claude Code at the local server's Anthropic Messages endpoint — its root, beside the OpenAI routes under /v1. A local server serves only the models it loaded and answers one request at a time, or a few, so alc sets the session up differently from a hosted provider: every model alias (ANTHROPIC_DEFAULT_MODEL and the sonnet/opus/haiku tiers) pinned to the profile's model so Claude Code never asks the server for a model ID it does not have, non-essential traffic off, the real context window read from the server, and the first-token timeouts raised to thirty minutes.

That last one matters more than it sounds. Claude Code opens every session with a request of roughly 25k to 40k tokens — system prompt, tool schemas, project context — and a laptop-sized model reads that at a few dozen tokens per second: on an M3 MacBook Air, gemma4:12b needs about six minutes before the first token of a 22k-token request, and fifteen for a 39k one. Without the raised timeouts Claude Code abandons each attempt after six minutes and starts over.

What makes it pleasant on a laptop: a model whose ollama show <model> lists the tools capability, a 64k to 128k context window, a first request kept small (every MCP server, plugin, and skill adds tool schemas to it), and the model kept loaded so the prompt cache survives between turns. alc doctor prints an Ollama section with the server version, whether the model is pulled, whether it can call tools, and the context it actually gets.

Full tuning notes — KV cache type, keep-alive, why prompt length costs more than linearly on Gemma 4 — are in the provider guide.

llama.cpp and vLLM

llama-server -m Qwen3.8-27B-UD-Q4_K_XL.gguf --alias qwen3.8-27b --jinja -c 131072 --api-key "$LLAMA_API_KEY"

alc config upsert box --kind llamacpp --base-url http://127.0.0.1:8080/v1 --model qwen3.8-27b
printf '%s' "$LLAMA_API_KEY" | alc config key box --stdin
alc -p box claude

The profile keeps the OpenAI-style URL ending in /v1, which every other agent uses, and Claude Code is given the root. A key saved for the profile — or LLAMA_API_KEY, the variable llama-server itself reads — goes to every agent, and to Claude Code through its apiKeyHelper, never into a file. A vllm profile works the same way with vLLM's --api-key, and so does a vllm profile someone pointed at a llama-server before this kind existed.

Two settings are particular to these servers. Both render the model's own Jinja chat template, and many of those — Qwen's among them — refuse a system message anywhere but first, while Claude Code sends one mid-conversation to a model it does not recognise; alc sets CLAUDE_CODE_MODEL_CAPABILITIES so that text rides in the first user turn instead. And llama-server sends its response headers at once, then nothing until the whole prompt is read — minutes, for a long one — which Claude Code's stream watchdogs would end after five; CLAUDE_STREAM_IDLE_TIMEOUT_MS goes to its thirty-minute ceiling on every local server.

The context comes from llama.cpp's /props — the per-slot n_ctx, which is what one request gets on a server running several slots — or from vLLM's max_model_len. alc doctor prints a llama.cpp and vLLM section: the server and its build, whether it takes the key, whether it lists the model, that context, and whether /v1/messages exists.

Remote control

Drive it from your phone has the short version; this is the rest.

alc sessions                 # the link, then what is running (tmux sessions marked)
alc attach 7QK2              # any unambiguous id prefix
alc rename 7QK2 review
alc kill 7QK2
alc hub status               # or bare `alc hub`
alc hub stop --drain
alc remote url               # the link again, after it scrolled away
alc remote status            # on/off, bind, ceiling, where the files are
alc remote auto-share on     # share every session without --share
alc remote off               # refuse to share sessions at all
alc remote token --rotate    # invalidate every link handed out so far

Sessions are owned by a background hub, which is why they survive the terminal that started them and why they all appear on one page; ctrl-\ then d detaches. Sharing by default also lives in alc config, on the Sharing & remote screen.

Who owns the size

A shared session without --tmux is one terminal with two viewers, and a terminal has one size. That size belongs to the terminal you launched from, which is still sitting there drawing at it — so the page does not touch it. It draws the agent's real grid instead, as large as it fits, centred, with black where the ratio does not match. Resize your terminal and the page follows within a few seconds.

--tmux is for when the page is the side you are actually going to use:

alc --share --tmux --codex claude    # or -t

Your terminal and the hub each attach as their own tmux client, so nothing has to agree on a size. The trade is that it runs the opposite way round — the page sets the size, and a narrower or shorter terminal shows the top-left corner of the screen (pan with ctrl-b :refresh-client -L/-R/-U/-D). With no browser attached the size stays where it launched. tmux owns the keyboard too, so detaching is ctrl-b then d, and in exchange you get tmux's scrollback and a session that survives an ssh drop.

alc runs its own tmux server per session and starts it with no configuration file, so your own tmux is untouched, alc's sessions behave the same for everybody, and a ~/.tmux.conf is never a way into a session's environment. Running alc from inside tmux is fine. Needs tmux 3.2 or newer (on Windows, the native port below); alc doctor says what you have, and --tmux only applies to a shared session — it says so if you pass it without one. One caveat worth stating plainly: your local terminal is now a direct tmux client rather than a mirror, so it shows the agent's raw output. The browser still sees API keys alc injected masked; your own terminal does not.

On Windows, the alc installer automatically checks for and tries to install the native Windows port of tmux. If setup was skipped or could not finish, this is the manual fallback; then open a new terminal so PATH picks it up:

winget install --id arndawg.tmux-windows --exact

The tmux row of alc doctor says whether the native port was found. psmux also installs a tmux.exe, but alc cannot drive it — it cannot run the command sequence alc creates a session with — so alc looks past it on PATH and the two can be installed side by side; MSYS2, Cygwin, and WSL builds of tmux are not used on Windows either.

The native port passes command lines, environment, and working directory through the ANSI code page, so on Windows the tmux pane runs a small launcher — alc itself — that collects the agent's exact launch from the hub over loopback. Non-ASCII folder names, arguments, and environment values work as a result, and the provider API key never enters tmux's own environment. If alc is installed under a folder whose path is not plain ASCII, it uses the Windows 8.3 short path; on a drive with short names turned off, --tmux refuses and says to install alc under an ASCII path.

On Windows, stopping a --tmux session (alc kill or alc hub stop --drain) ends its tmux server and the agent with it. Windows has no hangup signal, so its card shows the session ended without an exit status, where macOS and Linux show the signal.

Reaching it from a phone

Three ways, all supported:

# Your own Wi-Fi — nothing to install
alc claude --share --bind-lan          # prints http://192.168.1.42:8787/#k=…

# Tailscale — alc stays on loopback, HTTPS, no third party
alc remote allow-host box.tail1a2b.ts.net
tailscale serve 8787

# Cloudflare Tunnel — works over cellular, no VPN
alc remote allow-host '*.trycloudflare.com'
cloudflared tunnel --url http://127.0.0.1:8787

alc answers only to names you allowed. Loopback is always allowed, and --bind-lan adds this machine's own addresses; alc remote allow-host adds a tunnel's hostname, exactly or as *.example.com for a tunnel that renames itself every run. Restart a running hub (alc hub stop --drain) for a new allowed host to take effect. A LAN link is plain HTTP, so the token crosses your local network in clear — fine at home, use a tunnel on café Wi-Fi.

Permissions

alc has five rungs, loosest last: plan (reads and plans, writes nothing), ask (asks before anything that changes the world), auto-edit (edits files without asking, still asks for commands), auto (acts inside whatever sandbox the agent has), and full (no gate). --permission <rung> sets where a session starts.

A shared session with no --permission starts at ask on the three agents whose flags alc verified against a real --help — Claude Code, Codex, and OpenCode — so a link opened on a phone is not looking at an autonomous agent there. The other five launch exactly as they would on their own, because guessing an unverified flag name into argv produces a session that will not start rather than a tightened one; name the rung with --permission to have alc pass the documented flag anyway, except on Pi, which has no permission model to set. The page can change the rung while the session runs, up to a ceiling — auto-edit by default, set on the Sharing & remote screen of alc config. Tightening is never gated.

Past the ceiling, the page shows a ticket and you type it at a terminal on the host machine:

alc confirm 7QK2M9XB4T

It prints granted: <rung>, and the page may apply that one change within the next minute. Tickets expire unredeemed after five minutes, and alc confirm refuses to run without a controlling terminal — which is the point: the agent cannot redeem its own ticket.

The eight agents do not agree on what a permission mode is, so alc records for each one whether it verified the flags against a real --help, whether the mode can be changed mid-session at all (Kimi is relaunch-only; Pi has no permission model and is not sandboxed), and whether the current mode was set at launch, read back off the screen, or merely assumed. The page shows the agent's own word beside alc's rung — auto-edit · Accept edits — because a single shared label would mislead.

A shared alc --codex claude runs on the same background bridge as an unshared one.

What this actually grants

A page that types into a coding agent is remote code execution on your machine, so it is worth being plain about the model:

  • The link's fragment (#k=…) is the credential. Anyone who has it can type into the session. It never reaches the server, a proxy, or an access log — but it is in your clipboard, so treat it like a password.
  • alc checks the Host header down to the port, requires an Origin on the WebSocket upgrade, and compares tokens in constant time. That is what stops a page at some other origin from driving your agent through your browser.
  • The browser's HTTP plane and the channel that creates processes are different sockets with different credentials — on Unix the control channel is a 0600 unix socket in a 0700 directory, so a browser token cannot reach session creation.
  • A shared session is screen sharing. alc masks the API keys it put into the environment, but anything else the agent prints, a viewer sees.
  • alc remote token --rotate invalidates every link handed out so far.
  • alc reads no configuration from the working repository, so a checked-in file can never turn sharing on.

--share needs a real terminal on both ends and refuses when input or output is redirected, so a scripted alc claude -p … > out.txt keeps behaving exactly as it does today.

Configuration

Platform Config directory
Windows %APPDATA%\alc
macOS/Linux ${XDG_CONFIG_HOME:-$HOME/.config}/alc
  • config.toml: provider metadata, models, defaults, URLs, and env-var names.
  • credentials.toml: locally saved API keys. On Unix, alc writes this file with mode 0600; on Windows it lives under the current user's AppData.
  • remote.toml: sharing — on/off, share-by-default, bind address, port, and the permission ceiling. alc config show prints the sharing and share-by-default values as comments at the end.
  • usage.jsonl: one line per launch, and one per turn the Codex bridge carried. alc usage aggregates it; delete it to start counting again.

Override the directory with ALC_CONFIG_DIR. Useful scripting commands:

alc config init
alc config show
alc config path
alc config upsert codex --kind codex --model gpt-6.1-sol --effort low
alc config upsert work --kind openrouter --model anthropic/claude-sonnet-4.6
printf '%s' "$OPENROUTER_API_KEY" | alc config key work --stdin
alc config set-default claude work
alc config remove work

The TUI keys are shown at the bottom of every screen. Tab/Shift+Tab, or 1/2/3, move between the three screens named in the header — Providers, Agent defaults, and Sharing & remote. On a Codex profile, ←/→ on the Model field opens the guided GPT model and effort chooser, which writes the launch defaults for alc --codex claude.

Credential precedence, the full alc config upsert flag list, and the Codex-to-Claude setting precedence are in the configuration guide.

Install

Windows PowerShell

irm https://raw.githubusercontent.com/treeleaves30760/all-code/main/install.ps1 | iex

macOS

curl -fsSL https://raw.githubusercontent.com/treeleaves30760/all-code/main/install.sh | sh

Linux / WSL

curl -fsSL https://raw.githubusercontent.com/treeleaves30760/all-code/main/install.sh | sh

The installer puts alc in ~/.local/bin (Windows: %USERPROFILE%\.local\bin) and adds that directory to your user PATH when needed. On macOS/Linux, restart the terminal or source the profile named by the installer; PowerShell updates the current session and your User PATH. If PATH cannot be changed, the installer prints the exact directory to add manually. To install into a different directory, set ALC_INSTALL_DIR: on macOS and Linux a custom directory is never added to PATH for you, while on Windows it is added to your User PATH like the default one. The Windows installer supports Windows PowerShell 5.1 and PowerShell 7, including 32-bit PowerShell on 64-bit Windows.

Optional tmux setup

After downloading, verifying SHA-256, and installing alc, the installer checks tmux -V for 3.2 or newer. A compatible install is left alone; otherwise it tries to install or upgrade tmux using an existing system package manager:

  • Windows: WinGet, package arndawg.tmux-windows, user scope, without forcing a CPU architecture. The automatic command accepts package and source agreements and disables interaction. It skips psmux and non-native ports; an old or unparseable first native port on PATH still blocks later ones.
  • macOS: Homebrew (brew install tmux, or brew upgrade tmux if already installed). Homebrew is never run with sudo.
  • Linux / WSL: the first available apt-get, dnf, yum, pacman, zypper, or apk. Non-root installs use cached sudo credentials, or ask for them only via a controlling terminal when stdout or stderr is a terminal. Package operations use noninteractive sudo and never read the piped script. pacman does not refresh package indexes on its own, avoiding a partial upgrade.

tmux is only needed for --tmux, not ordinary alc or plain --share. No Homebrew/WinGet bootstrap, source build, psmux removal, or tmux configuration changes are performed. Missing managers, unavailable privileges, unsupported packages/architectures, failed installs, and versions still hidden by an older PATH entry produce warnings and manual instructions; they do not fail the alc installation. The installer rechecks the version instead of assuming success.

PowerShell appends new User/Machine PATH entries to the current session without replacing session-only entries. If tmux is still missing, open a new terminal and check tmux -V and alc doctor. Manual fallbacks (choose your platform):

winget install --id arndawg.tmux-windows --exact
brew install tmux                                      # macOS (upgrade if already installed)
sudo apt-get update && sudo apt-get install -y tmux     # Debian / Ubuntu / WSL
sudo dnf install -y tmux                               # Fedora / RHEL (or yum)
sudo pacman -S --needed tmux                           # Arch; keep the system fully updated
sudo zypper install tmux                               # openSUSE
sudo apk add --upgrade tmux                            # Alpine

Installer opt-outs

ALC_NO_TMUX_INSTALL=1 skips automatic tmux setup; ALC_NO_PATH_UPDATE=1 separately stops alc's own PATH edits, including session PATH refresh. WinGet can still change persistent PATH itself. To avoid dependency-install side effects as well as installer PATH edits, set both:

curl -fsSL https://raw.githubusercontent.com/treeleaves30760/all-code/main/install.sh | ALC_NO_TMUX_INSTALL=1 ALC_NO_PATH_UPDATE=1 sh
$env:ALC_NO_TMUX_INSTALL = '1'
$env:ALC_NO_PATH_UPDATE = '1'
irm https://raw.githubusercontent.com/treeleaves30760/all-code/main/install.ps1 | iex
# Optional: clear these overrides for future installs in this session.
Remove-Item Env:ALC_NO_TMUX_INSTALL, Env:ALC_NO_PATH_UPDATE

Updating

alc update --check
alc update

alc update selects the correct release for the current OS and CPU, verifies the archive against the release's published SHA-256 checksum, checks the packaged version, and then replaces alc. Linux and macOS update immediately. Windows stages the verified files and finishes replacement just after the running alc.exe exits; wait a moment before checking alc --version. Use alc update --force to reinstall the current latest release.

Running sessions keep the binary they started with, so restart any open alc-launched agent after updating, and alc hub stop once its sessions are done.

Build from source

Rust 1.88 or newer:

cargo build --release --locked

The Codex bridge is alc's own code (src/bridge/), compiled into the binary, so a source build is a complete one — alc --codex <agent> works with nothing else installed. Release archives ship one binary, alc, for the same reason, with the license notices (LICENSE, THIRD_PARTY.md, THIRD_PARTY_LICENSES/) beside it.

Useful development checks:

cargo fmt -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-targets

Uninstall

Remove alc from the install directory, then optionally remove the config directory listed by alc config path. Removing the config also deletes locally saved API keys and cannot be undone.

License

alc is MIT licensed. Bundled third-party notices are in THIRD_PARTY.md.

About

Configure LLM providers once, then launch Claude Code, Codex CLI, or OpenCode with the provider you want — including Claude Code on your Codex/ChatGPT login. Supports Anthropic, OpenAI, OpenRouter, Ollama, and vLLM.

Topics

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages