Skip to content
| Marketplace
Sign in
Visual Studio Code>Machine Learning>Codex Workspace ChatNew to Visual Studio Code? Get it now.
Codex Workspace Chat

Codex Workspace Chat

painterner

| (0) | Free
Workspace-mapped Codex and Claude chat with configurable local and remote Responses endpoints.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Codex Workspace Chat

A VS Code chat view that lives in the Secondary Side Bar, talks to the local Codex CLI through codex app-server, lists sessions whose cwd matches the current workspace, and automatically resumes the session previously selected for that workspace. It can also use Claude through the official API or any configured provider that exposes an OpenAI-compatible Responses endpoint.

It can also connect to a configured remote WebSocket or OpenAI-compatible Responses endpoint. Claude CLI does not run in local daemon mode, so Claude requires the official API or another provider's relay service.

Features

  • Starts or reuses the host-wide codex app-server daemon and connects directly to its Unix control socket over WebSocket; threads and VS Code windows share the persistent daemon instead of spawning dedicated app-server processes or proxy children.
  • Can alternatively connect through a configured remote WebSocket endpoint without exposing the local app-server listener.
  • Independently configures Codex and Claude transports. Codex defaults to host-side localDaemon; Claude defaults to remote and can be disabled without changing Codex. The removed localDirect setting is migrated to localDaemon.
  • When a remote endpoint is enabled, discovers its available models through GET /v1/models and shows a compact Agent selector above the thread picker.
  • Discovers the visible Codex catalog through model/list, shows a model selector below the chat status, and applies changes to the next message in the current thread. /model opens the same list and /model <model-id> selects one directly.
  • Supports application-managed, provider-native, and hybrid thread storage. Application-managed threads preserve one logical thread ID, transcript, and draft across Codex, Claude, and Custom model changes; hybrid threads retain native behavior until the first model switch and then persist as application-managed threads.
  • Sends Claude turns through the configured streamed POST /v1/responses endpoint. The bearer token remains in the Extension Host and is never exposed to Webview JavaScript.
  • Adds optional Custom Responses Agents from an explicit base URL and model list. Authentication is optional; a saved bearer Token stays in per-workspace VS Code SecretStorage, while an environment variable can be used as fallback.
  • Accepts standard streamed Responses events (response.output_text.delta, response.completed, response.failed, and response.incomplete) and standard message/output content.
  • In provider-native mode, keeps Claude transcripts in extension global storage, isolated by VS Code workspace and Claude model. Application-managed and converted hybrid threads instead keep one provider-neutral transcript for model handoffs.
  • Runs extension-owned Claude threads statelessly with store:false: every request contains a bounded copy of the locally saved transcript, so Reload Window, provider restarts, Rewind, and Fork never depend on a server-side session ID.
  • Supports Claude Rewind to here and Fork from here against the local conversation tree. Rewind restores the selected prompt and keeps workspace files unchanged because the interactive wrapper does not expose reversible disk checkpoints; Fork preserves the source thread and disk.
  • Opens in the right-side Secondary Side Bar on VS Code 1.106+, matching the Codex and Claude layout; older supported versions fall back to the Activity Bar/Primary Side Bar.
  • Synchronizes every restored Webview instance so Reload Window cannot strand the visible chat on the static Connecting screen when VS Code restores a sidebar placement.
  • Keeps protocol traffic on child stdout and diagnostic logs on child stderr.
  • Times out stalled app-server RPC calls after 30 seconds and records request/response stages in the Output Channel instead of waiting forever.
  • In a single-folder window, finds CLI, VS Code, and app-server threads with an exact cwd match and preserves the existing folder-level behavior.
  • In a multi-root .code-workspace, maintains a dedicated workspace-owned thread registry. Only threads created, forked, imported, or included by the one-time binding migration are shown; unrelated history from its member folders is not imported.
  • Keeps each workspace-owned thread's real folder cwd, labels it with the corresponding root name, and uses the active editor's root only as the default for a newly created thread.
  • Switching editors between roots never clears or replaces the selected conversation. The workspace remembers one selected thread independently of its member folders.
  • On first upgrade, migrates only the last folder binding for each root into the workspace registry so the previously selected conversations remain reachable; it does not import each folder's complete history.
  • When VS Code's Add Folder to Workspace converts an existing single-folder window into a multi-root workspace, adopts all paginated threads from that original folder as workspace membership. The newly added folder's old history is not adopted, and rollout files are referenced rather than copied or duplicated.
  • Automatically resumes the saved thread or the most recent matching thread.
  • If another Codex process owns a thread's active writer, falls back to thread/read and opens the complete history in explicit read-only mode instead of failing with a generic error. Sending and Rewind stay disabled; after closing the owner, Refresh retries writable resume. Viewing, Markdown/JSONL export, and Fork remain available.
  • Persists unsent composer drafts in VS Code workspace state, isolated per thread. Switching threads restores each thread's own draft, and Reload Window restores the active draft; sending or clearing the composer removes the saved value.
  • Keeps a newly created empty thread as a persistent local draft until its first message. It can be switched away from, switched back to, and restored after Reload Window without asking Codex to resume a nonexistent rollout file.
  • Renders persisted user, assistant, command, file-change, and tool items.
  • Streams assistant messages and command output through 50 ms batched deltas, updates only the active message DOM node, and sends high-frequency updates only to visible Webviews. A hidden view receives an authoritative snapshot when shown again.
  • Uses an explicit output-follow lock: scrolling upward stops automatic pull-to-bottom behavior during both streaming and full state redraws, preserves the exact scroll offset, and resumes following only after the user returns to the bottom or sends a new prompt.
  • Shows compact current-session statistics: active model/reasoning effort, on-disk JSONL size, loaded message-text size, message/turn counts, command-output size, current context-window usage, and cumulative tokens. Token metrics update from thread/tokenUsage/updated when Codex reports them.
  • Shows account limits reported by Codex app-server: each named/model-specific bucket, rolling window duration (including 5-hour and weekly windows), remaining percentage, reset countdown, credits, and spend controls. The row refreshes from account/rateLimits/updated and can be refreshed manually.
  • Reports transient model capacity errors separately from account limits. UI-facing failures use stable CW_* error codes and controlled copy; raw app-server/backend messages are kept in the private Output Channel instead of being rendered to users.
  • Keeps command execution compact by default: one command line plus the latest four output lines, with full logs available on click.
  • Renders assistant Markdown in a compact, sanitized layout with local KaTeX support for $...$, $$...$$, \\(...\\), and \\[...\\] formulas.
  • Renders completed fenced mermaid diagrams with a lazily loaded, locally packaged Mermaid renderer using strict security and bounded graph sizes.
  • Opens local Markdown links and file-change paths with VS Code's registered viewer, so images, PDFs, notebooks, and text files use their appropriate editor. Workspace-relative paths, absolute paths, file:// URIs, and path:line[:column] or #LlineCcolumn locations are supported; line locations use the text editor and fall back to the registered viewer for binary files, while executable URI schemes are rejected.
  • Freezes streaming DOM updates while text is selected so copying a live response does not lose the selection.
  • Shows Fork from here on the assistant response for a completed turn. It creates and selects a new thread containing history through the selected turn, omits the later conversation, preserves the original thread, leaves disk files unchanged, and updates the workspace binding to the fork. For an interrupted/incomplete turn that Codex cannot include directly, it can fork immediately before that turn and restore its user prompt in the new branch.
  • Shows Rewind to here on the corresponding user input. It removes that user turn and everything after it in place, automatically reverses their recorded disk patches, and restores the prompt to the composer so it can be edited or run again. It uses thread/revert with a compatible in-place rollback fallback for older connections or non-paginated legacy threads; no duplicate thread is created. A modal confirmation is required, including a warning before replacing an unsent draft.
  • Persists per-turn disk checkpoints from turn/diff/updated. Rewind uses git apply --reverse --check, aborts on post-turn user edits instead of overwriting them, restores any already-reversed patches if a later patch conflicts, and offers Restore Files after success. If any removed legacy/interrupted turn has no checkpoint, the extension offers an explicit conversation-only rewind and leaves every disk file unchanged instead of attempting a partial reversal. Git is required for automatic disk reversal.
  • Supports new threads, thread switching, refresh, and turn interruption.
  • Allows switching to another thread while the current model is still generating. Active turns continue in the background, are marked with a running indicator in the thread picker, and resynchronize from app-server when selected again; Stop always targets only the selected thread.
  • Keeps the composer sendable while a model is generating. Additional messages enter a visible per-thread FIFO queue, can be removed before dispatch, and are submitted automatically as soon as the preceding turn completes.
  • Adds a one-click Git commit action that gives an isolated, low-reasoning Codex helper only the latest user/model turn, uses its single-line summary as the commit subject, and commits changes under the active workspace path. A persistent adjacent push icon optionally runs git push after a successful commit.
  • Imports and exports sessions from compact title-bar actions in both VS Code and the standalone window. Standalone imports use the browser file picker and exports use browser downloads. Every Agent supports readable Markdown; Claude and Custom Responses use portable JSONL maintained by the extension, while native Codex JSONL remains a lossless rollout copy.
  • Creates a clean native Codex continuation from the current rendered history. Smart compact keeps user/assistant text plus bounded command/tool summaries, while Messages only excludes tool records entirely; both remove binary/encoded payloads, preserve the original task and workspace files, carry the unsent draft forward, and switch to the new same-directory task.
  • Displays command and file-change approval requests with accept/decline controls.
  • Detects a missing Codex executable and offers the official installation guide or the codexPath setting instead of showing a generic spawn error.
  • Supports always-ready voice dictation in the composer. The first click/focus requests microphone access, then an AudioWorklet performs adaptive local voice activity detection, keeps 200 ms of pre-roll, and forwards 100 ms PCM chunks only while speech is active. User transcript is inserted at the current caret without blocking or replacing concurrent keyboard input. Voice can use local Codex Realtime or an independently configured OpenAI-compatible audio transcription model.
  • Provides a settings gear for transport, remote endpoint URL/token, Custom Responses URL/models/token, voice provider/model/base URL/token/language, VAD threshold, and automatic microphone startup. Tokens are stored per workspace in VS Code SecretStorage and never written to settings.json or returned to the chat Webview.

Requirements

  • VS Code 1.96 or newer.
  • A recent codex CLI available on PATH and already authenticated.
  • A folder or workspace open in VS Code.

If Codex is elsewhere, set codexWorkspaceChat.codexPath to the executable path. The value is passed directly to child_process.spawn; it is not evaluated by a shell.

Standalone terminal launcher

Run Codex Workspace Chat: Install cwc Standalone Launcher once from the Command Palette. It installs cwc into ~/.local/bin and the standalone runtime into ~/.local/share/codex-workspace-chat; ensure ~/.local/bin is in PATH. Then open a standalone chat window for the current directory or another folder:

On Linux, the installer also registers a Codex Workspace Chat desktop entry and icon. Chrome uses a dedicated CWC profile and matching desktop class, so GNOME/KDE group standalone windows under their own taskbar icon rather than the regular Chrome icon.

cwc .
cwc /path/to/project
cwc /path/to/project.code-workspace

The launcher does not start VS Code. It starts a small local Node host, launches the existing chat UI in a Chrome/Chromium app window, and connects directly to the shared Codex daemon control socket. The HTTP listener binds only to 127.0.0.1 and every route requires a random per-process token. Closing the app window stops the local host connection after a short grace period; the daemon and active Codex turns remain available to other clients.

The standalone window also provides a collapsible terminal from the >_ title button. It uses xterm.js in the browser and a separate local node-pty daemon scoped to the current workspace. Drag the terminal's top edge to resize it. Closing the Chrome window or the standalone chat host only detaches the terminal; its shell and running jobs remain alive and are restored with scrollback when cwc opens that workspace again. Use the terminal's + action to explicitly close the persistent shell and create a fresh one.

Native Codex session files and authentication are shared with the CLI and VS Code extension. The standalone host reads normal VS Code user/workspace settings, but its workspace/thread mapping and drafts are stored separately under ~/.local/state/codex-workspace-chat/standalone. VS Code SecretStorage cannot be read outside VS Code, so standalone remote endpoint, Custom Responses, and HTTP voice tokens must currently be supplied through their configured environment variables. Opening a source link uses the operating system's normal file handler and may start an editor only when requested.

Claude through a remote API

Claude CLI does not run in local daemon mode, so there is no local Claude transport. Use the official Claude API or another provider's relay service that exposes an OpenAI-compatible Responses endpoint:

  1. Leave codexWorkspaceChat.claude.transportMode at its default remote when a remote Claude provider is available (or choose Disabled to hide Claude).
  2. Set codexWorkspaceChat.remoteEndpoint to the provider's WebSocket or HTTP endpoint. For example, an endpoint ending in /v1/codex is used for native Codex transport and its /v1 base is used for Responses requests.
  3. Open Codex Workspace Chat: Configure Agents and Voice and save the provider token securely. The environment variable named by codexWorkspaceChat.remoteTokenEnv remains a supported fallback.
  4. Reload the window and choose Claude from the Agent selector.

Codex keeps its own selected transport; choosing Claude does not force Codex into remote mode. Claude supports local thread selection, drafts, Stop, Rewind, Fork, Markdown and portable JSONL import/export, Markdown rendering/link opening, and independently configured HTTP voice transcription.

Custom Responses API

Open Codex Workspace Chat: Configure Agents and Voice, then under Custom Responses API:

  1. Enable the custom Agent.
  2. Enter an API base URL such as http://127.0.0.1:8080/v1. The extension calls {baseUrl}/responses.
  3. Enter one or more model IDs, one per line or comma-separated. These become separate choices in the Agent selector; the extension does not require a /models endpoint.
  4. Optionally save a bearer Token, or name an environment variable containing it. Leave both blank for an unauthenticated local endpoint.
  5. Save, reconnect, and select Custom Responses from the Agent selector.

The endpoint must accept model, string input, stream:true, and store:false, and return Responses-compatible SSE. Conversation state is extension-owned: each turn sends a bounded copy of the locally stored transcript, so Reload Window, Rewind, Fork, Markdown/portable JSONL import/export, drafts, Stop, and thread switching do not depend on server-side response storage. Rewind changes conversation history and restores the selected prompt, but it cannot reverse disk changes because a generic Responses API exposes no disk checkpoint protocol. Custom Agents also do not expose native Codex account limits or structured command/file-change cards.

Settings keys:

  • codexWorkspaceChat.customResponses.enabled
  • codexWorkspaceChat.customResponses.baseUrl
  • codexWorkspaceChat.customResponses.models
  • codexWorkspaceChat.customResponses.tokenEnv

Voice input

Voice input is enabled by default. Focus or click the message box once to grant microphone access; the green dot means it is listening, and the red pulsing dot means speech is active. Click the dot to stop or restart the current microphone session. Use the 🎙 Auto / 🎙 Off button to persistently enable or disable automatic startup; turning it off immediately releases the microphone and remains off after Reload Window. Hiding the chat view also releases the microphone.

The default codexRealtime provider uses an ephemeral local Codex thread, enables client-managed handoffs, consumes only user transcript events, and never submits dictated text automatically. It requires localDaemon. The openaiTranscription provider works with Codex, Claude, or Custom Responses in every transport mode and posts each completed VAD utterance as a WAV file to the configured OpenAI-compatible /v1/audio/transcriptions endpoint. Its model, base URL, language hint, environment fallback, and SecretStorage Token are independent from the chat Agent.

Settings:

The extension settings panel saves connection, model, and voice preferences at VS Code user scope so they are reused across projects, while thread storage mode remains workspace-specific. API tokens are kept in SecretStorage and keyed by service endpoint; native settings.json workspace overrides remain available when a project genuinely needs different values.

  • codexWorkspaceChat.threadStorageMode — this is stored per workspace. hybrid (default) keeps existing provider-owned threads visible and converts the current native thread on the first cross-provider model switch. appManaged keeps one application-owned thread across all models and uses the manual smart-sync button to import matching local Codex and Claude sessions. native preserves the original provider-owned behavior.
  • codexWorkspaceChat.threadStorageLocation — this is stored per workspace. workspace (default) writes application-managed and Responses thread history to .mai-chat/ inside the project, so copying, moving, or cloning the folder carries the conversations with it. global is the previous behavior and keeps history in the extension global storage on this machine only. Changing it moves the existing threads of that workspace to the new location; the first time an existing workspace is opened the extension asks once before moving anything. Add .mai-chat/ to .gitignore to keep history out of version control.
  • codexWorkspaceChat.voiceInput.enabled — show and enable voice dictation.
  • codexWorkspaceChat.voiceInput.autoStart — begin listening after the first input gesture.
  • codexWorkspaceChat.voiceInput.vadThreshold — raise this if background noise triggers speech detection.
  • codexWorkspaceChat.voiceInput.provider — codexRealtime or openaiTranscription.
  • codexWorkspaceChat.voiceInput.baseUrl / .model / .language — HTTP transcription endpoint settings.
  • codexWorkspaceChat.voiceInput.tokenEnv — environment fallback when no voice Token is saved in the settings panel.

Codex Workspace Chat: Export All Threads writes every thread of the current workspace — application-managed and Responses alike — to a single .jsonl bundle, and Import All Threads reads one back, rebinding each thread to the current workspace path and asking whether to skip or replace threads that already exist. Use these to move history between machines or to keep a backup independent of where the folder lives.

The ⇄ toolbar action performs the local smart sync on demand. It scans only sessions whose cwd matches an open workspace folder, reconstructs the active Claude parent chain, reads Codex history through the paginated app-server API, and imports them as Codex * title or Claude * title. Source IDs and file/thread fingerprints make repeated syncs update changed imports without creating duplicates; application-only messages are preserved.

The ↪ toolbar action (Codex Workspace Chat: Continue in Another Agent) hands the current thread to a different agent. Today the target is Claude Code: the rendered history is compacted the same way ≋ compacts it — user/assistant text plus bounded command summaries, with binary and oversized payloads removed — and written as a native Claude session under ~/.claude/projects/<mangled-cwd>/<session-id>.jsonl (honoring CLAUDE_CONFIG_DIR). A leading injected note records which agent and model produced the transferred answers, so Claude does not mistake them for its own. Choose whether to open it in the Claude Code VS Code extension, in a terminal through claude --resume <session-id>, or to only write the file and resume later. The source thread, the session id, and the workspace files are left unchanged, and an existing session file is never overwritten. This is the mirror image of the ⇄ smart sync, which imports the same files back.

For application-managed threads, ⊟ compacts the current thread in place. The selected Agent produces a durable continuation summary, the summary and compact boundary are persisted with the logical thread, and future Codex, Claude, or Custom requests send that baseline plus only messages created after the boundary. Earlier messages remain available in the UI. The existing ≋ action remains the separate “continue as a new compact task” workflow.

Development

npm install
npm run check
npm test
npm run smoke

Press F5 in VS Code with this directory open to launch an Extension Development Host. Open the Codex Chat icon in the Activity Bar.

Session selection

On first open, the extension calls thread/list with:

  • the current workspace folder as cwd;
  • cli, vscode, and appServer source kinds;
  • newest activity first.

For provider-native threads, the default mappedOrLatest mode resumes the stored mapping first, then falls back to the most recently active matching thread. Change codexWorkspaceChat.autoResume to mappedOnly or off if desired. Application-managed threads restore their own workspace selection independently.

For a multi-root workspace, the folder containing the active editor is preferred; otherwise the first workspace folder is used.

Import and export

Use the download and export icons in the Workspace Chat title bar, or run Codex Workspace Chat: Import Session / Export Session from the Command Palette.

  • Markdown exports the messages currently loaded in the UI in a readable document. The file also contains hidden, versioned markers so re-import preserves message roles and exact text. On import, user and assistant messages become model-visible history in a new thread; command, tool, reasoning-summary, and system entries remain visible reference material but are not injected as model replies.
  • JSONL (Codex) copies the active native Codex rollout file byte-for-byte. It may include prompts, tool calls, local paths, and internal session state, so treat it as sensitive. Import validates the native session_meta header and asks app-server to fork the file into a new native thread; the selected file is never used as the live writable session.
  • Portable JSONL (application-managed / Claude / Custom Responses) writes a versioned header followed by one structured message per line. Import creates a new locally persisted thread under the currently selected storage mode and model.

Import and export are disabled while a turn is active so the result cannot end on a partially written event. Native Codex JSONL import requires localDaemon, because a remote provider cannot read a file from the VS Code machine by local path.

Why stdio does not break logging here

When stdout is an IPC protocol, arbitrary application output on stdout corrupts message framing. A second failure mode occurs when a parent does not continuously drain a piped stdout or stderr: the operating-system pipe buffer can fill and block the child. Interactive terminal applications may also change behavior when stdout is not a TTY.

This extension avoids those cases:

  • app-server is designed for non-TTY JSONL over stdio;
  • child stdout is parsed only as JSONL and never forwarded as log text;
  • child stderr is continuously drained into the Codex Workspace Chat Output Channel;
  • stdout and stderr are never merged;
  • stdout is continuously drained through a readline interface;
  • the Webview and extension diagnostics use VS Code APIs rather than the protocol stream.

If a future wrapper is placed between this extension and app-server, that wrapper must also send all diagnostics to stderr and reserve stdout exclusively for JSONL.

Current scope

The first release handles command-execution and file-change approvals. Less common server-initiated interactions, such as structured MCP elicitation or custom tool user-input forms, are rejected explicitly rather than left hanging. They can be added as additional Webview cards using the same request/response path.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft