dsh-agentone
Verifieddsh-agentone · v1.0.13 · MIT · Web UI
AgentOne 平台集成:平台模型、SkillHub 技能与技能包(整包/内置技能与插件一键装齐,逐项进度与失败重试)、套餐、CLI(安装网络重试与可回看的失败详情)、飞书云盘共享文件夹(web/官方桌面端侧栏页签 + 左栏底部入口)、左栏「工作台」面板;插件装前宿主兼容预检;官方桌面端「关于」页自升级修复:分离进程 pnpm 通道绕开宿主 already-installed 死路(Windows 适配),附「让 AI 代升级」一句话引导
Install
dsh plugin add dsh-agentone Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Published to npm without a public repository. Inspect the package contents before installing.
Tags
Readme
dsh-agentone
AgentOne 平台集成插件(dsh web 版 / 桌面版通用)。安装后让独立 dsh 接入公司 AgentOne 平台:IDOne 登录、平台模型、SkillHub 技能、套餐申请、dsh 插件管理、 lark-cli / ccpg-cli 状态探测、CCPG 品牌定制。
能力总览(M1–M4 已全部交付)
- 平台登录(M1):设备登录流(一次性授权码),入口按平台能力面自动
路由——平台开启邮箱锚点模式(IDOne 统一登录)时走 IDOne,否则回退
飞书;凭据保存在本机
$DSH_HOME/agentone/credentials.json(0600)。 access 令牌临期自动轮换(single-flight),refresh 失效自动回到未登录态。 - 平台模型(M2):登录后自动把 dsh 的 llm provider 指向 AgentOne
OpenAI 兼容代理(
/api/plugin/v1),模型密钥不下发到本机;对话经平台 走 TokenHub 按用户计量。平台 403 的plan_required错误码原样透传, 前端据此引导申请套餐(不依赖中文文案匹配)。 - SkillHub 技能(M3):套餐技能与管理员默认技能在启动/登录和常驻后台同步,
支持
611/c611-ops-workbench、611--c611-ops-workbench与全局技能名; 技能市场搜索、手动安装/卸载,装/卸载后技能列表即时刷新(失效 45s status 缓存);已装技能平台侧对比 latest 版本/指纹,有更新时展示 「v旧 → v新」并支持一键升级(覆盖式重装,原子替换旧目录);技能包 zip 走平台代理下载(穿越清洗 + 原子落盘)。技能行展示中文名,按 「市场目录 display_name → 本地 SKILL.md(short-description/H1,含 CJK 才用)→ DefaultSkill 用途说明首句 → bare slug」四级名字链解析,列表与 市场搜索同源;行1 中文名 + 唯一分类徽章,行2 bare slug(等宽)· 来源 (套餐/平台默认)· 状态,行 title 挂完整用途说明;时间戳版本号 (YYYYMMDD.HHMMSS)显示为日期。 - SkillHub 连接配置(M3+):登录后自动从平台拉取 registry 与用户级
个人 token,写入
$DSH_HOME/agentone/skillhub.env(0600,含SKILLHUB_BASE_URL/SKILLHUB_TOKEN/CLAWHUB_REGISTRY/CLAWHUB_TOKEN四个与平台托管容器同名的变量),本机有 clawhub CLI 时同步写入登录态; 登出时全部清理。会话内使用:source $DSH_HOME/agentone/skillhub.env。 - 套餐申请(M3+):状态页「套餐」tab 展示当前套餐/审批中/可申请列表, 一键提交申请;审批通过后前端轮询检测到 active 自动同步模型。
- 平台默认能力(#479):管理员在「集成开关 → dsh 插件」单独保存默认 技能、npm 插件、用途说明和安装期构建授权。技能和插件始终安装最新发布版本, 受管内容有新版时自动升级;客户端启动、登录及约每 5 分钟后台检查。 本机状态由目录、版本和归属记录共同确认,用户级台账作为参考。 目录已有用户文件、账号/registry 不同时等待用户确认应用;停用只停止管理, 不删除本机内容。平台暂时不可用时缓存仅展示,不用于安装。
- 内置能力一键装齐:技能页与插件页各有一个「一键装齐(N)」主按钮,按平台 清单逐个安装缺失项;面板逐项显示等待 / 安装中 / 成功 / 失败与原因,结束后可在 原地重试失败项,不需要回列表找按钮。可选能力、本机冲突和「需升级 DSH」的条目 不参与批量——不覆盖用户文件,也不做注定失败的重试。技能包「安装整包」、单技能 安装与批量共用同一进度面板。
- dsh 插件管理(M3+):列出当前 profile 的包、版本、bundle 注册状态;
安装成功需物理版本、插件声明和 profile 注册同时成立。注册不证明运行时加载,
页面提示重启生效。Web 必须配置实际
profileName;桌面壳按宿主契约自动取 当前 profile——第三方壳(desktopProfiles + 受管 desktopPnpm 通道)与官方 DeepSeek Harness 应用(launcher 的 profileContext + 宿主 pluginManager, 与应用内「设置 → 插件」同一管线,不接受 pnpm 选项)分别适配;安装/卸载 串行排队、支持生命周期取消。自身与 DSH 基础组件不属于平台默认清单, 自身只在独立安装模式允许手动升级。 - 旧版技能记录迁移(0.5.41):0.5.39 起本机安装真源是
$DSH_HOME/agentone/skill-state/<slug>.json;≤0.5.38 只写平台台账,升级后 这些技能会「有目录、无记录」。这类条目标注「旧版安装」,插件页提供 「重新应用旧版安装的技能」批量入口(按平台版本原子覆盖目录并重建记录); 有本机记录但内容被改过的真冲突仍逐项人工确认,不自动覆盖。 - CLI 探测、安装与授权(M4):
lark-cli/ccpg-cli安装与授权态三态探测; 未安装时「安装」一键自助安装(lark 走npm install -g @larksuite/cli@latest, 无 npm 的机器退化 pnpm——含 DeepSeek Harness 桌面壳自带 Node/pnpm 工具链, 全新 macOS 不装 Node 也能装;ccpg 走公司auto-install.sh,口径与平台 cli-deployd 一致)。lark-cli 安装遇软件源网络错误会自动按原配置重试一次, 仍失败才改用国内镜像(--registry只作用于本次安装,不改本机 npm 配置); 失败时页面保留可展开的完整命令输出与中文网络提示,不再是十秒后消失的一行 技术摘要; 已装未授权时「去授权」发起官方 Device Flow(授权链接 + ASCII 二维码 + 验证码 + 自动轮询确认,设备码仅存插件进程内存); lark-cli 首装未config init时探测为「未配置」,「初始化应用」一键驱动 官方config init --new(长驻子进程 + 验证链接/二维码 + 终态轮询,成功后 自动衔接设备流授权;关闭弹窗即终止子进程)。平台托管实例不提供自助初始化 ——容器内 HERMES_HOME 上下文下 config init 会拒绝执行,应用配置由 Hub 经 cli-deployd 统一下发。 - 插件装前宿主兼容预检:安装/升级前先查目标版本的
peerDependencies与本机 DSH 运行时(lib/host-compat.js,语义对齐宿主 includePrerelease 判定)——不满足时不发起安装,弹「这个新版本要求更新的 DSH」确认框:主按钮 「保持现在的版本」(已装版本兼容时明确告知可继续使用),次按钮「仍然更新」 显式强制(宿主校验仍会兜底拒绝并回滚)。升级引导按宿主形态区分:官方桌面 → 应用内检查更新/官网;社区壳(DSH NEXT / DSH Desktop)→ 引导改装官方版https://www.deepseek.com/harness/;平台托管实例 → 联系管理员升级镜像。 宿主拒绝后的英文installation rejecteddiagnostic 统一翻译成同口径中文; 平台同步条目置为「需升级桌面版」(非失败、无重试按钮,出「详情」弹窗)。 - 全局中文回复默认:插件启动时在
$DSH_HOME/AGENTS.md注入受标记 管理的「默认始终使用中文回复」指令块(dsh 官方 agent-instructions 机制, 每个会话基线加载,project 级指令优先);幂等不重复注入,用户已有语言 偏好或删除标记块后不再介入(本机只做一次决策,记录于$DSH_HOME/agentone/language-default.json)。 - 飞书云盘资料夹(侧边栏 tab):注册 better-sidebar「飞书云盘」页签,
iframe 直嵌飞书网页版(飞书不设 frame-ancestors,spike 实测),页面交互
全部是飞书官方 Web UI。寻址(
lib/drive.js):打开时用 lark-cli 在 「我的空间」根目录找到(没有则创建)AgentOne文件夹并缓存 token (改名不影响、被删自动重建);设置页「云盘」tab 支持初始化/重新定位/ 粘贴链接收养其他文件夹(POST /agentone/api/drive/home/resolve)。 独立 dsh 未装 better-sidebar 时静默不注册该页签。 宿主适配:页签与 footer 入口所有宿主恒注册(官方桌面版dsh-app://不再被 误伤);个别会静默拦跨源 iframe 的桌面壳由页签内运行时探测兜底——onLoad后contentDocument仍可读即白屏,换退路卡片(新窗口打开 + 重试)。 内容变化时自动刷新:服务端对根清单算指纹(GET /agentone/api/drive/rev,10s 节流), 页签 ready 后每 8s 轮询,指纹变了才重挂载 iframe。用户正在云盘里浏览时不硬刷新 (重载会回到根视图):顶部弹蓝色横幅「云盘内容有更新 / 立即刷新」,右下角常驻 「刷新」胶囊同步变蓝;焦点离开云盘后下一拍自动应用。点胶囊/横幅立即刷新并重新寻址。 - 启用云盘(默认启用):设置页「云盘」tab 的「启用云盘」开关。AgentOne 文件夹是
用户与 AI 共享的工作目录——AI 可以读取使用里面的资料,也可以把飞书云文档存进去。
插件做两件事(
lib/archive.js):在$DSH_HOME/AGENTS.md注入受标记管理的指令块 (每会话基线加载,只告知能力——可以查/存、在哪查/存;目标指向drive.json而 不写 token),并把技能装到$DSH_HOME/skills/agentone-drive/(SKILL.md+scripts/drive.mjs:list查看内容(只读不创建)、按「项目或应用」 查找或创建子文件夹、重复保存同一文档不重复移动、缺权限时给中文自助指引)。 默认启用,只有用户明确停用过才关闭(落盘enabled:false);停用时撤销指令块与 技能目录。同名技能目录不是本插件创建时拒绝覆盖,开关状态也不改动;历史版本的agentone-drive-archive目录带归属标记时升级自动清理。 不承诺「自动保存」——插件做不到替模型执行,是否读/存由模型按任务判断; 用户可见文案统一用「可以读取 / 可以存进」,不用「自动保存」「归档」等说法。 - 工作台面板(sidebar.panellist + main 成对注册):左栏「自动化任务」下方
出现「工作台」入口(order 15),打开卡片式工作台页面。当前集成
「DOC数字化AI运营平台」:整卡点击网页内嵌打开(iframe 直嵌
docapp.hypersmart.ltd,飞书账号 OAuth 登录链无 frame 拦截,登录 cookie
留宿主会话);卡片右下角保留「用飞书客户端打开」applink 深链。切面板
不断页:iframe 常驻
document.body浮层(React 只渲染占位 div 对位), 切走仅隐藏(CSS 隐藏不销毁浏览上下文),切回原样恢复——应用停在二级页面 也不丢。白屏宿主探测与云盘页签同款(contentDocument可读 = 被拦),兜底 新窗口/客户端/重试。左栏浮层z-index:1盖主区内容、让位操作胶囊与宿主弹层。 - 首启引导:dsh 首次启动弹出平台登录引导(order -50,早于官方 「添加 API Key」),登录一次即跳过官方密钥引导;暗色主题适配。
- CCPG 品牌定制(自 dsh-ccpg-brand 移植):服务端
lib/brand.js四条腿 + 客户端 hero 图标 slot——tapIndex把<title>改为「CCPG AI 工作台」、 favicon 指/favicon.svg、</head>前注入品牌 CSS(侧边栏品牌行换成 「CCPG 图标 + CCPG AI 工作台」(官方鲸鱼与 deepseek 字标由 CSS 隐去后自绘), hero 文案换「让社区变得更美好」、藏「预览版」徽章);exact 路由/ccpg/logo.png、/ccpg/icon.svg服务品牌图,/ccpg/brand.css是品牌 CSS 的唯一正文来源,/favicon.svg用 logo 生成的 SVG 接管标签图标 (exact 优先于 SPA fallback)。hero 图标不在 CSS 里改:官方 HeroShell 声明了conversation.hero.brand.mark且官方实现在其中不注册任何东西(该 slot 留给品牌方),所以由lib/client.js的HeroBrandMark注册 CCPG 图标 ——类名会被官方重构(旧headlineText已删),slot 名才是稳定契约。 品牌 CSS 必须同时由客户端注入:tapIndex只作用于 webServer 渲染的index.html,桌面壳(dsh-app://)的首页文档不走那条路——只挂 tapIndex 时桌面端侧边栏字标与 hero 文案/徽章全是官方原样(2026-10-15 实测)。 故 CSS 正文只放服务端/ccpg/brand.css一处,client.js的injectBrandStylefetch 回来挂<style data-plugin-css>(官方客户端插件 的既有做法),已注入(服务端或客户端)则覆盖同一份、不叠加,杜绝 「抄两份、漏改一份」。侧边栏官方是把图标/字标注册进 slot 的 (sidebar.brand.mark/sidebar.brand.name),所以 CSS 只能隐掉 brandIdentity 下的子元素、再由brandMark背景与brandName::after自绘(收起态railMark同样处理)。 类名锚点用[class*="本地名"](css-module 哈希前缀随 dsh 构建变,本地名 稳定),且必须带!important:官方客户端 CSS 是运行时 append 到 head 的, 同特异度时后写的会赢;brandIdentity两个子元素必须分别隐藏——写[class*="logoRow"] [class*="brand"]会同时命中 brand/brandIdentity/ brandMark/brandName 四个元素(曾画出 4 个 logo)。tapIndex 缺失的旧宿主 自动跳过首页变换(仅告警),资源路由仍生效;tapIndex 与路由的 disposer 均接入 fiber effect,live patch reload 不泄漏不撞 duplicate route。 整套品牌(左上角 + 首页)由设置页「工作台」tab 的「品牌定制」开关实时控制, 见下一条。 - 设置页「工作台」tab(品牌定制开关):AgentOne 设置面板新增的可扩展页,
排在「云盘」与「关于」之间(
lib/page.js的 tab 体系,模型仍是默认激活页)。 首个开关是品牌定制(默认开,偏好键branding):这是整体品牌开关, 关掉后左上角与对话首页一起恢复官方的图标与文案(服务端/ccpg/brand.css正文为空,tapIndex也不再改<title>/favicon,客户端注销 hero 图标 slot)。 偏好存在lib/workbench.js的$DSH_HOME/agentone/workbench.json(原子写、读失败回落默认),/agentone/api/workbench的 GET/POST 读写;服务端按当前偏好生成品牌 CSS (getPrefs()现取,开关一改brand.css与 tapIndex 注入都跟着变),客户端injectBrandStyle同拉brand.css与偏好、按开关挂/清样式并注册/注销 hero 图标 slot。面板保存后postMessage({type:'dsh-agentone:workbench'})通知首页 重新同步,所以切换即时生效、不用重启(消息发不出去也只是下次进首页才生效, 服务端已落盘)。
所有平台请求统一走 lib/http.js(默认 10s 超时、技能包下载 60s),
平台挂起时快速失败并给出中文提示,不会吊死状态页轮询。
安装
dsh plugin --profile web add dsh-agentone
平台托管镜像集成:docker/dsh/Dockerfile.default 默认插件块(见
plugins/README.md 全流程)。
使用
打开 dsh web 的 /agentone/ 页面(或 dsh 设置 → AgentOne)→「IDOne 登录」
(平台未开启统一登录时为「飞书登录」)→ 浏览器完成平台 OAuth → 自动跳回
并显示已登录账号。授权完成页会等待
模型配置就绪后自动关闭;配置失败时展示原因并提供「重试同步」。
登录成功后插件自动完成模型配置(也可点「重新同步模型」手动触发):
$DSH_HOME/settings.yaml写入llm-pi-ai.providers.platform(指向平台/api/plugin/v1代理)与agent-default-model,dsh 模型选择器出现 「平台模型」;模型列表按系列聚簇 + 系列内版本降序写入(插件侧按平台sort_models_by_version同一规则兜底重排,旧版平台返回的上游原序也能得到 稳定顺序,默认模型仍取平台下发的default_model);$DSH_HOME/.credentials.yaml写入refs.AGENTONE_API_KEY(0600),内容 是 30 天插件令牌而非真实模型密钥——密钥不出平台,TokenHub 按用户计量;- 只覆盖
platform命名空间,用户自己配置的其它 provider 原样保留; - 同步失败(如平台侧 AirRouter 瞬时不可达)不阻断登录/启动,原因记录在 状态页「同步状态」;状态页轮询发现残留错误时按指数退避(1min 起、 封顶 30min、最多 30 次)自动重试,平台恢复后无需重启 dsh 即自愈;
- 「退出登录」(页头按钮)会吊销平台令牌、移除凭据引用与 platform
provider(其它 provider 的默认模型设置不受影响);凭据文件损坏时也能
正常退出(坏文件移开为
credentials.json.corrupt)。
登录流(与平台 app/api/plugin_auth.py 契约):
插件页 ──POST /agentone/api/login──▶ 本插件后端
◀─ {login_url, provider} ──
浏览器 ──login_url──▶ 平台 OAuth(IDOne 优先,飞书兜底)──▶ /api/auth/plugin/landing
landing(JS, Bearer) ──POST /api/auth/plugin/grant──▶ {redirect_url(一次性 code)}
浏览器 ──redirect_url──▶ 本插件 /agentone/callback?code
插件后端 ──POST /api/auth/plugin/exchange──▶ {access_token}
(存本机 0600,state 比对防 CSRF)
所有写操作接口仅接受 Content-Type: application/json 的请求,阻止跨站
表单伪造 JSON POST。
配置(dsh settings)
| 字段 | 默认 | 说明 |
|---|---|---|
platformUrl |
https://ccpg.one.agentone.work |
AgentOne 平台地址(本地开发用 profile cordis.patch.yml 覆盖为 http://127.0.0.1:8558) |
storeDir |
$DSH_HOME/agentone |
凭据目录 |
profileName |
空 | Web 模式填写实际启动 profile(例如 web 或自定义名);无法确定时暂停插件写入。Desktop 自动读取当前 profile |
brandTitle |
CCPG AI 工作台 |
品牌定制:浏览器标签页标题与侧边栏品牌名 |
brandHeroHeadline |
让社区变得更美好 |
品牌定制:聊天首页 hero 大标题文案 |
品牌是否显示不在这里配(settings 改动要重启):设置页「工作台」tab 的「品牌定制」开关实时生效, 关掉后左上角与对话首页一起回官方。
密钥类值一律不进 settings,仅落 credentials.json(0600)。
设置面板打开提速(内置行为)
打开「设置 → AgentOne」不再被平台往返卡住:tab 栏与骨架立即可见,数据并行拉取
(/api/me、capabilities、技能清单、目录四类请求由串行改为两层并行),应用启动时
后台预热快照。技能清单快照 45s 内直接复用;过期后先喂旧值、后台刷新(装卸技能
即时失效,不吃旧值);已装技能的目录摘要按(路径, 大小, mtime)签名缓存;
桌面壳的面板 HTML 按插件加载周期闭包缓存。两个环境变量可调(常量在插件加载时
求值,改了要重启宿主):
| 环境变量 | 默认 | 说明 |
|---|---|---|
DSH_AGENTONE_STATUS_TTL_MS |
45000 |
技能清单快照视为新鲜的时长 |
DSH_AGENTONE_STATUS_STALE_MS |
600000 |
过期后仍可先喂旧值的窗口上限,超过则同步等待拉新 |
模块结构
lib/
index.js 路由与业务编排(登录/状态/技能/套餐/插件/CLI)
page.js 状态页与授权完成页的 HTML/CSS/JS 模板(纯静态)
brand.js CCPG 品牌定制(tapIndex 首页变换 + /ccpg/brand.css、/ccpg/*、/favicon.svg 路由)
workbench.js 设置页「工作台」本机偏好(workbench.json,原子写;目前只有 branding 整体品牌开关)
desktop.js 桌面壳探测与 profile 解析(全仓唯一一份,见下节)
http.js 平台请求统一通道(超时、错误码透传)
auth.js 登录流、令牌轮换/吊销、能力面/套餐 API
language.js 全局中文回复默认($DSH_HOME/AGENTS.md 受标记管理注入)
model.js 平台模型 → settings.yaml / .credentials.yaml
skill.js 技能下载/解包/卸载(zip 穿越清洗、原子落盘)
skill-state.js 技能本机记录($DSH_HOME/agentone/skill-state/<slug>.json)、状态判定
与本地中文名解析(SKILL.md short-description/H1 → 技能列表中文名)
defaults-sync.js 平台默认能力协调器(清单拉取/对齐/缓存)
profile-plugins.js 当前 profile 的插件操作(通道选择见下节)
store.js 凭据持久化(0600;损坏自动移开)
proc.js dsh/pnpm CLI 转发与 lark-cli/ccpg-cli 探测
qrcode.mjs 授权 URL 的二维码 SVG(vendor qrcode-generator,MIT;lark/ccpg 通用)
client.js dsh 浏览器端 bundle(设置菜单 iframe + 首启引导 + 左栏工作台面板 + 飞书云盘页签/footer + 设置导航图标换肤 + 品牌 CSS/hero 图标按偏好注入)
桌面宿主契约(两类壳,判定只有一份)
宿主服务面差异是 0.5.39/0.5.40 两次事故的根因类别(品牌正则抄了两份漏改一份;
只接了一类壳的契约)。品牌判定与 profile 解析只允许 lib/desktop.js 一份实现,
test/desktop-srcdoc.test.mjs 用源码扫描守卫这一点。
| 第三方壳(dsh-plugin-desktop) | 官方 Electron 应用(DeepSeek Harness / DSH NEXT) | |
|---|---|---|
| profile 来源 | ctx.get('desktopProfiles').current(name + dir) |
ctx.get('profileContext')(name/dir/packageManager,launcher 发布) |
| 安装通道 | ctx.get('desktopPnpm').runPlugin(argv, dir, signal) → {stdout, stderr, done, cancel} |
ctx.get('pluginManager').installBundle(spec, {requestId}) / removeBundle(name) / cancelInstall(requestId) → {application: applied|restart-required|overridden|cancelled|failed, packageResult, error} |
| 不发布 | pluginManager |
desktopProfiles、desktopPnpm(app.asar 均 0 命中,实测 2026-10) |
| CLI 兜底 | dsh CLI 拒绝 --profile desktop |
同左;profileContext 是唯一答案 |
要点:
- 官方
pluginManager与应用内「设置 → 插件」同一管线,不接受 pnpm 选项;--allow-build不转发(构建审批由官方管线自理),其余附加参数必须拒绝而不是 静默丢弃(profile-plugins.js的desktopManagerRun)。 application: 'overridden'是「改动保留、被别的层覆盖显示」,不是失败。- 非桌面宿主(
dsh web/CLI):插件配置profileName优先,launcher 的profileContext次之(desktop.js的resolveProfileTarget)。 - installed ≠ enabled(读官方
dsh-plugin-manager源码确认):dsh.profile.bundles是启用集,node_modules里的依赖只是「已安装」。 官方「已安装列表」= 启用集 ∪ profile 依赖 ∪ 应用自带依赖 (installation.dependencies——rc.2 那批 browser-use/computer-use 由应用 供给、不可卸载),因此会出现「已安装但未启用」条目;installBundle装新包时 reconcile 会自动启用带dsh.bundle声明的新依赖,但不会悄悄启用存量 未启用包。前端术语用「已启用/未启用」,别叫「已注册」——和官方 UI 对不上。 peer 不兼容的启用会被宿主拒绝(结构化错误incompatible-version),需在 应用内授权该精确版本(version exemptions)或等插件发兼容版本。
开发
# 本地路径安装调试(无需发包)
dsh plugin --profile web add /path/to/plugins/dsh/dsh-agentone
无构建步骤(纯 ESM JS);运行时 peer 依赖 @deepseek-ai/cordis /
@deepseek-ai/schemastery 由 dsh host 提供。测试:npm install && node --test
(YAML 合并/登出清理语义、路由冒烟、凭据容错、令牌轮换等)。
发版前真实宿主门禁(单测全绿但宿主内翻车的两类事故都由它拦):
# 1) 把候选版本装进 desktop profile(用应用自带 pnpm,与应用内安装同源)
# RT="/Applications/DeepSeek Harness.app/Contents/Resources/runtime"
# cd ~/.dsh/profiles/desktop && \
# DSH_DESKTOP_NODE_EXECUTABLE="/Applications/DeepSeek Harness.app/Contents/MacOS/DeepSeek Harness" \
# "$RT/bin/node" "$RT/pnpm/bin/pnpm.mjs" add 'dsh-agentone@<版本>'
# 2) 完全退出并重开 DeepSeek Harness(插件代码 restart-required)
# 3) 跑门禁:逐条断言本次事故签名(旧代码未重启/profile 解析/插件清单/技能搁浅)
node scripts/desktop-host-smoke.mjs