Preface

When developing agents with DeepSeek Harness (dsh), you might encounter a requirement where the agent in the session needs to consult an external coding agent—such as OpenAI’s Codex—for a second opinion, or to run a coding task in parallel. Manually doing this involves spawning a codex process yourself, capturing JSONL output, polling the status, and then feeding the results back into the session. This scaffolding code is irrelevant to the main task, yet it must be written every time.

dsh-codex-bridge is designed to solve this problem. The DSH philosophy is that “everything is a plugin,” and capabilities are mounted as plugins into the harness; this project is a concrete implementation of this approach. Below is an introduction to what it is, how to install it, the tools it provides, and its limitations.

What is it

dsh-codex-bridge is a two-sided (host + browser) plugin maintained by pandashere that integrates Codex CLI into DeepSeek Harness under the MIT license. The term “two-sided” means: the host side exposes a set of tools to the agent, while the browser side provides visualization within a Web session pane. To the agent, Codex becomes a tool that can be called directly; to the user, the entire process of each Codex session is observable on the web page.

Core Features

call_codex: Invoke Codex as a Tool

Starts Codex in the dsh session’s working directory (underlying command: codex -a never exec --json), supporting two modes:

  • async: Returns immediately; multiple calls can run in parallel.
  • block: Waits for the final answer.

Parameters are { prompt, mode?: async|block, sandbox?: read-only|workspace-write, model?, timeout_ms?, codex_session_id? }.

codex_status and codex_abort

codex_status lists the current codex sessions for the dsh session, including status, prompt preview, and progress. It is suitable for polling after starting in async mode.

codex_abort terminates a codex process group by codex_session_id: it first sends SIGTERM, and if that exceeds killGraceMs (default 2000ms), it sends SIGKILL.

codex_steer: Resume on the Same Thread

codex_steer is used to continue an ended (settled) Codex session on the same thread. Under the hood, it uses codex exec resume <thread_id>, and new records trace back to the original session via the parent chain. Parameters are { codex_session_id, prompt, mode?: async|block, model?, timeout_ms? }. Typical use cases involve asking follow-up questions or adjusting direction based on an existing session.

Web-side Codex Tab

The browser side provides a Codex Tab (parallel to Chat / Trajectory) in the Web session pane, displaying: status, prompt, Agent Loop waterfall chart (messages, tool calls with commands and parameters, collapsible tool outputs and exit codes, round separators), transcript, and final answer.

Status is pushed in real-time via session projection channels (codex/session events, codex/sessions projection). After a page refresh, history can be restored via playback. The browser side is provided by /plugins/dsh-codex-bridge/client.js and follows the __ModuleLoader__.load({id, factory}) protocol.

Installation and Enablement

Running requirements:

  • Node.js 22 or later;
  • @deepseek-ai/dsh@0.1.0-rc.6;
  • An authenticated and available Codex CLI (executable name codex, or specify the path via codexPath).

The plugin does not read or store API keys; authentication is handled by the Codex CLI itself.

First, build and pack the plugin in the plugin directory to generate a standalone bundle:

npm install
npm run check
npm pack

Then install the generated tarball to the DSH profile, and start dsh web with a restart:

npx @deepseek-ai/dsh@0.1.0-rc.6 plugin --profile web add ./dsh-codex-bridge-0.1.0.tgz
npx @deepseek-ai/dsh@0.1.0-rc.6 web

Note: Installing the source code directory via a link is not supported (host peers are provided by the DSH profile); you must install the packed tarball and restart.

Verify that the browser side is in place (when the default Web profile runs on local port 3080):

curl -s http://127.0.0.1:3080/plugins/dsh-codex-bridge/client.js | head

For updates, repack the tarball with the new package version, remove the installed bundle first, then add the new tarball and restart. The uninstall command:

npx @deepseek-ai/dsh@0.1.0-rc.6 plugin --profile web remove dsh-codex-bridge

Configuration Options

The configuration options and default values given in the README are as follows:

Configuration Default Value Meaning
codexPath codex codex executable file (absolute path or PATH lookup)
defaultSandbox read-only codex’s own shell command sandbox strategy (can be increased for deployment)
defaultTimeoutMs 0 lifecycle cap for a single codex session (0 = unlimited)
maxParallel 3 global limit for concurrent codex processes
maxSessionsPerSession 8 active codex session limit within each dsh session
maxRetained 16 number of ended records retained per dsh session (evicts the oldest)
maxPromptChars 16384 prompt length limit (rejects if exceeded)
maxTranscriptChars 16384 transcript limit in events/projections
maxLoopSteps 32 step limit for the agent-loop window
maxLoopBytes 16384 serialized byte limit for the loop window (UTF-8, evicts the oldest completed steps)
allowedAgents roots who can call call_codex: roots or all
killGraceMs 2000 grace period for abort when SIGTERM → SIGKILL

Design Stance and Resource Limits

The README clearly defines the design stance: this is a UX channel, not a security boundary. Codex runs with the calling user’s permissions, under its own sandbox strategy—read-only and workspace-write are provided to the model, danger-full-access is restricted to deployment configuration.

The calling surface visible to the model is deliberately tightened:

  • Codex always runs in the session working directory and never uses the host’s cwd (fail closed);
  • By default, only the top-level agent can call it (allowedAgents: roots, can be changed to all);
  • Resource usage and write amplification are limited via maxParallel, maxSessionsPerSession, maxLoopSteps, and maxLoopBytes.

Known Limitations

Several points worth knowing before use, listed from the README:

  • Each call executes once; continuation relies on codex_steer. The standard CLI does not support real-time interjection during execution; that would require the experimental codex app-server / remote-control path.
  • The loop window is recent activity, not an audit log. Old steps are physically evicted under maxLoopSteps / maxLoopBytes; dsh session logs still retain full snapshots, but the tab only displays the retained window.
  • The sandbox belongs to Codex itself. defaultSandbox maps to codex -s, which constrains what Codex’s shell commands can touch, not the harness’s security boundary.
  • Process group termination is POSIX-only. Windows porting would require Job Objects or taskkill /T tree termination.
  • Telemetry desensitization only covers dsh exports; Codex’s own telemetry is out of scope.

Use Cases and Notes

Who it’s for: Developers doing agent development on dsh who want to use Codex as a second opinion or a parallel coding channel without having to write process management scaffolding everywhere. Typical usage involves starting parallel tasks in async mode, polling progress with codex_status, and using codex_steer for follow-up questions after completion, with the entire process observable in the Codex tab on the web side.

Pre-installation note: The plugin runs with the permissions of the current dsh process. It is recommended to read the source code before installing to the profile to confirm the license (this project is MIT) fits your usage scenario.

Conclusion

dsh-codex-bridge turns “invoking an external coding agent” from manual scaffolding into a controlled tool invocation plus an observable tab, significantly reducing the cost of integration and the surface area for errors. Project addresses: