用 Codex 给 DeepSeek Harness 写了个桌面插件 PaiWarp,一句话自动跑完 PaiCLI 终端测试、录屏并换好教程截图
大家好,我是二哥呀。
突然想到的一个点子,就是给 DeepSeek Harness 桌面版做一个插件,这个插件里我可以让 DeepSeek Harness 帮我运行 PaiCLI,完成终端的一些截图。
因为像 Codex、DeepSeek Harness 这些桌面端 Agent,哪怕是给足权限,他们也说控制不了终端,这就让我很烦。
每次测试 PaiCLI,还要手动敲命令,截图,我就很受不了。

直接搞个终端插件,让 DeepSeek Harness 帮我完成测试,录屏,截图,不就好了?
当然了,开发工作仍然是交给 Codex 来做,我只需要把需求告诉它,虽然这个插件看起来不复杂,但可以和 PaiCLI、DeepSeek Harness、Codex 打通一套工作流,也是 PaiCLI 的一个更符合当前 AI 时代的一个应用场景。

面试求职也很好用啊。
现在打开 DeepSeek Harness 桌面端,选中 paicli 工作区,只需要在聊天框里发一句“帮我重新跑一下第一章里的 Case”,剩下的事情就不用我动手了。
桌面端的 Agent 会自己打开终端,依次键入构建、启动和测试指令,让终端里的 PaiCLI 完成修改代码和编译运行的任务;与此同时,插件在后台用 Chromium 和 xterm.js 把终端画面录成视频,并在启动、修改代码、编译运行三个时刻各截一张图。校验无误后,插件还会把图上传到图床,再把教程里的旧图替换掉。
这篇教程就把完整的过程讲给大家。
- DeepSeek Harness 桌面插件的工作原理
- 桌面 Agent 和 PaiCLI Agent 怎样通过终端衔接
- 自动录屏、截图、替换原图
01、桌面端怎么识别 paiwarp
DeepSeek Harness 收到提示词后:
帮我重新跑一下第一章里的 Case。

先调用 paiwarp_run_chapter_one 打开本机终端,接着连续调用 paiwarp_terminal_input,往终端里依次敲入内容。
mvn clean package
java -Duser.home="$PAIWARP_SESSION_HOME" -jar target/paicli-1.0-SNAPSHOT.jar
读取 demo/src/main/java/com/example/Hello.java,把输出改成 Hello PaiCLI
进入 demo 目录,编译并运行 Hello.java
/exit

要让桌面端识别这套工具,得先按 DeepSeek Harness 的插件包(bundle)规范组织好插件目录。整个插件放在 PaiCLI 仓库的 plugins/paiwarp-dsh 目录下,核心入口声明在 package.json 里。
{
"name": "paiwarp-dsh",
"version": "0.1.0",
"description": "在本机终端复跑 PaiCLI 教程,验证产出、拍摄截图与录屏。",
"type": "module",
"main": "./host.js",
"exports": {".": "./host.js", "./client": "./client.js", "./locale/*.json": "./locale/*.json", "./package.json": "./package.json"},
"dependencies": {"@xterm/xterm": "6.0.0"},
"engines": {"dsh": ">=0.2.2-rc.1 <0.3.0"},
"dsh": {
"bundle": {"patch": "./cordis.patch.yml"},
"client": {"platform": "web", "inject": ["@deepseek-ai/dsh-api-remotes","@deepseek-ai/dsh-client-ui-sidebar-right","@deepseek-ai/dsh-client-ui-conversation"]}
}
}
这份配置把插件分成了前后端两部分。
下文说的“宿主”,指桌面端里负责加载插件的 Node.js 后台进程。
main指向的host.js是插件在宿主进程里的入口,负责注册工具、校验工作区和启动 Python 运行器;exports里导出的./client指向client.js,运行在桌面端的 Web 界面里,负责渲染聊天卡片和右侧栏的终端面板。locale/zh.json与locale/en.json提供插件管理页上显示的名称和简介。dsh.bundle.patch指向同目录下的cordis.patch.yml。DeepSeek Harness 使用 Cordis 加载扩展,Cordis 是一套负责管理插件加载、卸载和依赖注入的框架。下面这三行配置把paiwarp-dsh加载到宿主的启动列表里。
- insert:
- id: paiwarp
name: paiwarp-dsh
本地开发和安装时,先准备好本机依赖,再通过桌面端“从本地目录安装”的入口把插件安装上。
- 本机环境:安装 Java 17 及以上版本、Maven、Node.js、
ffmpeg和ffprobe,并为系统自带的/usr/bin/python3安装 Playwright(一套用代码控制浏览器的自动化测试库)及其配套的 Chromium 浏览器 - 安装前端依赖:从仓库根目录进入
plugins/paiwarp-dsh,在终端执行npm ci安装@xterm/xterm - 挂载本地插件:打开 DeepSeek Harness 桌面端的“插件”页面,点击“添加插件”,填入
plugins/paiwarp-dsh的绝对路径,安装后点击“立即启用”

02、提示词怎么变成终端输入
插件启用后,在聊天框里只要输入“帮我重新跑一下第一章里的 Case”,DeepSeek Harness 就知道先调用 paiwarp_run_chapter_one,再连续调用 paiwarp_terminal_input。
为什么?
答案在 host.js 追加给模型的系统提示词(system prompt section)和工具定义里。host.js 在顶部声明了 inject 数组,向 DeepSeek Harness 申请使用五个宿主服务:
tools:向当前会话的模型注册可调用的工具commands:注册聊天框里的斜杠命令/paiwarp,用于查看终端状态、暂停、恢复或手动发送按键workingDirectory:获取并核对当前会话绑定的本地工作区路径sandboxPolicy:读取当前会话的权限模式,判断是立即放行还是弹出审批systemPrompt:往模型的系统提示词里追加插件专属的使用规则
// plugins/paiwarp-dsh/host.js(节选)
ctx.systemPrompt.section({
name: 'paiwarp:chapter-one', order: 530,
text: '在 paicli 工作区,用户要求复跑第一章(第一期)的教程 Case 时,直接调用 paiwarp_run_chapter_one。它在本机专用终端输入教程命令和两个中文任务、检查 PaiCLI 的真实工具输出、截图录像、只更新对应图片地址。打开后,每当工具返回 waiting_input,就调用 paiwarp_terminal_input,按返回的 run、turn 和 expected 原样键入那一行。一直执行到 passed 或 failed;只在最终状态汇报。'
})
这段提示词给外层模型规定了明确的调用顺序。
模型看到用户要求复跑第一章的 Case,就先调用不带参数的工具 paiwarp_run_chapter_one。宿主收到调用后,先通过 checkWorkspace 校验当前会话的工作目录是不是插件所在的...
未能定位到原文的划线
企业级Agent工作流编排项目PaiFlow
Vibe Coding版本的PaiAgent
派聪明RAG AI知识库Java版本+Go版本
微服务 PmHub、技术派、MYDB
求职派JobClaw(OpenClaw/Hermes架构
PaiCLI(类似Claude Code的Agent
派简历(代码已完成)
等实战项目。
1. 微信扫右侧的优惠券加入知识星球
2. 解锁星球的实战项目教程和源码: 项目源码+教程获取
真诚点赞 诚不我欺
回复