DeepSeek Harness Bluebook
User Guide

Migrating from Codex / Claude Code

Three migration paths: model-level compatibility (Responses API), reusing existing hooks.json (hook bridges), and native Cordis plugins

If you currently use OpenAI Codex or Anthropic Claude Code, DeepSeek Harness offers three gradual migration paths. This page is compiled from the upstream hooks subsystem documentation and the official DeepSeek API announcement.

First: decide whether to migrate at all

The harness is still in the developer preview stage, while Codex and Claude Code are mature products. If your current tool already fits, there is no need to switch just because DeepSeek's official benchmarks use the harness — those scores are system scores of "model + harness + configuration + tool environment", see benchmark interpretation.

The three paths can be combined as needed:

PathApproachBest for
1. Model-level compatibilityKeep Codex, point the model at the DeepSeek APIUsing DeepSeek V4 first without switching tools
2. Hook bridgesMove to dsh, reuse your existing hooks.jsonTeams with established hook workflows that want a smooth switch
3. Native pluginsRewrite custom logic as Cordis plugins on extension pointsLong-term investment needing typed returns and stronger capabilities

Path 1: model-level compatibility

The DeepSeek API natively supports the OpenAI Responses API format, adapted for Codex; the official docs provide a one-click configuration script to wire Codex up (see the DeepSeek API announcement). For model setup details, see configure models.

Nearly zero cost

No workflow or editor changes — just swap the model endpoint — and you can compare DeepSeek models on your own tasks. This is also the fastest way to evaluate "model vs tool" contributions.

Path 2: hook bridges

The harness's hooks subsystem lets you point existing Claude Code / Codex hook configurations at bridge plugins, so those external shell hooks keep running on the harness's typed interception points. Both bridges are Cordis plugins:

Claude Code bridge (dsh-hooks-claude-code)

Reads a Claude Code hooks.json (or a settings file's hooks key). The mapped hook points:

Claude Code hookBehavior
SessionStartadditionalContext injected into the new session (cannot block)
UserPromptSubmitdeny → reject the step; additionalContext → appended context
PreToolUsedeny → deny the tool call; ask → convert to an approval request
PostToolUsedeny → block with feedback; additionalContext → prepended context
Stopblock Stop and steer the reason back, forcing the agent to run one more step
SubagentStart / SubagentStopinject context / observe only

Enable it in cordis.yml:

- dsh-hooks-claude-code:
    configPath: ./.claude/hooks.json
    pluginRoot: ./.claude/plugins/my-plugin
    projectDir: .
  • configPath: required; a process-level config, parsed once at load.
  • pluginRoot: replaces ${CLAUDE_PLUGIN_ROOT} in command strings.
  • projectDir: replaces ${CLAUDE_PROJECT_DIR} and sets the hook env var; defaults to the session cwd.
  • Only type: 'command' hooks run; http / mcp_tool / prompt / agent are parsed and skipped (with a warning).
  • Hook processes run in the session workspace directory; multiple hooks on one point run serially in config order, with decisions folded by strictness (deny > ask > allow).

Codex bridge (dsh-hooks-codex)

Reads a Codex hook configuration, implementing 5 of its 10 hook points: PreToolUse, PostToolUse, SessionStart, UserPromptSubmit, Stop.

- dsh-hooks-codex:
    configPath: ./.codex/hooks.json
    model: deepseek-v4
  • Matchers are always interpreted as regular expressions; the stdin payload is snake_case with extra turn_id and model fields.
  • No Codex plugin env injection and no config-time placeholder substitution.
  • No tool pre-approval or rewrite paths: hooks can block, but never pre-approve or replace tool input.
  • Only synchronous type: 'command' hooks run; async: true hooks are skipped (with a warning).

Bridge boundaries

Bridges are compatibility paths, not the full capability

Both bridges cover only a deliberate subset of their protocols. Parse failures are isolated (a warning, and nothing is registered) so a typo never stops the agent; but native Cordis plugins can do everything a bridge does, with typed returns and no serialization boundary. All deep customization should move to native plugins (see the developer guide).

Path 3: native Cordis plugins

Underneath, the bridges sit on the harness's typed interception points (agent/pre-step, tools/pre-execute, tools/post-execute, etc. — see Host Services & Events). A "native hook" is just an ordinary Cordis plugin mounted on those same points: the bridges translate the external shell-hook protocol onto them, and your own plugins can consume them directly.

Concept mapping

Codex / Claude CodeDeepSeek Harness
hooks.json (shell hooks)cordis.yml plugins (or hook bridges as a compatibility layer)
PreToolUse deny / asktools/pre-execute waterfall decisions (deny / ask)
${CLAUDE_PLUGIN_ROOT}the bridge's pluginRoot config
Product-built approvalsBuilt-in permission presets and approval policy
Terminal CLIWeb GUI / headless / CLI entry modes

Suggested route

  • Get model-level compatibility working first (path 1) and A/B on your own task set;
  • Add the bridges when you need your hook workflows (path 2), gradually rewriting high-frequency hooks as native plugins (path 3);
  • Keep the old tool as a fallback during migration — run both in parallel until you are ready to switch.

On this page