DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

Codex Bridge — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
C

dsh-codex-bridge

Codex Bridge

Observe and steer a local Codex (OpenAI) session from DeepSeek Harness, over the codex app-server protocol.

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:JUYANJY/dsh-codex-bridge#eb4c5278183ab8bb1d056a2ad27d6f6c5b50d481
READMECompatibilityVersions

Compatibility and provenance

Codex Bridge is published as dsh-codex-bridge and currently resolves to version 0.1.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
10/10/2026

Versions

0.1.0stable
10/10/2026

Related plugins

Loading related plugins…

Latest
0.1.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 1
Weekly downloads
0
Last push
10/16/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in developer-tools.

Web App@deepseek-ai/dsh-web-appThe dsh browser-surface bundle: the web patch layer over dsh-base plus the runtime glue plugin (frontend dist serving, web-surface prompt, bash runtime variables, URL line)Sdk Minimal@deepseek-ai/dsh-sdk-minimalThe standalone minimal SDK profile bundle: JSON-RPC, one DeepSeek adapter, persistent shell, and JSONL sessionsSdk App@deepseek-ai/dsh-sdk-appThe dsh SDK profile bundle: stdio JSON-RPC serving and process lifecycle over dsh-baseExperimental Inspector@deepseek-ai/dsh-experimental-inspectorExperimental cross-realm CDP hub for Host debugging and Client Runtime inspection

README

dsh-codex-bridge

Observe and steer a local Codex (OpenAI) session from DeepSeek Harness.

The plugin talks to codex app-server — the same protocol the Codex app itself uses — which is what makes the live parts possible at all:

Reading the rollout .jsonlThis plugin
Transcriptafter it is writtenlive deltas, plus polls
Reasoningonly what was flushedsummary deltas as they stream
Rate-limit budgetnot presentaccount/rateLimits/read
Send a messagenot possiblequeue (the only cross-process path)
Answer an approvalnot possibleonly for turns this bridge started

It was built as a DSH counterpart to a Codex session running in the Codex desktop app: read what that session is doing, hand it the next instruction, and know exactly which parts are impossible rather than guessing.

Tools

ToolWhat it does
codex_statusAccount, plan, rate-limit budget, local processes, latest thread, pending approvals. Degrades to a readable message when Codex is not reachable instead of throwing.
codex_threadsRecent threads, optionally filtered by a search string.
codex_transcriptItems of one thread, newest first.
codex_watchWatches a thread for N seconds and returns what streamed past, merging the live notification stream with transcript polls and labelling each event's source.
codex_sendqueue (default), turn, or steer. Falls back to the queue when the desktop app holds the thread's write lock.
codex_approvalsLists pending approval requests and answers them.
codex_queueShows the messages still waiting on a thread (action=list), and cancels one with action=delete. Reports what the app-server confirmed, since a live session usually consumes a queued message first.

Board

The same projection is also a panel inside Harness: a sidebar row named Codex opens a board whose columns are waiting for approval, turn observed here, queued messages and no observed activity.

It is deliberately read-only. The panel polls one host route (a single snapshot endpoint) and holds no path to codex_send or codex_approvals at all: a board that could decline an approval by accident would be worse than no board.

Four rules keep it honest, and they are why the columns are named the way they are:

  • A thread waiting on an approval is never filed under Queue, even when it also has queued messages.
  • Running means this bridge's connection saw turn/started and has not seen it finish — a statement about the connection, not about the machine. So the last column is no observed activity, never "idle": silence from a connection-scoped protocol is not proof that nothing is happening.
  • Every card carries a last line: the newest item the rollout reports that is not encrypted reasoning (reasoning items trail almost every turn and their text is sealed), with that item's own status printed verbatim — inProgress, failed, whatever the protocol said. It reports what the thread last did; it is not a claim that a turn is running.
  • Queue and last-action inspection are sampled (a bounded number of threads per refresh, reported in the snapshot's probe block), and the board says so rather than presenting a partial read as a total.

The client half is plain JS loaded by the web client — no build step, like the shipped client plugins. It shows up after a Harness restart.

What you cannot do, and why

Four of these are structural, not missing features — full evidence in docs/limitations.md:

  1. The desktop app holds an exclusive write lock on every thread it has opened, even while idle. So turn/steer are unavailable for those threads and queue is the only write path.
  2. Approvals go to the client that owns the turn. For a turn the Codex app is running, codex_approvals sees nothing and cannot answer for it. Approving the app's turns from here is impossible over this protocol.
  3. Live deltas go only to the owning connection. Watching a desktop-owned thread works, but through polling, so it is up to ~1.2s behind and arrives as source: "transcript".
  4. Reasoning bodies are encrypted. You get the emitted summary — rendered as (reasoning not exposed: encrypted) when there is none — not the hidden chain of thought.

Also: codex_send is a real write. A queued message is picked up promptly — in testing, almost immediately — so queueing is sending, not drafting. codex_queue action=delete can cancel an entry that is still waiting, but that is a race rather than an undo: the tool reports the app-server's own answer instead of assuming the message never went out.

Install

The plugin is loaded by name, so the profile needs two symlinks. The script creates them, moves any existing vendored copy aside (never deletes it), and records what it did so the change is reversible:

node scripts/install.mjs --dry-run     # show the plan
node scripts/install.mjs               # apply it
node scripts/install.mjs --write-config # also append the loader entry if missing

It targets ~/.dsh/profiles/desktop by default; override with --profile <dir> or DSH_PROFILE_DIR.

Then restart DeepSeek Harness. This is not optional: patchReload: live re-reads config, not module code, so a running Harness keeps the module it already imported (see limitation 6).

To undo:

node scripts/uninstall.mjs --dry-run
node scripts/uninstall.mjs

The loader entry in the profile's cordis.patch.yml is hand-maintained config and is never edited silently — install.mjs prints the exact YAML to paste when it is missing, and uninstall.mjs tells you which block to remove.

Configuration

- insert:
    - id: dsh-codex-bridge
      name: dsh-codex-bridge
      config:
        binary: ""            # explicit path to `codex`; empty = auto-detect
        requestTimeoutMs: 30000

Binary resolution order:

  1. explicit binary
  2. $DSH_CODEX_BIN
  3. /Applications/ChatGPT.app/Contents/Resources/codex
  4. /opt/homebrew/bin/codex
  5. /usr/local/bin/codex
  6. /usr/bin/codex
  7. bare codex (resolved on PATH)

Development

npm test            # 68 unit tests, no Codex install required
node scripts/smoke.mjs   # live handshake against the real app-server

tests/helpers/fake-codex.js is a real codex app-server stand-in: it speaks the protocol over stdio in a child process, so the transport, framing, correlation and timeout paths are exercised for real rather than mocked. Its behaviour is driven by environment variables:

  • FAKE_CODEX_LOCK=1 — thread/resume and turn/steer answer with the active-writer error, which is what a desktop-owned thread does.
  • FAKE_CODEX_SILENT=1 — never answers, for the timeout path.

The smoke script is the only test that needs Codex installed, and it writes to no thread.

Layout

src/index.js          cordis entrypoint: name/inject/Config/apply
src/bridge.js         one shared app-server connection, lazily started
src/app-server.js     spawn, JSONL framing, request correlation, inbound requests
src/codex.js          protocol payloads -> compact records
src/notifications.js  which notification methods matter, and how to describe them
src/errors.js         the active-writer error and the explanation shown to users
src/board.js          the read-only projection the tools and the board share
src/board-channel.js  the host route the panel polls (one POST endpoint)
src/client.js         the panel itself; loaded by the web client, never by Node
src/tools/*.js        one factory per tool

Requirements

  • Node >= 22 (uses node:test, ESM, randomUUID)
  • A Codex install for anything live; the unit tests need none

License

MIT — see LICENSE.