pi2dsh README

The project's README from github.com/weijiafu14/pi2dsh. As one markdown file: README.md.

pi2dsh

English | 中文

Run the Pi ecosystem's plugins on DeepSeek Harness, unmodified.

dsh plugin add pi2dsh          # once
dsh plugin add <any-pi-plugin> # then any Pi plugin, straight from npm

Why this exists

DeepSeek Harness is built on ideas worth betting on — a durable, reconstructable session log, a clean service composition, an agent loop you can actually reason about. What it does not have yet is a large plugin ecosystem: it is early, and the plugins people want on day one — web search, memory, code navigation, subagents, vision — are mostly not written for it yet.

Pi has that ecosystem already, and it is mature: hundreds of published packages, many with real users.

pi2dsh is one compatibility layer that implements Pi's public extension ABI on top of DSH's native services, so a Pi package runs on DSH as published — no fork, no patch, no per-package adapter. You install a Pi plugin the same way you install anything else in DSH, and it works.

At the same time, pi2dsh is an ongoing, full-surface, real-world test of DSH's architecture. Instead of patching individual plugins, it asks whether the models, tools, sessions, interaction, resources and client capabilities that Pi plugins rely on can preserve their logic and lifecycle using only DSH's public services and extension seams. If they can, that is strong evidence that DSH's architectural goals for building agents and an agent-plugin ecosystem have been achieved, at least along this dimension. Wherever the bridge must bypass, degrade or cannot express a capability, it pinpoints an architectural gap that remains.

Install

One engine, then whatever plugins you want:

dsh plugin --profile web add pi2dsh
dsh plugin --profile web add pi-mcp-adapter

Then restart dsh — plugins mount at startup.

A profile needs a surface bundle. DSH's built-in templates are web and headless. A custom profile is valid when its product installs a surface — for example @deepseek-harness-tui/dsh-tui in the dsh-tui profile. A bare arbitrary profile has no surface and can start with nothing to drive it, so add the intended surface to dsh.profile.bundles first.

That is the whole model. There is no conversion step, no generated bundle, no build. The engine discovers the Pi packages in your profile (every one is something you explicitly added) and mounts them through a single bridge instance: one model directory, one login, one credential store, one upgrade unit.

Day-to-day:

Task Command
Add a plugin dsh plugin add <pkg> (then restart dsh)
Remove a plugin dsh plugin remove <pkg> — remove plugins before removing the engine
Upgrade a plugin dsh plugin add <pkg>@latest — the engine is untouched
Upgrade the engine dsh plugin add pi2dsh@latest — your plugins are untouched
Check a plugin before upgrading npx pi2dsh inspect <pkg>@<version>

Two installer messages worth knowing:

Requires Node.js 22.19+ and DeepSeek Harness.

Engine configuration

The engine reads one config block from its plugin row. Today it takes a single opt-in:

# $DSH_HOME/profiles/<profile>/cordis.patch.yml
- id: pi2dsh
  config:
    serveNativeSubagents: true

serveNativeSubagents (default: off) serves DSH-native subagents with the profile's Pi packages. With it on, a child agent DSH spawns through its own subagent delegation (one whose session carries the subagent origin) receives every discovered Pi package mounted on its own agent scope — the package's tools, commands and prompt sections appear for that child only, and every contribution unwinds when the child ends. With it off, such children run as plain DSH agents, exactly as before.

The mount is guaranteed for the child's first turn: prompt assembly and tool execution wait for it, so even a child that runs a single turn sees the full tool set. Each child is served exactly once, whichever path DSH created it through — children the agent registry reports as runtime roots are served by the engine's root mount path, and the subagent path serves the rest; the two never overlap. Pi subagent-bridge children are unaffected either way: they already receive the creator package's own per-spawn loader mount, and the bridge recognizes them by the pi2dsh-sub- session-id prefix (stable across a persisted resume), so no child is ever mounted twice.

Walkthrough: advanced MCP in your terminal

The clearest example of what the bridge buys you. dsh-TUI ships a native /mcp command for DSH's official MCP client — it works, and it stays untouched. The Pi ecosystem has a much richer MCP power tool: a full-screen server manager, lazy tool discovery, one proxy tool instead of flooding the model context with dozens of tools, JavaScript orchestration of multiple MCP calls, OAuth logins, resources and prompts. With the bridge, that package runs unmodified.

1. Install

dsh plugin --profile dsh-tui add @deepseek-harness-tui/dsh-tui   # skip if the profile exists
dsh plugin --profile dsh-tui add pi2dsh
dsh plugin --profile dsh-tui add pi-mcp-adapter

Or use the same unmodified Pi packages in dsh-pi-tui:

dsh plugin --profile pi-tui add @xmoon76/dsh-pi-tui
dsh plugin --profile pi-tui add pi2dsh pi-mcp-adapter @tintinweb/pi-subagents
dsh --profile pi-tui

That composition keeps dsh-pi-tui's native /login and projects Pi OAuth flows into it, mounts the original MCP manager through the public piTuiExtensions surface, and exposes the original Pi subagent flow at /agents. See examples/pi-tui-ecosystem.

Then restart dsh — plugins mount at startup.

2. Configure your MCP servers

Inside dsh-TUI, run:

/pi-mcp setup

The setup flow can adopt MCP server definitions from host configs you already have into the adapter's own standard mcp.json. No bridge-specific configuration exists — everything you touch is the package's own surface.

3. Use it

/pi-mcp

opens the full-screen interactive server manager — its footer documents the keys for enable/disable, reconnect and OAuth login. The model receives the adapter's mcp and mcpScript tools through DSH's normal tool registry, and each agent (/new included) gets its own fully connected instance.

dsh-TUI's native command remains separate, and both stay available:

/mcp       # native DSH MCP-client status
/pi-mcp    # the installed Pi adapter's manager

What is verified behind this walkthrough: 16 host-influenced capabilities end to end on the stock npm stack — three real transports, discovery, proxy and hot-loaded direct tools, mcpScript, resources, prompts, images becoming real DSH attachments, MCP Apps, tool approval through DSH questions, elicitation, sampling against the real DSH model runtime, cancellation and session restart. The full evidence matrix: docs/mcp-compatibility.md.

Full runnable version: examples/tui-mcp.

What actually works today

Two levels, and they are not the same claim.

Level 1 — verified end to end, with a runnable example

Someone sat down, used the plugin's real feature on a real DSH loop, and saw it work. This is the list to trust.

Plugin What was exercised Where Example
@kassing/pi-vision Image analysis delegated to a vision model; image-admission companion route; analysis injected into a text-only model's turn CLI + web vision-bridge
@crazygit/pi-codex-image-gen ChatGPT/Codex OAuth → gpt-image-2 generation; local reference-image upload through DSH approval; image edit; native attachment storage and inline Web rendering CLI + web codex-image-gen
pi-btw /btw <question> as a real child session in DSH's subagent UI; /btw-inject; /btw --save; main thread stays clean CLI + web side-conversation
pi-powerline-footer A terminal status line — model, thinking level, project, context usage — drawn as a floating status pill in DSH web, colour included web presentation-surfaces
pi-mcp-adapter Original full-screen manager; stdio/Streamable HTTP/SSE; discovery, direct/proxy/scripted calls, resources, prompts, images, structured content, MCP Apps, approval, elicitation, sampling, cancellation and restart through DSH runtimes CLI + web + dsh-TUI + dsh-pi-tui tui-mcp · mcp-at-scale · pi-tui-ecosystem · evidence matrix
@tintinweb/pi-subagents The model delegates to autonomous subagents: spawn (with real host-native tools), background + completion notify, mid-run steer, wait-for-result, resume with memory, stop that stays stopped, interactive manager, and cross-restart reopen by archive identity — every child a native DSH session CLI + dsh-TUI + dsh-pi-tui subagents · pi-tui-ecosystem · acceptance report
pi-provider-alibaba Alibaba Token Plan (CN) with its plan-specific key: live catalog, cold-start dynamic model, complete tool loop and restart. The package also declares Coding/API routes, but each requires its own non-interchangeable credential CLI + web alibaba-token-plan
@ff-labs/pi-fff + pi-lens Code navigation for the model: ffgrep content search finds a marker that exists in exactly one file, and lsp_diagnostics reports a planted TS2322 through a real local typescript-language-server — both asserted from the tools’ own results in the session log CLI + web code-navigation
pi-vision-tool Tool registration through a JSON-Schema shape DSH had to convert (anyOf → oneOf) CLI + web —
pi-approval-guardian Every tool call reviewed by a second model before execution; allow and deny both observed CLI (bare env) —
pi-hermes-memory Cross-session memory end to end: memory_add in one session, recalled in a second, fresh one (the codeword existed nowhere else); five tools, ten /memory-* commands, system-prompt memory injection CLI persistent-memory
pi-background-tasks Background shell job started with bg_run, output read mid-run with bg_logs: the log result carries early ticks of a still-running 60-second job, with the final tick provably absent CLI background-tasks

Examples for the two remaining rows are still to be written; per this project's own rule they get re-verified from scratch before an example lands, so the table says plainly which have one today.

Level 2 — mounts and its surface answers a probe

The Pi catalog's top 50 packages by monthly downloads, each mounted in a real DSH runtime and then called through a black-box probe. Status as of 2026-08-14; per-package machine-readable evidence in community/.

47 of 50 exercised successfully · 1 with no probeable surface · 2 pending a re-run.

What this level does not tell you: that the plugin's actual feature works the way you would use it. A probe calls a registered surface with synthetic arguments; a user runs a workflow. pi-btw is the cautionary example — it graded "working" here for weeks while /btw <question> failed on a real session, because the feature needed two ABI gaps closed (Pi's settable AgentState.messages, and an input descriptor on bridged commands) that no probe exercised. Both are fixed in 0.11.0, and both were general fixes that unlock every plugin doing the same thing.

So read the table below as "the bridge covers what this plugin touches", not as "this plugin is known-good". When you try one, a report either way is useful.

Area Packages
MCP pi-mcp-adapter · pi-mcp-extension
Web search & fetch pi-web-access · pi-deepseek-search · pi-web-search · @ollama/pi-web-search · @juicesharp/rpiv-web-tools
Code navigation & editing pi-lens (ast-grep) · @narumitw/pi-lsp · pi-readseek · @ff-labs/pi-fff · pi-landstrip · pi-hashline-edit-pro¹
Subagents & background work @gotgenes/pi-subagents · @mjasnikovs/pi-task
Memory pi-hermes-memory · pi-goosedump
Planning & goals @narumitw/pi-goal · pi-goal-list-loop-audit · @narumitw/pi-plan-mode · @juicesharp/rpiv-todo
Asking you / approvals @juicesharp/rpiv-ask-user-question · pi-ask-user · @gotgenes/pi-permission-system · @juicesharp/rpiv-advisor
Side conversations pi-btw · @narumitw/pi-btw
Models & providers pi-provider-litellm · pi-llama-cpp · pi-prompt-template-model · @vigolium/piolium
Images @kassing/pi-vision (see above) · @amaster.ai/pi-image-gen
External integrations @llblab/pi-telegram · pi-cursor-sdk² · @howaboua/pi-codex-conversion · pi-agent-browser-native² · pi-harness-runtime
Prompting & workflow pi-simplify · pi-fabric² · mitsupi · pi-cc-extensions · pi-rtk-optimizer · pi-interview¹
Terminal decoration pi-powerline-footer · @narumitw/pi-statusline · pi-zentui
Voice @juicesharp/rpiv-voice
Usage reporting @alexanderfortin/pi-deepseek-usage³

¹ Mounts; the exercise run is pending a re-run (a harness-side failure, not a package or bridge gap). ² Ran its own business logic end to end and rejected the synthetic probe arguments — working, correctly validating. ³ A pure event-hook package: all subscriptions attach, but every handler is gated on a live DeepSeek billing session, so a black-box probe has nothing safely callable to assert.

Packages outside the top 50 are not a separate case — the bridge has no per-package code. If one hits an ABI gap, fixing that gap unlocks every package that shares it.

Level 1 grows by working through Level 2 one plugin at a time. The full verification ladder, with what each rung does and does not prove: support matrix.

How it works

Three layers, and nothing crosses them:

┌─ Pi plugin ─────────────────────────────────────────────────┐
│ unmodified npm package. It sees a complete Pi host: the     │
│ three Pi runtime imports, registerX, ctx.*, 33 lifecycle    │
│ events. It never learns DSH exists.                         │
└──────────────────────────┬──────────────────────────────────┘
                           │  Pi's public ABI
┌──────────────────────────▼──────────────────────────────────┐
│ pi2dsh — the translator, and the only place that knows both │
│ vocabularies. Registry projection, event bridge, session &  │
│ subagent bridge, credentials, vendored Pi logic.            │
└──────────────────────────┬──────────────────────────────────┘
                           │  ordinary DSH plugin + llm adapter
┌──────────────────────────▼──────────────────────────────────┐
│ DeepSeek Harness. Sees a normal plugin. Never learns Pi     │
│ exists.                                                     │
└─────────────────────────────────────────────────────────────┘

DSH is two halves, and so is the bridge. The column above is the server; the browser shell has its own plugin surface, and a Pi capability that is a SHAPE rather than a behaviour lands there:

┌──────────── DSH server (cordis) ────────────┐  ┌──────── DSH browser shell ────────┐
│ services · waterfalls · durable events      │  │ dsh.client + exports "./client"   │
│                                             │  │ slot registry (ui-slots)          │
│ pi2dsh engine                               │  │   shell.overlay  ← panel, pills   │
│   tools · commands · models · sessions      │  │   session.header.utilities ← hdr  │
│   subagent bridge ─────────────┐            │  │   overlay ← widget pills/cards    │
│   browser-state registry       │            │  │   composer.dock ← working/footer  │
│     GET /pi2dsh/browser-state ─┼── own route┼──┼─▶ all four seats, one poller      │
└────────────────────────────────┴────────────┘  └───────────────────────────────────┘

The browser half's data rides this package's own route, not DSH's typed Remote system: that one is a first-party, code-generated contract, and an out-of-tree plugin talking to its own UI should carry its own channel. One payload per session serves every seat — the side-conversation panel, plus the Pi presentation surfaces (status, widget, header, footer, title and the working/thinking chrome), which are drawn in the host's own slot seats rather than re-implemented. Two host rules make the browser half load at all — the package must export ./package.json (the host resolves the manifest by subpath), and the ./client bundle is a closure-factory artifact, not plain ESM.

The rules that keep it honest:

pi2dsh (weijiafu14/pi2dsh)

Searching Database…

218 ·GitHub
这是什么?pi2dsh 是一个兼容层,可以让 Pi 生态的插件不做任何修改就直接在 DeepSeek Harness(DSH)上运行 —— 不用 fork,不用打补丁,也不需要为每个包单独写适配器。它在 DSH 的原生服务之上实现了 Pi 的公开扩展 ABI,所以一个 Pi 包安装到 DSH 上,就和它原样发布的一样能正常工作。
那 pi2dsh 本身是一个 DSH 插件,还是我要单独运行的一个工具?它本身就是一个 DSH 插件 —— 也就是那个'引擎'。你只需要添加一次,它就会发现你配置目录里的所有 Pi 包,并通过一个桥接实例统一挂载它们:一次登录、一套凭据存储、一个升级单元。
我怎么把它跑起来?先安装 DeepSeek Harness,然后用 dsh plugin add 添加这个引擎,再重启 dsh —— 插件在启动时挂载。其他 Pi 插件也用同样的方式添加;没有转换步骤,不生成打包产物,也不需要构建。
在它能用之前,我需要装好哪些东西?需要 Node.js 22.19+ 和 DeepSeek Harness。Pi 插件就是普通的 npm 包,通过 dsh plugin add 添加即可;另外你的 DSH 配置需要一个界面(surface)—— 内置的 web 或 headless 模板,或者像 dsh-tui 这样的 TUI 包都行。
桥接之后,每个 Pi 插件在 DSH 上都能真正用起来吗?分两个层次:大约十来个插件(MCP 适配器、子代理、视觉、图像生成、记忆、代码导航、后台任务)经过了端到端验证,并附带可运行的示例;Pi 排名前 50 的包里有 47 个至少能挂载并通过黑盒探测。但探测通过并不等于功能有保证 —— pi-btw 看起来正常了好几周,而 /btw 在真实会话里依然会失败。
安装时有什么坑需要留意吗?有两个。pnpm 默认会拦截依赖的构建脚本(ERRPNPMIGNOREDBUILDS)—— 在 $DSHHOME/profiles/web 里运行 pnpm approve-builds,或者把相关包列到 allowBuilds 下,然后重新执行添加。另外,刚发布新版本时,pnpm 的 minimumReleaseAge 可能悄悄装上旧版本,所以添加时最好固定版本号。
这个桥接能力的招牌示例是什么?是 MCP 演示:Pi 的 pi-mcp-adapter —— 全屏服务器管理器、工具懒加载发现、用一个代理工具代替几十个工具塞满模型上下文、脚本化的多次调用编排、OAuth 登录 —— 不做任何修改就能在 dsh-TUI 里运行,和 DSH 原生的 /mcp 命令并排使用。它有十六项受宿主影响的能力经过了端到端验证。
更新是怎么进行的 —— 每次都要把所有东西重装一遍吗?不用:用 dsh plugin add @latest 升级插件(引擎不受影响),用 dsh plugin add pi2dsh@latest 升级引擎(你的插件不受影响)。删除引擎之前要先删除各个插件,你还可以用 npx pi2dsh inspect . 预先检查一个插件。
作者为什么要做这个,而不是直接写原生的 DSH 插件?DSH 在架构上很有前景,但还太早期 —— 用户第一天就想要的那些插件它还没有,而 Pi 已经有几百个成熟的包。这个桥接同时也是对 DSH 架构的一次全功能面的真实测试:凡是它不得不绕过或降级某个能力的地方,都标记出一个尚待弥补的架构缺口。
Creator
weijiafu14
Size
49.9 MB
Stars
218
Age
2mo
Commits · 90 Days