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

|
31 installs
| (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.

Native remote Codex connections always send an opaque project scope derived from a random installation-local salt and the workspace identity. The Gateway uses the authenticated Token plus that scope for separate Codex history and workspace volumes, independently of whether sshai synchronization is enabled. The salt and resulting scope are not written to project files or VS Code settings.

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 model and per-model reasoning-effort selectors below the chat status, and applies changes to the next message in the current thread. /model opens the same model 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 reusable prompt templates in extension-wide storage. A template can be created manually or prefilled from any historical user request, then inserted into the composer, renamed, edited, or deleted from the Templates panel.
  • 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.
  • Analyzes each completed turn's shell commands as one workflow through the configured local Ruleport service. A diamond action on every completed command opens a left-side, scrollable explanation popover with independently collapsible steps, detailed semantics, illustrative state/output after each command, and an illustrative final result.
  • 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. Pin it to the GNOME/KDE Dock like any other application. Chrome uses a dedicated CWC profile with browser background services disabled and, when XWayland is available, a matching desktop class. Standalone windows therefore stay under the CWC icon without Chrome update, default-browser, or separate Settings UI. Each successful cwc launch records up to six recent folders or workspace files; right-click the pinned icon to reopen one directly. The stored paths stay local in ~/.local/state/codex-workspace-chat/recent-workspaces.json. The installer also records the active Node.js executable so Dock launches work when Node is provided by NVM and is absent from the desktop session's PATH.

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. Use Ctrl+Shift+C and Ctrl+Shift+V to copy and paste; Ctrl+C remains the terminal interrupt shortcut.

The standalone title bar also has a Files action. It opens a resizable workspace file tree and compact UTF-8 text editor beside the chat. Directories load only when expanded, Ctrl+S saves the current file, and chat file links open in the same editor. Saves detect changes made on disk after the file was opened. The editor is intentionally limited to workspace text files up to 8 MB; it does not load an extension host, language server, debugger, or the rest of the VS Code workbench.

Smart Run and Stop

The ▶ title action detects and runs the current project in a visible terminal. The ■ action sends the detected graceful stop command, or terminates the Smart Run terminal when the project has no explicit stop script. Detection checks workspace overrides first, followed by common package scripts, Docker Compose, Make, Cargo, Django, Python, Go, and .NET project markers. For example, an Astro package with dev and dev:stop scripts resolves to npm run dev and npm run dev:stop (or the package manager selected by packageManager and lockfiles).

When local heuristics cannot determine a run command, Smart Run can call the development server from ~/all/ai-dev/web-skills at http://127.0.0.1:4341/v1 by default. It sends a bounded project summary and the current package.json, never source files. Ruleport can satisfy a learned package_script rule locally or ask the configured OpenAI-compatible target. AI-suggested run and stop commands are displayed for confirmation before execution. The target defaults to the extension's Remote endpoint and saved Token; every Ruleport and model endpoint can be overridden in settings.

Workspace-specific overrides:

  • codexWorkspaceChat.smartRun.runCommand
  • codexWorkspaceChat.smartRun.stopCommand

Ruleport fallback settings:

  • codexWorkspaceChat.smartRun.aiFallback
  • codexWorkspaceChat.smartRun.heuristicsEnabled — disable this to force Ruleport during testing; explicit workspace overrides still win.
  • codexWorkspaceChat.smartRun.includeChatContext — include up to 12 recent user/assistant messages (24,000 characters total) in Ruleport fallback analysis. Tool output, system messages, and command logs are excluded.
  • codexWorkspaceChat.smartRun.ruleProxyUrl
  • codexWorkspaceChat.smartRun.ruleProxyTokenEnv
  • codexWorkspaceChat.smartRun.aiTargetBaseUrl
  • codexWorkspaceChat.smartRun.aiModel
  • codexWorkspaceChat.smartRun.aiTokenEnv

Command workflow explanations

Command workflow explanations are enabled by default with codexWorkspaceChat.commandExplanation.enabled. After a native Codex turn completes, the extension sends that turn's command text, status, and a bounded tail of each command's actual output to the same Ruleport URL and analysis provider configured for Smart Run. Ruleport receives the whole sequence in one request so it can explain how the commands relate instead of describing each one without context.

Each completed command shows a diamond action. Clicking it opens the workflow popover at the left edge of the chat and selects that command's node. Every node can be expanded or collapsed independently and includes the exact command, a plain-language explanation, ordered effects, an illustrative post-command state, and illustrative terminal output. The final section shows an illustrative result for the complete workflow. Parser output is rendered only as text and is never executed. Disable automatic analysis in VS Code settings; the diamond action can still request an explanation on demand.

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 /v1 WebSocket or HTTP endpoint, such as wss://gateway.example.com/v1. The same /v1 base provides model discovery and 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.requestObservations.enabled — enabled by default. VS Code and cwc write one JSON record for every submitted prompt to .mai-chat/request-observations/, independently of native, hybrid, or application-managed thread storage. Each record captures the Agent, effective model, effective Codex reasoning effort, thread, working directory, transport, host, and request timestamp.
  • codexWorkspaceChat.requestObservations.includePrompt — enabled by default. Include the submitted prompt in each observation so the records can later become a model and reasoning-effort selection dataset. Disable it to retain request settings without retaining prompt text.
  • codexWorkspaceChat.dynamicWorkspaceTools.enabled — enabled by default for remote native Codex. It exposes built-in local_workspace tools for listing, reading, searching, writing, exact replacement, and running shell commands against the live local project. File paths and command working directories cannot escape the selected workspace root. Shell commands run on the machine hosting VS Code or cwc, use that machine's environment and network, and return their stdout, stderr, and exit status to Codex.
  • codexWorkspaceChat.dynamicTools — optional additional function and namespace tools for native Codex threads. Each function maps to one explicit VS Code command ID. The command receives the generated argument object first and call metadata second; its return value is sent back to Codex as text. The extension never exposes unlisted VS Code commands.
  • codexWorkspaceChat.sync.* — optional workspace synchronization, off by default. See the section below.
  • 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.

Workspace synchronization (optional)

When Codex runs behind a remote endpoint, the agent works on the remote host's copy of the workspace, not on this machine's files. If the project is edited directly on that host, for example over VS Code Remote SSH, there is one copy and nothing to synchronize. When a separate local checkout is kept instead, the extension can supervise an external sshai sync process that keeps the two directories in step.

This is off by default. With codexWorkspaceChat.sync.enabled unset, the extension never starts a process, never looks for the sshai binary, and reports no synchronization state, so an ordinary single-machine setup is unaffected.

{
  "codexWorkspaceChat.sync.enabled": true,
  "codexWorkspaceChat.sync.target": "dev-server",
  "codexWorkspaceChat.sync.remoteRoot": "/srv/codex-workspace-chat/workspaces",
  "codexWorkspaceChat.sync.ignore": ["node_modules", ".git", "dist", ".mai-chat"]
}

The extension owns only the process lifetime: it starts sshai sync with these settings, streams its output to the Codex Workspace Chat Sync output channel, restarts it with backoff if it exits unexpectedly, and stops it when the settings are turned off or the window closes. File comparison, conflict handling, and transfer belong entirely to sshai; the extension implements no synchronization of its own and reads no file contents for it.

With automatic routing, the extension derives a stable ws-<20 hex digits> ID from the normalized absolute local project path. It synchronizes to <remoteRoot>/<workspaceId> and sends the same ID as x-codex-workspace-id to the configured remote endpoint. The endpoint must support this optional workspace routing protocol. Native connections and remote Responses requests wait for the first successful synchronization cycle. The SSH account needs non-interactive authentication and write access to the supplied root. Moving the local project changes its ID; reopening it at the same path reuses its directory. Set the root once for a service; individual project directories need no manual configuration. The bottom File sync indicator shows the last reported cycle, conflicts, or a failure. This integration supports the first folder in a VS Code or standalone window; open other projects in separate windows. The standalone host supervises the same sshai sync process and reports the same synchronization status before it opens a remote Agent connection.

Existing sync.remotePath values retain their exact destinations and omit automatic workspace routing. Remove that legacy setting to opt into generated project directories. When synchronization is disabled, no workspace ID is added to requests.

codexWorkspaceChat.sync.conflict defaults to safe, which reports a path both sides changed and modifies neither. codexWorkspaceChat.sync.ignoreVcs excludes .git, which also stops the remote agent from reading Git history, so leave it off unless .git proves troublesome. Use Codex Workspace Chat: Start/Stop Workspace Synchronization and Show Workspace Synchronization Log to control and inspect it.

Because cycles run on an interval, a file the agent just created on the remote host can briefly be missing locally. Clicking its link then reports that the file has not arrived yet rather than a bare "file not found".

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.

Dynamic tool calling

With remote transport, native Codex receives the built-in local_workspace namespace by default. Its list, read, search, write, replace, and run tools act directly on the selected local VS Code workspace. run executes through the local machine's shell, so tests, builds, Git, package managers, and network requests use the machine running VS Code or cwc instead of the Gateway container. Codex is instructed to prefer these tools because a remote runtime directory may be only a synchronized copy. Disable them with codexWorkspaceChat.dynamicWorkspaceTools.enabled if needed.

Codex accepts dynamic tool definitions only when a thread is created. When an older remote thread or application-managed Codex backend is used for the first time after this feature is enabled, the extension transparently creates a tool-enabled replacement and injects the retained user and assistant context. The previous native thread remains available in history.

Native Codex threads can also call VS Code commands that you explicitly register in settings.json. For example:

"codexWorkspaceChat.dynamicTools": [
  {
    "name": "workspace_lookup",
    "description": "Look up metadata for a workspace-relative path.",
    "command": "example.lookupWorkspacePath",
    "inputSchema": {
      "type": "object",
      "properties": {
        "path": { "type": "string" }
      },
      "required": ["path"],
      "additionalProperties": false
    }
  }
]

The target command receives (arguments, metadata), where metadata contains tool, optional namespace, callId, threadId, and turnId. Strings are returned directly and other results are JSON encoded without an extension-specific size limit. Namespace entries use the Codex namespace shape and contain function entries with their own command fields. A failed or unknown command is returned to Codex as a failed tool result. Custom dynamic tools work with the local daemon and with a compatible remote native WebSocket gateway. The built-in local workspace namespace is attached only to remote native Codex. Responses-compatible Claude and Custom agents do not use this bidirectional protocol.

Command-execution and file-change approvals are also handled. Other server-initiated interactions, such as structured MCP elicitation or custom tool user-input forms, are rejected explicitly rather than left hanging.

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