DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Crew — DeepSeek Harness 插件(DSH Plugin)
← Plugins

@dshworks/dsh-crew

Crew

在 dsh 旁以实时终端窗格运行 Claude Code 和 Codex:在 Web 界面中进行分屏,提供用于放置它们的按钮,以及让 dsh 代理向它们分配工作并读取其屏幕的工具。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add @dshworks/dsh-crew@0.2.2
README兼容性版本

兼容性与来源证明

Crew 以 @dshworks/dsh-crew 发布,当前版本为 0.2.2。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
npm
Registry 更新时间
2026/9/20

版本

0.2.2stable
2026/9/18
0.2.1stable
2026/9/4
0.2.0stable
2026/8/20
查看其余 1 个版本
收起版本
0.1.0stable
2026/8/17

相关插件

正在加载相关插件…

最新版
0.2.2
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
491.2 kB
文件数
21
Surface
web
许可证
MIT
发布源
npm
GitHub
★ 1
周下载
222
安全扫描
✓ v0.2.2 扫描通过
最近提交
2026/9/18
查看源码 ↗项目主页 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录

相关插件

继续浏览 developer-tools 分类下经过校验的插件。

Web App@deepseek-ai/dsh-web-appdsh 浏览器界面捆绑包:位于 dsh-base 之上的 Web 补丁层,加上运行时粘合插件(提供前端 dist、Web 界面提示符、bash 运行时变量和 URL 行)Sdk Minimal@deepseek-ai/dsh-sdk-minimal独立的最小 SDK 配置包:JSON-RPC、一个 DeepSeek 适配器、持久化 Shell 和 JSONL 会话Sdk App@deepseek-ai/dsh-sdk-appdsh SDK 配置包:基于 dsh-base 提供 stdio JSON-RPC 服务和进程生命周期管理Subagent Codex@deepseek-ai/dsh-subagent-codex基于官方 app-server 协议的一次性 Codex 子代理提供程序

README

dsh-crew

English | 中文

Claude Code and Codex, running as live terminals beside dsh. You watch them work. You can take the keyboard.

dsh can already delegate to them — subagent-claude-code and subagent-codex start the product, hand it one task, and return its final sentence. What they deliberately do not do is let you watch: no progress stream, no human interaction path, and the model-facing terminal tool documents "no TUI".

0.1.0-rc.8 made those two installable on demand as Profile Bundles, gave Codex named instances, and added non-interactive permission modes — which sharpens the split rather than closing it. Read the rc.8 provider notes: every query still "never waits for a user interface", AskUserQuestion is still disabled, and outside bypass mode canUseTool now denies anything needing a human on the spot. Upstream is making unattended delegation better on purpose. This plugin is for the other half: when you want to see it happen and be able to answer.

dsh-crew adds the missing half. Each crew member gets a real PTY running its own CLI in the session's workspace, streamed to a pane in the Web UI. The agent in the center column seats them and hands them work; you see every keystroke of it, and you can type into any pane at any moment.

The dsh Web UI with a Crew tab open beside Chat and Trajectory: a seat bar offering Claude Code, Codex, and dsh, and a real Claude Code terminal UI running in a pane in the session's workspace

Install

dsh plugin --profile web add @dshworks/dsh-crew
dsh --profile web

dsh plugin forwards to pnpm, so pnpm must be on PATH. A Crew tab appears beside Chat and Trajectory in the next session.

Nothing else to configure. The seat bar shows every crew member it can find, and disables the ones it cannot — with the reason on the button, so a missing codex reads as codex is not on the host PATH rather than a launch that fails a second later.

The two halves

The human half is the split view: a seat bar, and one pane per seated agent. The pane is a real terminal — colour, cursor addressing, the product's own TUI — because the plugin carries the CLI's bytes rather than reimplementing its surface. Type into it whenever you want; interrupt it with Ctrl-C; or use the broadcast line to put one message into every live pane at once and watch two agents answer the same question side by side.

The agent half is five tools, so the model in the center column can run the team:

crew_list                              → who can be seated, who already is
crew_seat(agent: "claude")             → starts a pane, returns its id + first screen
crew_send(pane: "…", message: "…")     → types it, presses Enter, waits for quiet
crew_send(…, run_in_background: true)  → returns a job id; the answer arrives as a notice
crew_peek(pane: "…")                   → the screen right now, as the human sees it
crew_dismiss(pane: "…")                → ends the process

That shared surface is the point. The delegation and the observation are the same terminal — the agent's crew_send and your eyes are looking at one screen, not at a task API and a log.

Turn the tools off with tools: false and the split view still works; the crew is then human-driven only.

Why crew_send waits

A coding agent's answer arrives over tens of seconds. A fire-and-forget send would force the model to poll in a loop and burn a turn per sample, so crew_send returns when the pane settles — the rendered screen unchanged for a quiet period. On timeout it says so and tells the model to crew_peek later; the crew member keeps working.

"Quiet" alone is not enough in either direction, and all three corrections came from real CLIs rather than from the test shell:

  • Enter is typed separately from the message. Both products read one burst ending in a carriage return as a paste and keep the return as a newline, so message + "\r" in a single write fills the composer and submits nothing. The pane then goes quiet — and a settle-on-quiet rule would hand the model back its own unsent question as the answer.
  • An unpainted screen is not a settled one. A CLI that has not drawn its first frame is perfectly quiet, so seating waits for content as well as calm before reporting a crew member ready.
  • The first screen may be a dialog, and the plugin will not answer it. In a directory it has not been trusted in, each product opens on its own trust prompt instead of a composer. The tools say so and hand it to the caller: answer the dialog with crew_send — an empty message presses Enter — and send the task only once the composer is up. A task sent into a dialog is typed into the dialog, and its digits can pick an option; that is how a "count from 1 to 12" prompt once chose 2. No, quit. Auto-answering a product's trust prompt is not the plugin's decision to make.

Sending in the background

crew_send with run_in_background: true puts the same wait on the harness's job seam instead of the calling turn:

crew_send(pane, message, run_in_background: true)
  → started crew job crew-1 — job_output to read, crew_peek to watch
  … the model keeps working; the human watches the pane …
  → background job crew-1 (crew: Codex ← Reply with exactly …) finished
  → job_output(crew-1) → what the crew member said

The job is owned by the calling agent, so job_list and job_output follow the harness's own session fence, and the completion notice wakes an idle model rather than being lost. job_kill stops the watch, sends SIGINT to the pane's foreground, and leaves the pane seated — a cancelled delegation is not a reason to close a terminal someone is watching. Whether that SIGINT also ends the crew member's current turn is the product's decision, and some of them listen for Escape instead; the pane staying open is what makes that recoverable, because the human can take the keyboard. It needs ctx.jobs and a job controller the calling agent can reach; without them the tool says exactly that instead of throwing. Set enableRunInBackground: false to remove the parameter.

Either way the result is the new lines rather than the whole viewport: the screen is diffed against a mark taken just before typing, so the model reads the answer instead of finding it again inside a banner it has already seen. A CLI that repaints in place produces no usable delta, and then the viewport is returned as it always was — and screen carries it regardless.

Why the host runs a second terminal emulator

Raw terminal bytes are the right thing to send a browser and the wrong thing to put in a context window: a full-screen CLI positions its cursor absolutely and repaints, so the stream is mostly escape sequences and the same text several times over. Stripping escapes does not fix it — it yields overlapping fragments in arrival order, not the screen.

So the host runs the same emulator the browser runs, headless, over the same bytes. crew_peek returns the grid a human is actually looking at. That is the only reason this plugin depends on a terminal emulator at all.

The roster

idlabelcommand
claudeClaude Codeclaude
codexCodexcodex
dshdshdsh

Each is spawned in its interactive form — the plain command with no prompt argument, which is what drops the CLI into its own terminal UI rather than one-shot mode.

A roster entry is data, not code. Adding a fourth agent is one row in config — never a new package:

# ~/.dsh/profiles/web/cordis.patch.yml
- id: dsh-crew
  config:
    agents:
      - id: aider
        label: Aider
        command: aider
        accent: '#7c3aed'

A row whose id matches a built-in overrides that built-in field by field, so pointing claude at a wrapper script is one line. enabled: false removes one.

Configuration

KeyDefaultMeaning
agents[]Extra crew members, or overrides of the built-ins by id.
trustedHosts[]Authorities besides loopback that may reach the routes. Match the deployment's --trusted-host values.
cols / rows100 / 30Pane geometry when the browser does not measure one.
scrollbackBytes262144Raw output retained per pane so a reload repaints its screen.
maxPanesPerSession6Panes one session may hold open at once.
graceMs3000SIGTERM-to-SIGKILL grace when a pane closes.
toolstrueExpose the five crew tools to the dsh agent.
enableRunInBackgroundtrueOffer crew_send's run_in_background. Needs the harness job seam.

Security

A pane starts a process on the operator's machine, so the two routes this plugin mounts are held to a stricter standard than a read-only one.

  • The workspace is never chosen by the browser. It comes from the dsh session the request names, exactly as the harness's own subagent providers derive theirs. An unresolvable session is refused, not defaulted — falling back to the server's cwd would start an agent with write access to whatever directory dsh was launched from, on nothing more than an unrecognized id.
  • Both routes are fenced on the Host authority (loopback, or a declared trustedHosts entry) and on Sec-Fetch-Site/Origin. A malformed trustedHosts entry fails the load, not a later request.
  • The control route requires application/json. That is load-bearing: a cross-site "simple" request — the one a browser sends with no CORS preflight — cannot set it, so a hostile page cannot reach a side-effectful operation blind.
  • The WebSocket needs a single-use token minted by the control route and redeemable for 30 seconds, which is what proves a fence-passing caller asked for that stream.
  • A tool call may only touch its own session's panes.
  • Nothing here writes the session log. Raw terminal bytes are not conversation state.

The fence answers "did this come from the dsh UI on this machine". It is not authentication, and network reachability remains the webserver's bind policy — if you expose dsh beyond localhost, that is the decision that matters. See SECURITY.md.

Notes from building it

  • No native dependency. The PTY comes from the harness's subprocess seam (ctx.subprocess.spawnTerminal), so this package inherits its credential scrub and process-tree teardown and ships no compiled addon. node-pty is a devDependency, used only to test against real PTYs.
  • TERM is set by the pane, not inherited. The harness server is normally started from a non-interactive shell, so its ambient TERM is dumb — and a coding CLI that reads that correctly concludes it is not on a terminal and turns off colour, which is precisely the output a pane exists to show. Panes declare xterm-256color / truecolor, which is what the browser end actually is.
  • dist/client.js is committed. Installing this package must not require a build step. npm test runs build-client --check first, so a stale bundle fails CI instead of shipping.

Development

pnpm install
pnpm test                   # 33 tests, against real PTYs, real sockets, and the real fence
CREW_REAL_CLI=1 pnpm test   # + 4 more that seat the real claude and codex

The opt-in suite is where the wire shape stays honest: it seats each product in a throwaway workspace, answers whatever dialog it opens on, and makes it reply to a two-line message — foreground and background. It needs credentials and spends model tokens, which is why it is off by default.

See CONTRIBUTING.md.

License

MIT — see LICENSE. Not affiliated with DeepSeek. "DeepSeek Harness" is DeepSeek's trademark, used here only to say what this works with; the name follows the "DSH" form their brand guidelines recommend.