Foreword

When building agent workflows with dsh (DeepSeek Harness), a common need arises: the main agent wants to consult an external coding agent for a second opinion or parallelize a coding task. If using Kimi CLI manually, you’d have to spawn kimi -p, capture the output stream, poll for status, and feed the result back into the dsh session. This scaffolding code is repetitive and error-prone—exactly the kind of thing a harness plugin should handle for you.

The dsh-kimi-bridge introduced below does exactly this: turns the Kimi CLI into a tool directly callable within dsh and provides a corresponding observation interface in the WebUI.

What is it

Maintained by pandashere, licensed under MIT, and currently at version 0.1.0. In a nutshell: this is a host + browser dual-sided DeepSeek Harness plugin that bridges the Kimi CLI (kimi-code) into the harness. It is the Kimi counterpart to dsh-codex-bridge, sharing the same architecture.

“Dual-sided” refers to the plugin covering both ends: the host side registers tools with dsh, while the browser side provides the interface via /plugins/dsh-kimi-bridge/client.js. DSH’s philosophy is “everything is a plugin”; the capabilities of external CLIs are integrated into sessions through this mechanism.

Four Tools

call_kimi

call_kimi runs kimi -p <prompt> --output-format stream-json in the current session’s working directory and supports two modes:

  • async: Returns immediately; multiple calls can run in parallel.
  • block: Waits for the final answer; when a kimi_session_id is provided, it waits for a previously started session. Cancelling the blocking wait will terminate the corresponding kimi session.

Parameter structure:

call_kimi: { prompt, mode?: async|block, model?, timeout_ms?, kimi_session_id? }

Each call_kimi runs a fresh kimi -p. The CLI itself does not support real-time steering during execution; the thinking process of kimi-code is not written to stream-json, and the plugin does not infer reasoning content from stderr.

kimi_status 与 kimi_abort

kimi_status lists all kimi sessions for the current dsh session, including status, prompt preview, and progress. kimi_abort accepts { kimi_session_id }, sends a SIGTERM to the process group first, and upgrades to SIGKILL after killGraceMs.

kimi_steer

kimi_steer continues a finished (settled) parent session using kimi -S <session_id> -p ...:

kimi_steer: { kimi_session_id, prompt, mode?: async|block, model?, timeout_ms? }

New records are linked back to the parent session via parent and inherit the parent’s model. Kimi sessions are bound to a working directory: the plugin locks cwd to the session’s working directory to ensure continuation happens in the same directory. Sessions are linear—the parent record must be the latest record, and a session can only have one active continuation at a time.

WebUI: Kimi Tab

The plugin registers a Kimi tab in the session panel, located after Codex.

The left column lists all kimi sessions for the current dsh session, featuring status dots, prompt previews, and relative time; click to select. The right column displays status badges, meta (id/kimiId/cwd/model/duration/exit/error), prompt, and two views: Activity | Text:

  • Activity: An Agent Loop waterfall chart, containing messages, tool rows with parameters, collapsible tool outputs, and turn separators.
  • Text: Streamed transcript and the final answer.

Status changes are pushed in real-time via the session projection channel (kimi/session events, kimi/sessions projection), and the tab updates immediately; after a page refresh, it restores via historical replay.

reviewOnly: Default Read-Only Whitelist

First, clarify the design stance: this is a UX channel, not a security boundary. kimi -p runs internally with permission:"auto", and the CLI has no sandbox flags available.

Therefore, the plugin defaults to reviewOnly: true: kimi runs under a managed home, and its [tools] whitelist contains only read-only tools—Read, ReadMediaFile, Grep, Glob—with no Bash/Write/Edit/MCP—and is enforced again before tool execution. Changing it to false means switching to the user’s unrestricted home, which is an explicit operational choice and should not be called a sandbox. reviewOnly is a tool whitelist, not a sandbox; true sandboxed workspace-write requires OS-level isolation (container/namespace).

Regarding credentials: the plugin does not copy credentials into the repository or dsh telemetry. In reviewOnly mode, the managed Kimi home points to the CLI’s existing authentication files via symbolic links, and the CLI remains the owner of the credentials. Kimi’s own telemetry is disabled via the subprocess environment variable KIMI_DISABLE_TELEMETRY=1.

Installation and Enablement

First, confirm the environment: Node.js 22 or later (engines: node >=22), @deepseek-ai/dsh@0.1.0-rc.6, and a fully authenticated and available kimi CLI (or set kimiPath in the config).

Step 1: Build, validate, and package in the plugin directory:

npm install
npm run check   # typecheck + tests + compliance
npm pack

npm run check runs type checking, tests, and compliance checks in sequence; npm pack generates the tarball dsh-kimi-bridge-0.1.0.tgz for the standalone bundle. If you modify the source code, npm run build compiles the host side with tsc and bundles the browser side with esbuild.

Step 2: Install the tarball into the web profile and restart dsh web:

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

Step 3: Verify the browser side is in place. The browser-side code is provided by /plugins/dsh-kimi-bridge/client.js and can be checked against the running default Web profile:

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

After the steps above, the Kimi tab should appear in the session panel. Note that installation via source directory link is not supported because the host-side peer dependencies are provided by the DSH profile. For updates, repackage with a new package version, remove the installed bundle, add the new tarball, and restart. The uninstall command is:

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

Configuration Options

The README explicitly lists the following configuration options and default values:

Config Option Default Value Meaning
kimiPath kimi kimi executable file (absolute path or PATH lookup)
reviewOnly true run kimi under a managed home where the [tools] whitelist is read-only
kimiHome '' source home for config and auth ('' = KIMI_CODE_HOME, otherwise ~/.kimi-code)
reviewHomeDir '' managed review home ('' = $DSH_HOME/kimi-review-home)
maxTimeoutMs 1800000 hard upper limit for any session timeout (30 minutes)
defaultTimeoutMs 600000 default lifetime per kimi session (10 minutes)
maxParallel 3 global upper limit on concurrent kimi processes
maxSessionsPerSession 8 active kimi session limit per dsh session
maxRetained 16 number of finished records retained per dsh session (FIFO)
maxPromptChars 16384 prompt length upper limit (argv prompt; rejects NUL, rejects very long prompts)
maxTranscriptChars 16384 transcript upper limit recorded in events and projections
maxLoopSteps 32 number of steps kept in the Agent Loop window
maxLoopBytes 16384 serialized byte limit of the Loop window (UTF-8, evicts oldest finished steps)
allowedAgents roots who can call call_kimi: roots or all
killGraceMs 10000 grace period from SIGTERM to SIGKILL

Two timeout items deserve separate explanation: Kimi’s print mode can experience long waits, so the plugin uses defaultTimeoutMs (default 10 minutes) to constrain the default lifetime of a single session, and maxTimeoutMs (default 30 minutes) as the hard upper limit for any session. allowedAgents, maxParallel, and maxSessionsPerSession are used to constrain resource amplification.

Known Limitations

  • The Agent Loop window is recent activity, not an audit record: when exceeding maxLoopSteps (32) / maxLoopBytes (16384), old steps are physically evicted; the tab only displays the retained window (the dsh session log itself still retains a full snapshot).
  • reviewOnly is a tool whitelist, not a sandbox; true sandboxed workspace-write requires OS-level isolation.
  • Only supports POSIX process groups (detached + negative pid kill); Windows port requires Job Object / taskkill /T tree termination.

Use Cases and Notes

Suitable scenarios are specific: you want the dsh main agent to use Kimi as a second opinion or a parallel coding channel; or you are already using dsh-codex-bridge and want to integrate Kimi with the same architecture.

A few notes:

  1. The plugin runs with the permissions of the current dsh process. Before installing any third-party plugin, you should check the source code and license—this project is MIT.
  2. Environment requirements: Node.js 22 or later, @deepseek-ai/dsh@0.1.0-rc.6, and a fully authenticated and available kimi CLI (otherwise set kimiPath).
  3. reviewOnly defaults to true and is a tool whitelist, not a sandbox; changing it to false for greater freedom is an explicit operational choice.

Summary

Returning to the original problem: enabling dsh agents to use Kimi previously required a set of manual scaffolding for spawning, capturing streams, polling, and backfilling; dsh-kimi-bridge condenses this into four tools plus a tab—calls can be async and parallel, sessions can be continued, the Agent Loop can be observed, and a default read-only whitelist provides a safety net. Source code and documentation are available on GitHub: https://github.com/pandashere/dsh-kimi-bridge, license MIT. The community DSH plugin directory (independent site, no official affiliation with DeepSeek or High-Flyer) can also be searched by plugin name.