Local Stream Deck controls for the Codex desktop app on macOS. It provides live chat status, commands, workflows, approval mode, usage, and context on keys. Each supported Stream Deck family gets a layout sized for its physical keys. Stream Deck + also gets four live dials.
This is an unofficial community project. It is not affiliated with or endorsed by OpenAI, Work Louder, Elgato, or Corsair, and it includes no proprietary OpenAI artwork or source.
Beta: the Stream Deck + experience is hardware-tested. The Stream Deck, Mini, Neo, and XL profiles pass automated and Elgato validation; their first independent hardware test is still in progress.
Requirements:
- macOS 13 or newer
- Codex desktop installed and signed in
- Stream Deck 7.1 or newer
- Stream Deck, Stream Deck Mini, Stream Deck Neo, Stream Deck XL, or Stream Deck +; dials require Stream Deck +
- Open the repository's Releases page.
- Download
com.todd.streamdeckcodex.streamDeckPluginfrom the newest release. - Double-click the downloaded file and approve installation in Stream Deck.
- Open Codex and select a chat.
- Grant Stream Deck Accessibility permission in System Settings → Privacy & Security → Accessibility.
No API key, account token, background service, or separate Codex CLI installation is required.
The editable profile for the connected model should install automatically. Every layout starts with Live Controls, followed by Agents & Sessions, then the workflow pages. Mini splits sections across additional pages to fit its six keys without dropping actions.
If no profile appears, download and open the matching release asset:
| Hardware | Manual profile asset |
|---|---|
| Stream Deck | streamdeckcodex-stream-deck.streamDeckProfile |
| Stream Deck Mini | streamdeckcodex-mini.streamDeckProfile |
| Stream Deck Neo | streamdeckcodex-neo.streamDeckProfile |
| Stream Deck XL | streamdeckcodex-xl.streamDeckProfile |
| Stream Deck + | streamdeckcodex-plus.streamDeckProfile |
The first page contains FAST, Permissions, PTT, Quota, YEET, New Project, Compact, and Context. Agents & Sessions contains six live chat slots, New Chat, and Plan. The remaining sections are Git & Delivery, Code Quality, Decisions, Workspace, and Codex Panels.
Reinstalling a profile creates another copy instead of overwriting personal changes. Remove an older test copy in Stream Deck's Profiles settings if you no longer need it.
All 50 key actions are present on every button-only profile. Model, Reasoning Effort, and Agent Navigator are dial-only; the key experience does not depend on them. Hold PTT while speaking and release the key to stop.
Please include the exact Stream Deck model, macOS version, Stream Deck version, Codex version, and the failing action when reporting a beta issue.
- Shows six recent Codex chats with live idle, running, unread, needs-input, error, and focused states.
- Opens the exact chat represented by a key or dial.
- Toggles FAST and Plan only after verifying the visible Codex result.
- Cycles the focused chat's real permission choices: Ask, Approve, YOLO, and Custom. Entering YOLO handles Codex's Full Access confirmation and verifies the result.
- Provides guarded push-to-talk, New Chat, New Project, Compact, Review, Browser, Files, Side chat, Settings, and other Codex commands.
- Launches named PR review, debugging, refactoring, testing, Git, and code workflows in the focused workspace.
- Displays weekly quota, banked resets, and focused-chat context from local Codex data.
- On Stream Deck +, previews and applies Model and Reasoning selections with live dial feedback.
| State | Color |
|---|---|
| Idle | #FFFFFF |
| Unread completion | #9BF396 |
| Thinking or running | #9CD5FE |
| Approval or answer required | #FFD0B8 |
| Error | #FF7373 |
| Empty slot | Off |
| Dial | Turn | Press |
|---|---|---|
| Agent | Browse recent chats | Open selected chat |
| Action | Select a curated Codex action | Run the displayed action |
| Model | Preview Luna, Terra, or Sol | Apply the displayed model |
| Reasoning | Preview a supported level | Apply the displayed level |
Touch-strip taps and holds are intentionally inert so a page swipe cannot run a command accidentally.
Commands that operate Codex's visible UI need Accessibility permission for the Stream Deck App. The native helper has a fixed allow-list; it cannot execute an arbitrary shell command.
Plan, FAST, Model, Reasoning, and Permissions reread the visible Codex control before reporting success. If Codex changes focus, contains a draft where that would be unsafe, or does not expose the expected control, the action fails closed and displays an alert.
Push-to-talk is guarded by a watchdog. Releasing the key, leaving the page, stopping the plugin, losing the parent process, a partial key-down failure, or the 60-second maximum hold releases every synthesized modifier.
The plugin runs locally and:
- opens Codex's local SQLite index read-only with
PRAGMA query_only; - reads bounded tails of recent Codex rollout and desktop-log files;
- uses the Codex App's bundled local app-server for account limits and model metadata;
- uses documented
codex://links and user-authorized macOS UI automation; - never writes Codex's SQLite database, rollouts, config, or App files;
- has no analytics, telemetry, independent network service, credential prompt, or direct credential access.
The plugin package is immutable at runtime and does not read its own manifest, which keeps it compatible with Elgato Marketplace DRM packaging.
See SECURITY.md for private vulnerability reporting.
- Confirm Codex is open with a chat selected.
- Confirm Stream Deck is enabled under macOS Accessibility.
- Clear any unsent draft before using Plan or FAST.
- Press the key again while the intended Codex window is visible.
The plugin refuses ambiguous focus instead of sending input to another chat.
Open the intended Codex chat and send or receive one message so Codex has an active composer, then press Permissions again. The key reads the visible composer; it does not guess from saved configuration.
Open the matching .streamDeckProfile release asset from the table above. If
the model-specific profile still does not appear, confirm the Stream Deck App
recognizes the device, then include its exact model in a beta bug report.
Usage needs a working signed-in Codex App session. Context needs a recent token snapshot from the focused chat. Both display no data rather than borrowing a value from another chat.
Use the bug report template. Do not attach Codex transcripts, rollout files, credentials, or private paths.
- Codex does not publish a stable desktop command API for every action, so some controls depend on documented shortcuts and visible accessibility labels.
- A Codex UI or local-schema update can require a companion update; failures are explicit and never shown as successful.
- Accept and Reject act on the currently visible approval or question. Read the request in Codex before accepting it.
- Unread acknowledgement is companion-local and resets when the plugin process is replaced.
- Stream Deck preserves customized profiles during plugin upgrades; profiles do not auto-update in place.
Development requires Node.js 24, librsvg, and ImageMagick.
git clone https://github.com/twidtwid/streamdeckcodex.git
cd streamdeckcodex
npm ci
npm run check
npm run linkUseful commands:
npm run check # formatting, types, tests, visual QA, build, validation
npm run pack # create dist/com.todd.streamdeckcodex.streamDeckPlugin
npm run qa:design # render and evaluate every profile keyThe connected mutation gate is intentionally separate from CI and fails closed unless it can prove a disposable fixture, exact foreground chat, empty composer, and cleanup. See QA.md before running connected QA.
npm ci
npm run check
npm audit --omit=dev
npm run packThe release should contain:
com.todd.streamdeckcodex.streamDeckPluginstreamdeckcodex-stream-deck.streamDeckProfilestreamdeckcodex-mini.streamDeckProfilestreamdeckcodex-neo.streamDeckProfilestreamdeckcodex-xl.streamDeckProfilestreamdeckcodex-plus.streamDeckProfile- release notes naming supported macOS, Stream Deck, and Codex versions
The package includes this project's MIT license and complete license texts for bundled runtime dependencies. Elgato's CLI validates the manifest and package before creating the installer.
Every redistributable pictogram is generated from Lucide. YEET is an original outlined wordmark generated from the open-licensed Barlow Condensed Black Italic font. No installed ChatGPT/Codex or Codex Micro artwork is embedded.
Implementation research included the official Stream Deck SDK, Marketplace plugin guidelines, and public open-source Stream Deck integrations listed in THIRD_PARTY_NOTICES.md.
The current requirement-by-requirement release audit is in MARKETPLACE.md.
Contributions are welcome. Read CONTRIBUTING.md and the Code of Conduct first.
