편집자 노트

Kimi 桥接插件

A dual-face (host + browser) plugin for DeepSeek Harness (dsh) that bridges the Kimi CLI (kimi-code) into the harness — the Kimi counterpart of dsh-codex-bridge, built on the same architecture.

이것은 DeepSeek Harness(DSH) 플러그인입니다. 이 사이트는 GitHub README, 설치 정보, 유지보수 상태, 공개 보안 시그널을 모아 보여줍니다.

업스트림에서 중국어 README를 제공하지 않아 저장소 원본 내용을 표시합니다.

dsh-kimi-bridge

English | 中文

A dual-face (host + browser) plugin for DeepSeek Harness (dsh) that bridges the Kimi CLI (kimi-code) into the harness — the Kimi counterpart of dsh-codex-bridge, built on the same architecture.

Why

A dsh agent often wants a second opinion or a parallel coding pass from an external coding agent (Moonshot Kimi). Doing that by hand — spawning kimi -p, capturing the stream, polling, wiring the output back — is exactly the kind of scaffolding a harness plugin exists to remove. This plugin makes Kimi a first-class dsh citizen:

  1. Calls Kimi as a toolcall_kimi runs kimi -p <prompt> --output-format stream-json in the session's working directory, with async (returns immediately; multiple calls run in parallel) and block (waits for the final answer) modes, plus kimi_status to poll and kimi_abort to cancel.
  2. Continues the same sessionkimi_steer resumes a settled Kimi session with a new message (kimi -S <session_id> -p …). Kimi sessions are bound to their working directory — the plugin locks cwd to the session working directory, so resume inside one dsh session holds. The session is linear: the parent must be the latest record, and one session can have only one active continuation.
  3. Shows the whole agent loop — the Kimi tab in the conversation pane (on par with Chat, Trajectory, and Codex) observes each session live: status, prompt, an Agent Loop waterfall (messages, tool rows with arguments, collapsible tool output, turn separators), the transcript, and the final answer — pushed through the session projection channel.

Design stance: this is a UX channel, not a security boundary — and kimi -p runs with permission:"auto" internally, so there is no CLI sandbox flag. The default reviewOnly mode therefore runs Kimi under a managed home whose [tools] allowlist is read-only (Read/ReadMediaFile/Grep/Glob; no Bash/Write/Edit/MCP), enforced again before tool execution. Setting reviewOnly: false opts into the user's unrestricted home — an explicit operator choice, never called a sandbox. allowedAgents, maxParallel, and maxSessionsPerSession bound resource amplification, and a finite defaultTimeoutMs bounds Kimi's print mode (which can otherwise wait ~25 days on background work).

Installation

Requirements: Node.js 22 or newer, @deepseek-ai/dsh@0.1.0-rc.6, and an authenticated Kimi CLI available as kimi (or set kimiPath). The plugin does not copy credentials into the repository or dsh telemetry. In reviewOnly mode, the managed Kimi home symlinks the CLI's existing auth files so the CLI remains the credential owner.

Build, validate, and pack the standalone bundle from the plugin directory:

npm install
npm run check
npm pack

Install the generated tarball into a DSH profile, then restart dsh web. Installing the source directory as a link is not supported because host peers are supplied by the DSH profile:

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

The browser half is served at /plugins/dsh-kimi-bridge/client.js and appears in the conversation pane. Verify it against a running default Web profile:

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

To update, build a tarball with a newer package version, remove the installed bundle, add the new tarball, and restart. To uninstall:

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

Config

KeyDefaultMeaning
kimiPathkimikimi executable (absolute path or PATH lookup)
reviewOnlytruerun kimi under a managed home whose [tools] allowlist is read-only
kimiHome''source Kimi home for config/auth ('' = KIMI_CODE_HOME, else ~/.kimi-code)
reviewHomeDir''managed review home ('' = $DSH_HOME/kimi-review-home)
maxTimeoutMs1800000hard cap on any session timeout (30 min)
defaultTimeoutMs600000default lifetime per kimi session (10 min)
maxParallel3global cap on concurrent kimi processes
maxSessionsPerSession8cap on live kimi sessions per dsh session
maxRetained16retained (settled) records per dsh session (oldest evicted)
maxPromptChars16384prompt length cap (argv prompt; NUL rejected; longer prompts are rejected)
maxTranscriptChars16384transcript cap recorded in events/projections
maxLoopSteps32bounded agent-loop window (steps kept in the record/projection)
maxLoopBytes16384serialized-byte cap for the loop window (UTF-8; oldest completed steps evicted)
allowedAgentsrootswho may call call_kimi: roots | all
killGraceMs10000SIGTERM → SIGKILL grace (kimi headless cleanup takes up to 8s)

Tools

  • call_kimi{ prompt, mode?: async|block, model?, timeout_ms?, kimi_session_id? }. async starts and returns immediately (parallel); block waits for the answer (or, with kimi_session_id, waits on a previously started session). A cancelled blocking wait aborts the kimi session.
  • kimi_status — list the current session's kimi sessions (status, prompt preview, progress).
  • kimi_abort{ kimi_session_id }; SIGTERM the process group, then SIGKILL after killGraceMs.
  • kimi_steer{ kimi_session_id, prompt, mode?: async|block, model?, timeout_ms? }. Continue a settled parent session (kimi -S <session_id> -p …; must run from the same directory, which the plugin guarantees); the new record links back via parent and inherits the parent's model. A post-restart parent works as long as its record carries the kimi session id.

Model Experience

The Kimi tab (conversation pane, after Codex):

  • Left column — every kimi session of the current dsh session, with status dot, prompt preview, and relative time. Click to select.
  • Right column — status badge, meta (id/kimiId/cwd/model/duration/exit/ error), the prompt, and an Activity | Text toggle:
    • Activity — the Agent Loop waterfall: messages, tool rows (tool name, running/done/failed, duration, exit code, truncated marker; output auto-expands on failure), turn separators, and a "N steps dropped" marker when the bounded window evicted older steps.
    • Text — the streamed transcript and the final answer.

State changes ride the session projection channel (kimi/session events, kimi/sessions projection), so the tab updates live and survives page refresh (history replay).

Known Limitations and Deferred Work

  • One shot per call, then continuation. call_kimi runs a fresh kimi -p; live mid-run steering is not available in the CLI (kimi-code's thinking is not written to stream-json either, so the tab never guesses reasoning from stderr).
  • The loop window is recent-activity, not an audit trail. Older steps are physically evicted under maxLoopSteps/maxLoopBytes; the canonical dsh session log still holds the whole-value snapshots, but the tab only shows the retained window.
  • reviewOnly is a tool allowlist, not a sandbox. It is enforced by the kimi [tools] switch before execution; a genuinely sandboxed workspace-write needs OS-level isolation (container/namespace).
  • POSIX-only process groups. Abort uses detached + negative-pid kill; a Windows port needs Job Object / taskkill /T tree termination.
  • Telemetry redaction covers dsh exports only. Kimi's own telemetry is disabled via KIMI_DISABLE_TELEMETRY=1 on the child.

Development

npm run check    # typecheck + tests + compliance
npm run build    # host (tsc) + client bundle (esbuild, __ModuleLoader__ ABI)

The client bundle speaks the harness __ModuleLoader__.load({id, factory}) protocol with the platform module table as externals; the host half follows the bundle format from create-dsh-plugin.

License

MIT

REPOSITORY SIGNALS

보안 및 설치 증거

이 점수는 공개 저장소 메타데이터와 이 사이트에 등록된 설치 증거에만 기반하며, 코드 보안 감사와 다릅니다.

출처 추적 가능

공개 플러그인 카탈로그에서 왔으며, 공개 GitHub 저장소로 연결됩니다.

라이선스

저장소가 MIT 라이선스를 선언했습니다.

유지보수 활동

최근 180일 내 코드 업데이트가 있습니다.

설치 증거

재현 가능한 정확한 설치 메타데이터가 아직 등록되지 않았습니다. 저장소 설명에 따라 직접 확인하세요.

설치 라이프사이클 스크립트

검사한 패키지 메타데이터에 설치 라이프사이클 스크립트가 선언되지 않았습니다.