开铺会商场地 shanhai-city-states/kaipu-dsh-plugin-release
DeepSeek Harness山海・开铺 — DeepSeek Harness 的「场地」插件:多人会商审校,全程留痕。
30.8/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/26 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add shanhai-city-states/kaipu-dsh-plugin-release该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🟢 扫描:未发现敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。
扫描于 2026/11/4(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 多智能体会商审校
- 执行位可替换
- 全程留痕
山海・开铺 — DeepSeek Harness 的「场地」插件:多人多灯会商审校,执行位可替换,全程留痕。
README
由 DeepSeek 最新模型翻译生成⚠️ 内部仓 · 源码暂不公开。转公开须过「公开清单 → 我方审查 → 决策人批」三关。
山海·开铺 · 插件仓(083)
对外名 山海·开铺 | 内部代号 083 远端:https://github.com/shanhai-city-states/kaipu-dsh-plugin(★ Private)日期:2026-10-05(上架轨)/ 2026-10-04(建仓) | 归属:阿舟(插件仓) | 服务端:星月状态:Step 1–3 完成 + 上架轨就绪(判据实测全绿,见 §五) | 契约工作基线:../007-阿舟-契约工作基线-v1.1-merged-2026-10-04.md 外部评审:../008-山海开铺-插件仓-2026-10-04.md(架构评审 —— 结论「符合」;三处留意已处置,见 §二·补)决策答复:../009-星月回复阿舟-五项决策答复与建仓口径-2026-10-05.md
★ 转公开三关(缺一不可 · 不许自行改 Public)
这不是「还没填完」,是当前正式形态。 星月 009 §二 的我方口径原话:
「不公开源码(源码是准备用的),而且公开必须经过我方独立审查。
在我们的用户量和知名度没起来之前,公开源码就是给别人留下武器对付自己。
展开完整文档(README 剩余 1 节)
⚠️ 内部仓 · 源码暂不公开。转公开须过「公开清单 → 我方审查 → 决策人批」三关。
山海·开铺 · 插件仓(083)
对外名 山海·开铺 | 内部代号 083 远端:https://github.com/shanhai-city-states/kaipu-dsh-plugin(★ Private)日期:2026-10-05(上架轨)/ 2026-10-04(建仓) | 归属:阿舟(插件仓) | 服务端:星月状态:Step 1–3 完成 + 上架轨就绪(判据实测全绿,见 §五) | 契约工作基线:../007-阿舟-契约工作基线-v1.1-merged-2026-10-04.md 外部评审:../008-山海开铺-插件仓-2026-10-04.md(架构评审 —— 结论「符合」;三处留意已处置,见 §二·补)决策答复:../009-星月回复阿舟-五项决策答复与建仓口径-2026-10-05.md
★ 转公开三关(缺一不可 · 不许自行改 Public)
这不是「还没填完」,是当前正式形态。 星月 009 §二 的我方口径原话:
「不公开源码(源码是准备用的),而且公开必须经过我方独立审查。
在我们的用户量和知名度没起来之前,公开源码就是给别人留下武器对付自己。」
| 关 | 动作 | 谁 |
| G1 | 出「公开清单」—— 逐文件列「拟公开件 + 一句为什么必须公开」 | 阿舟(出件方)→ docs/公开清单-G1-v1.md |
| G2 | 独立审查(首次转公开 = 全维度审查) | 星月方审查组 |
| G3 | 决策人批 | 星月方 |
判据(G2 会按这条审):每一个要公开的件,都必须能回答 「不公开它,功能就装不上 / 跑不起来」。答不出来的 ⇒ 边界排除(不带),而不是消毒后带上。
★★ 一个必须知道的连锁反应(我发现的):市场 CI 会去 raw.githubusercontent.com/<repo>/HEAD/package.json 取 dsh.bundle;条目里的 url 也是给用户点的链接。Private 仓 ⇒ 取不到、点不开。
⇒ 投稿件(PR)只能在 G1→G2→G3 走完、仓转 Public 之后才提。
在那之前,一切本地准备(market/.yml、tarball、判据)都可以就绪,但那个 PR 不能发。
〇、★ 这个仓库是什么(先读这段,别搞错)
一句话
本仓的主体是「插件」,不是「客户端应用」。
| 层 | 是什么 | 交付形态 | 谁是主推 |
| packages/plugin-platform | 场地插件(审计环境标准:编排对接 + 门禁 + 留痕 + 报告面) | 上 DSH 插件市场 | ★ 主推 |
| packages/plugin-wisdom | 智囊团插件(内置会商灯组,可单独装 / 可不装) | 同市场(独立包) | 次要 |
| packages/contract | 契约类型的唯一出处(I-3 / I-4 的 TS 形状) | 不发市场(内部包) | 支撑 |
| apps/shell | 零门槛分发形态(Tauri 壳 + DSH 侧车) | 安装包(可选·后置) | 后置 |
外部评审结论(008 · 2026-10-04)
「符合『一个服务只做一件事、做好了通过接口通信』,而且做到了「通过环境解耦」这个更高级的形态。」
| 关系 | 通信方式 | 评审 |
| 智囊团 ↔ 场地 | 通过 contract 定义的接口 | ✅ |
| 壳 ↔ 插件 | 不直接通信(壳不感知插件,只提供环境) | ✅ 更高级 |
| 插件 ↔ 服务端 | 通过宿主统一适配层 | ✅ |
★ 硬证据不是「声称符合」,是 check-decoupling.mjs 5 项断言全通过(§五 判据 5)。
三处留意点的处置见 §二·补。
为什么「插件为主」(需求书依据,不是我的偏好)
| 依据 | 原文 |
| 001-A §4.2 分发形态 | 「场地插件(核心):审计环境标准:编排 + 契约 + 门禁 + 留痕 + 签名 —— 优先上 DSH 插件市场」 |
| 001-A A-1 | 智囊团 = 一个独立模块(DSH 视角 = 一个插件);删掉这个插件 ⇒ 场地仍完整可用 |
| 001-A A-3 | 场地不内置任何「必须有的」 Agent;空场地 + 零 Agent ⇒ 仍能启动、能接入、能出审计流程 |
| 001-A R7 | 「开通即用 —— DSH 插件形态 ⇒ 装了就能跑」 |
| 004-客户端插件化 §九 #5 | 「壳(Tauri)是否要感知插件?→ 不感知(壳只管窗口与侧车;插件全在 ②③ 层)」 |
★ 与 003(财税工作台)的思维切换
| | 003 财税工作台 | 083 山海·开铺(本仓) |
| 主导形态 | 壳为主,插件为辅 | ★ 插件为主,壳为可选 |
| 交付给谁 | 财税客户,装我们的安装包 | 插件市场客户,装插件到他们自己的 DSH |
| 壳的作用 | 产品本体(财税工作台就在壳里) | ★ 零门槛分发形态(只为「客户没有 DSH」这一种情况存在) |
| 壳里有业务代码吗 | 有 | ★ 一点都没有(壳只做:起窗口 / 起侧车 / 随包带 profile) |
★ 所以「从 003 搬什么」要重新划:
| 搬不搬 | 内容 |
| ❌ 不搬 | 财税业务代码(专家库 / 客户空间 / 积分 / 归户)、财税种子数据、财税内部路径 |
| ⬇️ 搬(后置,进 apps/shell) | Tauri 壳骨架(003-caishui-v2/002-桌面端-Tauri/):窗口、侧车编排、CREATE_NO_WINDOW、显式 DSH_HOME、profile 随包 |
| ⬇️ 搬(约定照抄,代码重写) | DSH 插件的打包/构建约定(cordis.patch.yml 写法、dsh.client 声明、closure-factory bundle、build-client.mjs 的 MODULES 登记纪律) |
| ✅ 抄设计不抄代码 | 003 最后优化的客户空间左右分栏(左侧列表 + 右侧工作区)—— 见下方 §三 |
一、★★ 一个必须先说清的前提:插件要有宿主
「客户从插件市场装插件」的前提是 —— 客户已经有一个 DSH。三种情况:
| 客户情况 | 谁提供宿主 | 我们交付什么 |
| 已有 DSH(官方 Web / 自建部署) | 客户自己 | ★ 只交插件包(主路径) |
| 没有 DSH,但会折腾 | 客户自己下载/自起 DSH | 插件包 + 安装引导 |
| 没有 DSH,且不懂技术 | 我们 | 才轮到 apps/shell(后置) |
⇒ 壳不是「客户端版本」,是「零门槛分发形态」。 它的存在不改变插件为主这件事。
⇒ ★ 由此得出一条硬纪律:apps/shell 里不得出现任何 083 业务代码。壳只做三件事 —— ① 起窗口 ② 起 DSH 侧车(profile 随包) ③ 把 DSH 地址给 WebView。
业务全在 packages/plugin- 里。 这条一旦破,插件就不能独立分发,整个生态入口(R1/R2/R7)全废。
二、目录结构
山海开铺插件仓/ ← 本目录(2026-10-04 定名 · 原名「客户端」) ├── README.md ← 本文件(项目定位 · 先读) ├── contracts/ │ ├── README.md 契约层的用法与升版流程 │ └── v1.1/ ★ 契约的机器可读版(从 007 基线落下来的单一事实源) │ ├── errors.json 14 条错误码 + 中文文案 + HTTP 状态 + detail 形状 │ ├── sse-events.json SSE 事件名 + 字段 + 顺序 + 渲染规则 + 恢复接口 │ ├── features.json /me 的 features 六位语义 + 读法 wisdomTeam ?? expertTeam │ └── seats.json 三个可替换位 + 签名位(不可替换) ├── packages/ │ ├── contract/ ★ 契约类型的唯一出处(TS) │ │ ├── tsconfig.json → lib/(ESM,给 host half) │ │ ├── tsconfig.cjs.json → lib-cjs/(CJS,给 client bundle 内联;见 §四 D4) │ │ └── src/{index,errors,sse,models,account}.ts │ │ └── generated.ts ★ 机器生成(由 contracts/v1.1/.json),禁手改 │ ├── plugin-platform/ ★ 场地插件(主推 · 上市场) │ │ ├── package.json dsh.bundle / dsh.client(+ 上市场要的那一整套字段) │ │ ├── cordis.patch.yml patch 层(插入插件行) │ │ ├── locale/{en,zh}.json ★ 宿主里的显示名/描述(缺了会显示成裸包名) │ │ ├── icon.svg ★ 插件列表里的图标(官方上限 256 KiB,只认 SVG/PNG/JPEG/WebP) │ │ ├── tsconfig.json host half(★ 不含 DOM lib) │ │ ├── tsconfig.client.json client half(含 DOM + JSX;★ module 必须是 CommonJS) │ │ └── src/ │ │ ├── index.ts host half(④ 适配层对接 / 场地能力) │ │ └── client/ │ │ ├── index.ts slot 注册(main + sidebar.panellist 成对) │ │ ├── panel-id.ts ★ id/key 唯一出处(D3) │ │ ├── PlatformPanel.tsx 主面板(容器宽度断点 + 组装 + [data-kaipu-run] 判据边界) │ │ ├── PlatformPanelIcon.tsx 侧边栏入口图标 │ │ ├── Intro.tsx ★ 首屏:标题栏 + 「怎么用」卡(三步 / 术语 / 判定图例) │ │ ├── LeftPane.tsx C-1 总台(执行方 + 场景) │ │ ├── RightPane.tsx C-2 运行视图 / 报告 │ │ ├── run-reducer.ts ★★ 纯函数归约器(事件 → 视图,与数据来源无关) │ │ ├── ErrorSurface.tsx ★ 错误面(只显示译后文案;两个改道码不当错误渲染) │ │ ├── copy.ts ★ 三条必须显示的约束(契约外,出处已注明) │ │ ├── theme.ts ★ 判定配色 + 字号阶梯 FS(改字号只动这一处 · D6) │ │ └── mock/data.ts ★ 演示数据(确定性;界面必须明示是 mock) │ └── plugin-wisdom/ ★ 智囊团插件(可装卸 · INV-17 判据样本) │ └── (与 platform 同构) ├── market/ ★ 投稿件(提 PR 时只加这一个文件) │ └── <owner>__<repo>--packages-<pkg>.yml 条目:url/name/category/description/tarball ├── apps/ │ └── shell/ ⏳ 后置:零门槛分发形态(当前只有 README 说明) ├── tools/ ★ 判据工具(每个对应一条可自证的判据) │ ├── plugin.mjs ★ 插件生命周期(装/卸/启/停/升/回滚/preflight/sync) │ ├── build.mjs 构建编排:契约 → 各插件 host → client → bundle(判据 #6) │ ├── build-client.mjs client bundle 组装(closure-factory · 拓扑排序) │ ├── gen-contract.mjs 契约生成 + --check 漂移断言(判据 #3) │ ├── clean-scan.mjs 干净版扫描(判据 #2) │ ├── check-decoupling.mjs 解耦断言(判据 #5 · A-1/A-2 静态) │ ├── check-package.mjs 分发断言(判据 #7 · 留意1 第 3 条) │ ├── check-panel-order.mjs ★ 侧边栏位置礼仪(D10 · 插件不许抢宿主位置) │ ├── check-lifecycle.mjs ★ 生命周期验收(38 项 · 沙箱内跑) │ ├── check-fault-isolation.mjs ★ 故障隔离验收(23 项 · 真起 DSH 两次) │ ├── market-entry.mjs ★ 投稿件生成 + 官方 9 条规则复刻(--self-test 19 项负例) │ ├── check-market-ready.mjs ★ 包侧「上架就绪」断言(--self-test 21 项负例 · --release) │ ├── check-error-copy.mjs ★ 错误码文案判据(Step 7 · 期望值读自契约 JSON,不抄第二份) │ ├── check-verdict-fallback.mjs ★ 未知判定兜底可达(行为级 · 真跑编译产物) │ ├── check-tools-syntax.mjs ★ 工具语法自检(防「注释提前终止容器」那类坑) │ ├── link-dsh-peers.mjs ★ 把宿主 peer链进插件 node_modules(开发前置 · 需 KAI_DSH_REPO) │ ├── setup-dev-profile.mjs 开发环境一键就位(plugin.mjs 的薄封装) │ └── probe/ │ ├── panel-probe.mjs ★ 界面探针(CDP · 空 DOM 自愈 + 现场取证) │ ├── live-probe.mjs ★★ 数据源通路(live / unreachable —— 连不上时不许假装连上) │ ├── run-view-probe.mjs ★ 运行视图判据探针(Step 4/6 · 28 项字面量断言) │ └── copy-probe.mjs ★ 文案与约束判据探针(Step 7 · 23 项字面量断言) └── dev/ ⏳ 本地开发用 DSH_HOME + 沙箱 + 上架预览(gitignore)
★ 目录名:005-083-山海开铺项目/山海开铺插件仓(2026-10-04 定名)。
原名「客户端」与实际内容(插件)不一致 ⇒ 已改。
理由:名字是给未来的人看的 —— 叫「客户端」会让人以为这是客户端应用,而不是插件;而「插件为主、壳为辅」正是本仓的定位(§〇)。出处:小D 评审 008 §三 留意 3。
二·补、★ 评审三处留意点的处置(2026-10-04)
留意 1 · packages/contract 与插件独立分发的关系 —— ✅ 已定并写清
问题:插件要上 DSH 插件市场,客户装插件时 contract 的依赖怎么办?
定论:
★ contract 是「开发期类型契约」,不随插件分发。运行时不需要它。
| 依据 | 说明 |
| 编译期 | contract 里只有 interface / type / const 字面量表 —— 没有运行时逻辑(errors.ts 的翻译函数会编译进调用方产物) |
| 构建期 | 类型在 tsc 阶段被擦除并内联;const 表被 bundler 内联进 client bundle |
| 运行时 | 插件产物里不存在 @shanhai/kaipu-contract 这个包 —— 它是 dependencies 里的构建期依赖,不是运行期依赖 |
⇒ 要做的三件事:
| # | 动作 | 状态 |
| 1 | 把 @shanhai/kaipu-contract 从 dependencies 移到 devDependencies(构建期依赖的正确声明) | ✅ 已做 |
| 2 | 打包产物自带类型与常量(bundler 内联)⇒ 插件包零外部依赖(只留 @deepseek-ai/cordis 作 peerDependencies) | ⏳ Step 2(要真产物才能证) |
| 3 | 加一条分发断言:插件 tarball 里 grep 不到 @shanhai/kaipu-contract 的 import ⇒ 接进 clean-scan 或新增 check-package.mjs | ⏳ Step 2 |
★ 附带好处:零外部依赖是「能上插件市场」的硬条件 —— 市场不会替你解决依赖树。
留意 2 · plugin-platform 未来可能要拆 —— ✅ 已记演进方向
现在不拆(当前它确实是「一件事:提供场地」)。拆的触发条件与去向写在 packages/plugin-platform/README.md 的「未来演进方向」段(编排 / 门禁 / 留痕 / 报告面各自的拆分判据)。
★ 纪律:按「触发条件」拆,不按「感觉变大了」拆 —— 没到触发条件就拆,只会多出四个包互相 import。
留意 3 · 目录名不一致 —— ✅ 已改名(见上方 §二 目录名)
三、★ 关于「客户空间左右分栏」(003 最后那版 UI)
阿舟问过:003 最后优化的内侧竖栏设计(客户空间左右分栏)能不能参考?
能,而且正是插件面板该有的形态 —— 理由:
1. 插件面板天然是「嵌在宿主里的一个区域」,不是全屏应用。 它可能挂在侧边栏(很窄)、 主区域(很宽)、或悬停卡(更窄)。左右分栏 + 弹性伸缩是唯一天然适配三档的布局。
2. 003 那版已经实测过「左列表 / 右工作区」在手边操作上更顺(用户当时的原话是「漂亮」)。
3. 但只抄设计,不抄代码 —— 003 那份耦合了财税业务(客户 / 任务 / 归户 / 拖拽上传), 083 要的是通用层(铺子 / 场景 / Agent / 报告)。
⇒ 落到本仓:plugin-platform 的面板 = 左侧(场景列表 / 运行记录)+ 右侧(运行视图 / 报告); 窄挂载自动折叠左栏(断点由容器宽度决定,不由窗口宽度)。
四、★ 三条从 003 用血换来的纪律(写在这里,免得后人再踩)
| # | 纪律 | 003 的代价 |
| D1 | list 座位注册必须给 id —— 漏了会让 apply 抛错 ⇒ 整个 client bundle 加载失败 ⇒ 整站白屏 | 2026-10-04 实测 |
| D2 | package.json 的 dsh.client.inject 填「包名」(模块图边);client half 导出的 inject 填「cordis 服务名」 —— 两套词表,填错会卡 pending (waiting for services: …) | 2026-10-01 实测 |
| D3 | main 面板的 key 必须等于 sidebar.panellist 的 id —— 不等就是「点了没反应」 | 源码级证据 |
★ 另有两条不能违反的(来自 004-客户端插件化 §C): 插件不直连模型/服务端域名(一切走宿主适配层)· 插件不越受管根。
D4 · ★★ 内部包内联:client 侧产物必须是 CJS(2026-10-05,用一次「假的构建成功」换的)
背景:Step 4/6 要让面板直接用契约常量(VERDICT_TONE / lampKey / SSE_EVENT)。
契约层存在的唯一理由就是「这些常量只有一个出处」,所以不能抄一份到客户端(那是漂移)。
⇒ 只能把契约包内联进 bundle。
踩到的坑(两级):
| 级 | 症状 | 根因 |
| 1 | 内联后产物里留着一句 require("@shanhai/kaipu-contract") | 宿主 closure 的 require 只服务宿主模块表 ⇒ 浏览器拿到 undefined |
| 2 | 内联进来了,但浏览器报 SyntaxError: Unexpected token 'export' ⇒ 整站不渲染 | 契约包产物是 ESM(module: ESNext),而 client bundle 是 CJS closure |
★ 级 2 最难查的地方:构建是绿的。 bundle 文件照样生成了,check-package 也过,只有浏览器控制台一句 import failed。而且因为 DSH 的 client 启动是全或无(D1 同源),症状是整个界面不渲染 —— 看起来像「插件把宿主搞挂了」。
⇒ 两道防线(都已落地,别再退回去):
1. 契约包产出两态:lib/(ESM,给 host)+ lib-cjs/(CJS,给 client 内联)。
见 packages/contract/tsconfig.cjs.json。tools/build.mjs 两个都跑。
2. build-client.mjs 的 ESM 残留闸门:任一模块体行首出现 export / import 就 exit 1,并直接说明修法。★ 这条闸门实测过会失败(把 lib-cjs 挪走后确实报错并指到 @shanhai/kaipu-contract/index.js:15 export from './generated.js')。
配套判据(check-package.mjs A3)也改成了正向断言:「插件自身产物若在运行时引用了内部包,bundle 里就必须含有它的内联模块」。
—— 老版本断言的是「产物里不出现 @shanhai/kaipu-contract」,加了内联之后它变成假阳性 (字符串出现在模块注释里)。教训:「没有某个字符串」证明不了因果关系。
D5 · ★★ 界面探针的三条纪律(2026-10-05,一天之内被打到两次)
界面判据(tools/probe/.mjs)比静态判据脆,因为它跑在一个有状态的页面上。
今天连改两轮界面,探针连报「失败」,两次都不是产品坏了,而是探针自己不成立:
| # | 纪律 | 当天怎么被打到的 |
| D5-a | ★ 判据必须可复跑 —— 不许假定前态 | run-view-probe 第①段假定「刚打开面板 = 默认选中第一个场景」。第一遍通过;第二遍面板还停在上一次跑完的场景 ⇒ 7 条断言误报。修法:显式 pickScene('开铺审计 · 标准')。copy-probe 的约束② 同理(变更记录按场景取,不选场景就读到空) |
| D5-b | ★★ 断言要读「判据边界」区域,不读整页 | 首屏引导卡里有四类判定的图例(它必须在那儿)。若 R3 断言读 body.innerText,图例就让「运行视图里出现了 ⚡有条件」恒真 ⇒ 空断言。修法:运行视图加 data-kaipu-run,断言只读它;并且给这条边界加了自证断言(!runText.includes('第一次用?')),实测把它挪进去会精确报 1 项未过 |
| D5-c | 探针对象每次重建,不做「注入过就跳过」 | 改了探针加了 setIntro(),页面里还是上一版对象 ⇒ setIntro is not a function(不是断言失败,是崩溃) |
★ 三条同一个病根:判据要能被证伪,而不是「跑起来不报错」。
D5-b 尤其危险 —— 它不会失败,只会悄悄变成永远通过。
D6 · 字号要收成阶梯,不要各处写死(2026-10-05)
面板里原本散着 10 / 11 / 12 / 13 / 14 五个字号,实测反馈是「字体有点小、第一眼不知道怎么用」。
根因不是某一处写小了,而是没有阶梯 ⇒ 想整体调大就得满文件找数字,必然漏几处。
⇒ theme.ts 导出 FS(tag 12 / small 13 / base 14 / title 15 / heading 17)与 LH。
改字号只动这一处。 用 px 不用 rem/em:面板嵌在宿主里,root 字号不由我们控制。
★ 顺带一条:字号放大后左栏宽度与折叠阈值必须一起动(240→260 / 560→640)。
只改字号不改宽度,症状是「看起来够宽,但左栏每行都挤成两行」。
D10 · ★ 第三方插件的 order 要排在宿主内置项之后(2026-10-05 用户实测反馈)
症状(阿开报的):一刷新,我们的插件按钮就跑到最上面。
根因(宿主源码 + CDP 实测双证):
// packages/client/ui-sidebar/src/client/index.ts:50
.sort((a, b) => a.order - b.order) // 升序;同值看注册顺序
宿主内置项的 order 区间:ui-plugin-manager(插件)0 · ui-schedule(任务)10 · ui-agent-preset 20。
我们原来写的是 order: 0 ⇒ 与「插件」同值 ⇒ 实测排到了它前面:
修前:… 全局面板 · 开铺 · 开铺 · 插件 · 智囊团 …
修后:… 全局面板 · 插件 · 开铺 · 开铺 · 智囊团 …
纪律:第三方插件一律取 > 20 的值(我们定 30 / 35,留空隙给后来者)。
理由不是审美:插件按钮是宿主自带的,用户已有肌肉记忆;插到它前面 = 替宿主改布局。
★ 附带一条:改一个插件的 order 要回头看同一套插件的其它包 —— plugin-wisdom 原本 order: 10(注释写着「排在场地 order 0 之后」),场地改 30 后它就反超了。
「相对顺序」是成套的,不是单点的。
判据:node tools/check-panel-order.mjs 断言两条:① 每个插件 order > 20(宿主机内置区间上界)② 我们自己的两个 order 不许同值(同值 ⇒ 顺序看注册运气)。
★ 已做负例验证:把 order 改回 0 ⇒ 判据精确报 1 项未过、exit=1。
五、判据(可自证 · 不靠嘴)
Step 1 · 建仓与包结构
| # | 判据 | 怎么验 | 实测结果(2026-10-04) |
| 1 | 目录树与本 README §二 一致 | find . -type f 对读 | ✅ 逐条对上 |
| 2 | 干净版扫描通过 | node tools/clean-scan.mjs | ✅ FAIL 0 / WARN 12(全在 .md,是「说明不搬什么」时必须提的词) |
| 3 | 契约单一事实源成立 | node tools/gen-contract.mjs --check | ✅ 无漂移:errors 14 条 / SSE 事件 9 个 / 判定 4 类 / features 7 位 / 角色位 4 个 |
| 4 | 契约层类型可编译 | tsc -b packages/contract | ✅ 0 错误 |
| 5 | plugin-wisdom 可独立摘除(静态) | node tools/check-decoupling.mjs | ✅ 5 项断言全通过(A-1 / A-2) |
Step 2 · 插件真的能跑起来
★ 范围修正(重要):原七步的 Step 2 是「Tauri 壳 + 侧车」—— 那是壳为主思维下的首步。
定位切到「插件为主」后,「跑起来」应先证插件能跑(装进一个真 DSH 见到界面),壳留到「零门槛分发」阶段(apps/shell)。这不减少工作量,只是把验证顺序摆正。
| # | 判据 | 怎么验 | 实测结果(2026-10-04) |
| 6 | 构建一条命令到底 | node tools/build.mjs | ✅ contract + 2 插件 × (host tsc + client tsc + bundle) 全绿;platform 9.4 KB / wisdom 5.3 KB,各 4 模块、无环 |
| 7 | 产物可独立分发 | node tools/check-package.mjs | ✅ 14 项断言全过(见 §二·补 留意1):契约已内联、裸 require 只有 react / react/jsx-runtime、closure-factory 形态正确 |
| 8 | 真 DSH 认得这两个插件 | 起 DSH web,看页面里的 client 模块清单 | ✅ 清单里出现 @shanhai/kaipu-platform/client.js,@shanhai/kaipu-wisdom-team/client.js |
| 9 | ★ 界面上真的有(侧边栏 + 面板) | node tools/probe/panel-probe.mjs --expect=开铺,智囊团 | ✅ 两个入口都在(aria-label/title);点「开铺」⇒ 左栏「场景 / 运行记录」+ 右栏「运行视图 / 报告」都渲染(左右分栏生效) |
| 10 | ★★ INV-17 动态证据(卸掉智囊团 ⇒ 场地仍可用) | --drop=wisdom 重建 profile → 重启 → --expect=开铺 --absent=智囊团 | ✅ 侧边栏「智囊团」消失、「开铺」仍在;面板左右栏仍渲染;模块清单里 wisdom 为 false |
★ 判据 10 才是这个项目真正的架构判据 —— 静态断言(判据 5)只能证明「代码层面没依赖」,只有真卸了再启一遍才能证明「绕不开的场地没人来;可替换的东西才卖得出去」(001-A §3.2)。
★ 判据留档(截图,2026-10-04 实测):docs/evidence/
· step2-09-侧边栏+面板.png —— 两个入口 + 点开后的左右分栏面板
· step2-10-INV17-卸掉智囊团后场地仍可用.png —— 卸掉后只剩「开铺」,面板照常
Step 3 · 装卸机制 + 故障隔离
★ 状态是唯一事实源:dev/dsh-home/plugins.state.json。profile 的 bundles 与 node_modules 链接都是它的投影,由 sync 幂等重算 —— 因为「两个落点各改一半」必然不一致,而不一致的症状是「清单说有、界面没有」,不报错、只诡异。
3a · 六个动词(tools/plugin.mjs)
| 动词 | 行为 | 判据 |
| install <dir> --source=user\|enterprise | 真拷贝到 plugins//<短名>/(内置走仓内包,不拷不删) | ✅ |
| enable / disable | 改 state → sync:bundles 与链接同时摘/挂 | ✅ 停用后链接断开(真停用,不是「列表隐藏」) |
| uninstall | 代码移除 · 数据保留(plugins-data/);--purge-data 才清 | ✅ AC-C03 |
| upgrade <id> --to <dir> | 就地替换(安装位置稳定)· 自动留回滚点 | ✅ AC-C07 |
| rollback <id> | 从回滚点就地还原 · 回滚本身也可回滚 | ✅ |
| health / preflight / sync | 清单健康检查 / 启动前闸门 / 幂等重算 | ✅ |
38 项断言全绿:node tools/check-lifecycle.mjs (跑在 dev/.lifecycle-sandbox/,不污染真实 dev 环境,可重复跑)
3b · 兼容性:先拒绝,再运行(A3)
dshRange / hostApiRange 不满足 ⇒ 拒绝安装/启用,给可读原因,不留半个安装。
另加三条同类拦截:client bundle 非 closure-factory 形态 · 声明了运行期 dependencies(违反零外部依赖)· 有 exports["./client"] 却没声明 dsh.client.platform(DSH 会静默不加载浏览器侧 —— 这类「安静失败」必须装前拦掉)。
3c · ★★ 故障隔离:抓到一条上游限制(AC-C02)
实测取证(2026-10-04):把一个插件的 client bundle 改坏再加回去启动,页面上只剩一行: HARNESS Failed to load plugins … 1 entry did not activate … import failed 整个 web shell 不渲染 —— 真白屏;其他插件也一起不可用。
⟹ DSH 的 client 模块启动是「全或无」的,没有插件级错误边界。
这是上游限制(004-客户端插件化 §A7 早已预警「必须补错误边界」),不是本仓的 bug。
又因「零宿主改动」是硬纪律(插件要能独立分发 ⇒ 不能去改 DSH 的 loader), ⇒ 缓解只能落在我们这层:
| 手段 | 做法 | 判据 |
| 启动前闸门 | plugin.mjs preflight —— 任何启用插件不健康就 exit≠0,并警告「不要直接启动」 | ✅ |
| 坏插件熔断 | preflight --auto-heal —— 自动禁用坏的,保证「处置后一定起得来」 | ✅ |
| 装机期拦截 | 3b 那四类(形态 / 依赖 / 声明缺失 / 兼容性)在装进去之前就拒 | ✅ |
23 项断言全绿:KAI_DSH_REPO=<DSH 仓库> node tools/check-fault-isolation.mjs (A 三插件都好 → B 写坏 → C1 取证上游白屏 → C2 熔断后宿主照常、其他插件照旧)
★ 留档:docs/evidence/step3-03-熔断后宿主正常.png
⚠️ 复跑注意(环境级,非本仓问题):本验收要反复起停 DSH,在本机有两种「看起来像插件坏了」的干扰,都已定位并写进 skill dsh-plugin-mount:
| 现象 | 根因 | 处置 |
| atomic-write: timed out … .lock,且 stack 里有 node-safe-delete-shim.cjs | ★ 宿主的删除 shim 接管了 fs.rm,而 DSH 的 atomic-write 正是用它摘锁 ⇒ 锁摘不掉 | 与环境删除额度有关 ⇒ 换一个新会话再跑;别再怀疑插件 |
| 同上报错,但 stack 里没有 shim | 上次被强杀的实例留下 .lock | 清 DSH_HOME 与 profiles// 下的 .lock |
★ 脚本本身已做结构性加固:三个阶段的 DSH_HOME 彼此独立(段间零共享) ⇒ 从根上消掉「跨段 lock / 端口 / 半写状态」这一类争用。
Step 4/6 · 面板接真契约形状的数据(2026-10-05)
做的不是「塞点假数据看界面」,而是把契约的 renderRules 变成界面上可断言的字面量。
新增文件(全部在 packages/plugin-platform/src/client/)
| 文件 | 职责 | 为什么单独一个文件 |
| mock/data.ts | 契约形状的演示数据 | ★ 刻意确定性(不用 Math.random/Date.now)—— 带随机数的 mock 只能证明「界面没崩」 |
| run-reducer.ts | ★★ 纯函数归约器:事件序列 → 视图状态 | 归约只做归约。事件从哪来(mock / 真 SSE / 断线补拉)与它无关 ⇒ 接真接口时它不用改 |
| LeftPane.tsx | C-1 总台(执行方 + 场景) | — |
| RightPane.tsx | C-2 运行视图 / 报告 | — |
| theme.ts | 判定配色(实底徽标) | 面板可能挂在浅色/深色/悬停卡三种底色上 |
判据:node tools/probe/run-view-probe.mjs --port=3093 --cdp=9226 —— 28 项,实测全绿
| 契约条款 | 界面上的字面量断言 |
| R2 按轮分段、回炉可见 | 「第 1 轮」「第 2 轮」都在,且第 2 轮的 reason = 「⚡有条件回炉」 |
| R3 四类判定可区分且可见 | 四类全部出现过:✅通过 / ⚡有条件 / ❌驳回 / ⛔拒收(实底徽标) |
| R4 审核面口径固定显示 | 「本次参与审核面」「未参与审核面」「裁剪依据」都在,被裁剪的审核面名可见,且面板内 数量 = 0(不许做成折叠的次要信息) |
| R5 断开 ≠ 取消 | 点「停止接收」⇒ 显示「已停止接收」+「服务端仍在算完并落 lamp_runs」;全文没有「已取消」 |
| A-3 待接入 | agentId: null 的维度显「待接入」;零接入场景给出「全部未接入执行方」+「这不是故障」 |
| 演示数据必须明示 | 面板顶部固定挂「演示数据(mock)」徽标 + 一句「不是真实运行结果」 |
两条归约器的契约纪律(写在 run-reducer.ts 注释里)
- [R1] 归组键 = (round, lamp)(用契约的 lampKey(),不本地拼字符串); round_start 缺失时用事件自带的 round 兜底分组,并标记 degraded ⇒ 界面提示「未收到轮次开始事件」,而不是假装它是正常的一轮。
- [R6] 轮数不得推断 ⇒ 归约器只反映事件里说的,永不自己造一个轮次。
截图留档:docs/evidence/step6-01-运行视图-轮次分段.png · step6-02-契约形状演示数据-两轮+裁剪.png
Step 7 · 错误码文案 + 三条必须显示的约束(2026-10-05)
判据分两层,因为这两件事不是一类:文案表是「映射对不对」(静态就够),约束是「界面上真的说了没有」(必须看界面)。
层 1 · 静态:node tools/check-error-copy.mjs
- 14 条码逐条翻译,期望值读自 contracts/v1.1/errors.json ——本工具里不抄第二份文案表(抄一份 = 多一个事实源 = 改契约时这里悄悄过期而「测试全绿」)。
- 裸 code 外泄检查:译后文案里既不含 code、也不含 snake_case 形态的裸码(001 §4.2 纪律)。
- 兜底:未知码 / undefined → 兜底文案,且不回显那个未知码。
- isReroutableError() 与「契约里写了 clientAction 的码」完全一致(不许各说各的)。
- 错误体解析容错:代理返回 HTML / 空体 / 畸形体都不许抛。
- ★ 提醒:invalid_request / unauthorized 两条的 textStatus 是 pending-confirmation (文案是产品口径,不是技术细节)⇒ 提 PR / 对外前需星月确认。
层 2 · 界面:node tools/probe/copy-probe.mjs —— 23 项,实测全绿
| 断言 | 为什么这么断 |
| 14 条码各自走一遍真实渲染路径(点脚手按钮 → 读真实渲染出的错误面) | 「表里有 14 条」证明不了「接上了」;逐个触发才能被证伪 |
| 两个改道码不出现错误框([data-kaipu-error] 为空) | 契约 clientAction 明文:不弹错,另走一条路 |
| duplicate_request 消费到 detail.poll(data-kaipu-poll 属性可读) | 只断言「有个按钮」证明不了它读了 detail |
| 裸 code 不在可见文字里(只在 data- 属性里) | 属性给判据用,用户看不到 |
三条必须显示的约束(001 开发包 §6.4)落点
| # | 约束 | 落点 | 判据 |
| ① | 报告无签名 ⇒ 醒目 | UnsignedBanner(右栏顶部) | 文案逐字一致 + font-weight ≥ 600 + 实测警示色 rgb(220,38,38) |
| ② | 角色位变更 ⇒ 记录 + 原因 | SeatChangeBlock(报告下方) | 有标题、每条带「原因:」、显示 from → to |
| ③ | 超时释放 ⇒ 过期不候 · 可重新预约 | reservation_expired 的错误面 | 逐字显示 + 「不用重新填」 |
★ 未签名那条恒显示而且是刻意的:签名只能由服务端给出,演示数据不来自服务端 ——显示「已签名」就是撒谎。(与 mock 的「必须明示」同源。)
★ 这一轮抓到的真缺口:第一版接线没把 detail 传给错误面,于是两个改道码只会说一句「这一单已经在跑了,别急」、用户没有任何出路。
契约里那句 clientAction 是「按 detail.poll 切到查询接口」——不传 detail 等于那句没落地。判据点出来之后才修掉(mock/data.ts 的 MOCK_ERROR_DETAIL,形状照抄契约 detailShape)。
一处刻意的设计:三条约束的文案目前只在 001 开发包 §6.4,尚未进 contracts/v1.1。
按本仓纪律不单方扩契约 ⇒ 暂由客户端 src/client/copy.ts 持有并标明出处, 建议下一版契约把它们收进去(否则每个客户端都要各自抄一份 —— 正是漂移的起点)。
Step 8 · 可读性:字号阶梯 + 首屏引导(2026-10-05)
触发:实测反馈两条 —— 「字体有点小」「页面第一眼不知道怎么用」。
两条都不是 bug,是入口与可读性的问题;但对"这插件能不能被客户独立用起来"是硬伤。
改了什么:
| 项 | 改法 | 为什么 |
| 字号 | 收成 FS 阶梯(tag 12 / small 13 / base 14 / title 15 / heading 17),全部 56 处引用它 | 原来散着 10/11/12/13/14 五个值;没有阶梯 ⇒ 想整体调大必然漏几处(见 D6) |
| 首屏 | 常驻标题栏(「山海 · 开铺 · 场地 / 开铺审计的运行台」)+ 默认展开的「怎么用」卡,一键收起 | 第一眼是一屏结论性信息(演示数据 / 未签名 / 第 1 轮),却没有一句"这是什么、我该看哪几处" |
| 引导内容 | 三步(选场景 → 看逐轮 → 拉到底看结论)· 四个词(执行方 / 场景 / 维度 / 待接入)· 四类判定图例 | 术语与判定符号不解释,用户对不上 |
| 左栏 | 区块标题加人话副标题 | 原来只有「执行方」「场景」两个没有谓语的标签 |
| 空态 | 「还没选场景」时给三条说明,不再是一句"从左侧选一个场景" | 空态是唯一"用户一定会停一下"的位置 |
| 布局 | 左栏 240→260;折叠阈值 560→640 | 字号放大后 240px 装不下;只改字号不改宽度 ⇒ 每行挤成两行 |
判据(tools/probe/run-view-probe.mjs 第 ⓪ 段 · 12 条):
| 断言 | 说明 |
| 标题栏/三步/术语/图例都在 | 首屏真的解释了这是什么 |
| 引导卡可收起(收起后从 DOM 消失)且不动主内容 | 说明是说明,不霸占界面 |
| 可再次展开 | 不是一次性的 |
| ★★ 判据边界成立:运行视图文本里不含引导内容 | 这条是 D5-b 的自证 —— 没有它,R3 那几条会被图例污染成恒真 |
| 收起引导后运行视图照旧 | 收起不误伤 |
实测(同一份探针连跑两遍都必须全绿 —— D5-a):
node tools/probe/run-view-probe.mjs --port= --cdp=<c> # 48 项(含引导 12 项)
node tools/probe/copy-probe.mjs --port= --cdp=<c> # 23 项
字号的落地用 computed 样式核对(不靠"我看着像大了"):面板标题 17px · 场景名 17px · 执行方/轮次 15px · 引导正文/维度行/未签名提示 14px · 徽标 12px。
另加一条排版回归:面板内 scrollWidth > clientWidth 的元素数 = 0(首次实测 3 处,minWidth:0 + overflowWrap 修掉)。
★ 留档:docs/evidence/step8-01-首屏引导-放大字号.png · step8-02-收起引导-运行视图.png
Step 9 · 契约 #17 消费 + detail 补全(2026-10-05 · 依星月 012 答复)
触发的三件事(都来自星月的逐条答复,不是我猜的):
| # | 事 | 依据 |
| 1 | unauthorized 文案「过期」→「不管用了」 | 星月 012 §2.1:401 有无/过期/非法三种成因,只写"过期"会让"令牌被判非法"的用户反复重领还是失败(文案与实际成因不符 = 让人白试) |
| 2 | ★ 补 not_checked_in.availableAt | 星月 012 §5.2 给了 detail 全表 —— 我读完契约两遍都没发现少一个键 |
| 3 | ★ 契约 #17 消费:场景按场合分组 + 推荐 + 「未归类」 | 星月 012 §四 答"消费",并给三条约束 |
落点:
| 件 | 改了什么 |
| contracts/v1.1/errors.json | 文案(textSource 立为 <出具方>-<编号> §<节> 格式)· detailShape 补 ISO8601 · 加 $gate:本表是客户端侧副本,正本在服务端 |
| packages/contract/src/models.ts | SceneCategory / SceneRecommendation(新)· SceneCard.category · ScenesResponse.categories/recommendations |
| ErrorSurface.tsx | availableAt → 「可进场时点:…」· ★ 只格式化绝对时点,不算倒计时 |
| LeftPane.tsx | groupScenes()(纯函数)· 分类分组 · 推荐位 · 「未归类」单列 |
判据(新增 14 条,其中 3 条是反向对照):
| 断言 | 为什么这么断 |
| availableAt 渲染出「可进场时点」+ 格式合法 | 证明第三个 detail 键真被消费 |
| ★ 同组件的另一条改道码(duplicate_request)不显示它 | 这才证明它由 detail 驱动,而不是恒显示 |
| ★「空分类不出」:响应里没有的分类,界面绝不自己造 | 契约保证空分类不出 ⇒ 客户端不许自作主张 |
| ★「未归类不藏」:未归类的场景真的列在组里(不是空标题) | 契约点名"不藏" |
| ★★ 禁用词:全文不含「热门 / 多数人 / 大家都在用」 | 星月 012 §4.1 点名:when 是"适合什么场合",「热门」需要统计依据,现在没有,写了就是编 |
★ 三条新纪律(今天各被打到一次):
| # | 纪律 | 怎么被打到的 |
| D7 | ★ 改契约 JSON 后必须重跑 build —— 只跑 gen-contract 不够 | 判据 import 的是编译产物(lib/)⇒ 只生成不编译,判据拿到旧文案,报「实际是旧文案」。闸门是对的,是我少跑一步 |
| D8 | ★ 截图脚本必须先开面板,且要自证「拍到了东西」 | 我的截图脚本漏了 open ⇒ 两张图一模一样,靠字节数相同才发现。⇒ 截图后必须比对(字节数 / 关键元素在场),否则「有截图」不等于「有证据」 |
| D9 | ★ 时点可显示,倒计时不可自己算 | availableAt 是绝对时点 ⇒ 格式化显示;「还剩多久」的基准必须服务端给(007 §5.1)。一旦自己 Date.now() 相减,客户端时钟偏差会变成一个看起来像真的的错数字 |
实测:运行视图 59 项(含 #17 11 项)· 文案与约束 27 项(含 availableAt 3 项)·契约无漂移 · 干净版扫描 FAIL 0(90 文件)· 两个界面探针连跑两遍全绿。
留档:docs/evidence/step9-01-契约17-按场合分组.png · step9-02-availableAt-可进场时点.png
一键复跑
静态(不需要任何服务)
node tools/build.mjs \
&& node tools/gen-contract.mjs --check \
&& node tools/clean-scan.mjs \
&& node tools/check-decoupling.mjs \
&& node tools/check-panel-order.mjs \
&& node tools/check-tools-syntax.mjs \
&& node tools/check-package.mjs
装卸 + 兼容性(沙箱内跑,不需要服务)
node tools/check-lifecycle.mjs
界面装载(需先起 DSH + 开 CDP 的浏览器,命令见 tools/probe/panel-probe.mjs 头部)
node tools/probe/panel-probe.mjs --expect=开铺,智囊团
故障隔离(真起 DSH 两次,约 2 分钟)
KAI_DSH_REPO=<DSH 仓库> node tools/check-fault-isolation.mjs
运行视图判据(Step 4/6/8 · 需先起 DSH + 开 CDP 的浏览器) ★ 连跑两遍都必须全绿 —— 判据不可复跑 = 判据不可信(D5-a)
node tools/probe/run-view-probe.mjs --port=3093 --cdp=9226
文案与三条约束判据(Step 7 · 同上)
node tools/check-error-copy.mjs # 静态:14 条码映射 + 兜底 + 裸码外泄
node tools/probe/copy-probe.mjs --port=3093 --cdp=9226
上架:投稿件(官方 9 条规则)+ 包侧就绪
node tools/market-entry.mjs --check
node tools/check-market-ready.mjs
上架工具自己也要能被证伪(一个不会失败的校验器等于没校验)
node tools/market-entry.mjs --self-test # 19 项负例 + 4 项防假阳性
node tools/check-market-ready.mjs --self-test # 21 项负例 + 3 项防假阳性
★ Step 4/6 不含:接真服务端。面板现在跑的是演示数据(界面顶部有徽标明示),归约器与两栏渲染已按真契约形状写,接真 SSE 时只需换事件来源。
上架轨(与上面七步并行 · 2026-10-05)
| 项 | 内容 | 状态 |
| A | 包元数据对齐市场/npm 要求(repository / license / keywords / locale / icon / publishConfig) | ✅ 完成 |
| B | ★ 字段真伪审计:清掉 3 个「DSH 不读却看着权威」的自造字段 | ✅ 完成 |
| C | 投稿件(market/.yml)+ 官方 9 条规则本地复刻校验 | ✅ 完成 |
| D | ★ 官方安装器端到端实测(dsh plugin --profile web add <tarball> ⇒ 宿主自动登记 ⇒ 真界面可用) | ✅ 完成 |
| E | 公开清单 G1(docs/公开清单-G1-v1.md)→ 我方审查 G2 → 决策人批 G3 → 仓转 Public | ⏳ G1 已出,等审查 |
| F | ★★ 提交收录 PR | ⛔ 仓是 Private ⇒ 现在提不了(CI 取不到 package.json、用户点 url 404) |
| G | 发 npm(让 install 命令从 tarball 升级成 add <包名>) | ⏳ 可选 |
当前状态
| 步 | 内容 | 状态 |
| 1 | 建仓 + 包结构 + 契约单一事实源 | ✅ 完成 |
| 2 | 构建管线 + 真 DSH 装载 + 一个服务一件事验证 | ✅ 完成 |
| 3 | 装卸机制 + 兼容性拒绝 + 故障隔离(含上游限制处置) | ✅ 完成 |
| 4 | 面板接真契约形状的数据(C-1 总台 + C-2 运行视图) | ✅ 完成(演示数据) |
| 5 | 壳(零门槛分发形态) | ⏳ 后置 |
| 6 | mock 全流程(round=2 回炉 + skippedDims + 四类判定 + 待接入 + 停止接收) | ✅ 完成 · 28 项判据全绿 |
| 7 | 文案接入:14 条错误码 + 三条必须显示的约束 | ✅ 完成 · 静态 + 界面两层判据全绿 |
| 8 | 可读性:字号阶梯 + 首屏引导(三步/术语/图例) | ✅ 完成 · 引导 12 项 + 可读性回归全绿 |
| 9 | 契约 #17 消费(按场合分组)+ detail 补全(availableAt)+ 文案改定 | ✅ 完成 · 新增 14 项(含 3 条反向对照) |
| 10 | ★★ 接真服务端(host 通道 + 令牌在 Node + 数据源开关 + 诚实空态) | ✅ 完成 · 真数据已到界面(见下方「接真接口」一节) |
| — | POST /scene/{id}/run 的 SSE 接进面板(链路已实测通,只差接线) | ⏳ 下一步 |
| — | C-9 协作记录(013 需求稿)· 契约位 + 只读页 | ⏳ ADR 已裁决(8 问)· 待「正本单一定位」 |
| 上架 | 投稿件 + 包元数据 + 官方安装器端到端 | ✅ 代码侧就绪,等 G1→G2→G3 |
接真接口(Step 10 · 2026-10-05)
架构:浏览器(client) → 宿主网关 → host half(Node,凭据只在这里) → kai-pu。
★ 为什么必须中转(两条,缺一都不成立): ① 技术上不可能直连 —— kai-pu 不发任何 access-control- 头、预检 OPTIONS 回 501(实测); ② 纪律不允许 —— 仓 §四「插件不直连模型/服务端域名」。
★ 附带收益:deviceToken 只活在 host 进程内存,浏览器永不持有凭据。
| 判据 | 怎么验 |
| 插件能激活 | DSH 启动日志不再出现 shanhai-kaipu-platform: failed to import |
| 真数据到界面 | node tools/probe/live-probe.mjs --port= --cdp=<c> --expect=live |
| ★ 连不上时不说谎 | … --expect=unreachable(同一条判据的另一种期望) |
| 运行视图 / 文案与约束未被破坏 | 另两个探针(它们会自己切到演示数据摆前提) |
| 工具语法 | node tools/check-tools-syntax.mjs |
★ 开发前置:host half 需要宿主的 peer(@deepseek-ai/dsh-typert-protocol)—— KAI_DSH_REPO=<DSH 仓库路径> node tools/link-dsh-peers.mjs(node_modules 在 gitignore 内)。
缺它插件会静默加载失败(DSH 只给一句 failed to import,不给原因)——plugin.mjs sync 会主动提示。
★ 联调地址不进包:包里的 cordis.patch.yml 恒为中性(baseUrl: '');联调地址写在 dev profile 覆盖层(plugin.mjs sync 生成,落在 gitignore 内)——否则对方撤掉联调面之后,真实用户会去连一个死地址。
五·补、★ 上架门槛逐条对账(2026-10-05)
官方 6 条门槛 —— 逐条实测
| # | 门槛 | 现状 |
| 1 | 市场没有上传入口,靠给 awesome-dsh-plugin 提 PR(只加 data/plugins/<slug>.yml 一个文件) | ⏳ 等建仓;投稿件已就绪 |
| 2 | 来源必须是清单收录的公开仓库 | ❌ 还没有公开仓库 |
| 3 | 仓库创建满 1 天 + dsh-plugin topic + 真实可用代码 | ❌ 待建 |
| 4 | 必须声明 dsh.bundle(只声明 dsh.client 不算插件) | ✅ |
| 5 | 建议声明 prebuilt tarball(省掉用户的 allowBuilds 授权) | ✅ 两条都声明了 |
| 6 | package.json 的 repository 必须指回该仓库(npm 映射的唯一依据) | ✅(占位符待换真值) |
三个只有逐行读官方源码才知道的结论
① ★ 我们自造了 3 个字段,DSH 一个都不读。 dsh.dshRange / dsh.hostApiRange / dsh.permissions —— 全仓零引用。DSH 只读 dsh.bundle / dsh.client / dsh.profile。
已全部移到 kaipu. 命名空间,并删掉 hostApiRange(它命名的是一条不存在的版本轴:没有独立于 DSH 的"宿主 API 版本",客户端插槽 API 随 DSH 一起发版)。
tools/check-market-ready.mjs 立了护栏:再往 dsh. 塞自造键就 FAIL。
理由抄自官方自己的话:「一个没人读的字段仍然对打开文件的人显得权威……拒绝这个键,才是让文件对它做的事保持诚实的方式。」
② ★ 官方的兼容闸门只认 peerDependencies 里名字为 @deepseek-ai/dsh / @deepseek-ai/dsh- 的项 —— 对我们永远放行。 我们不 import 任何 dsh- 包(与官方 UI 插件同构:注入的包放 devDependencies,peer 只留 cordis),所以分发侧目前没有官方兼容闸门。
将来 Step 6 对接服务端会 import dsh-api-,那时必须同步补 peer —— 官方闸门才真正生效。
③ ★ github: 路线对我们不适用,投稿件必须写 tarball。 本仓 .gitignore 忽略 lib/(构建产物)⇒ 走 github:owner/repo#path:/packages/x 装出来的包没有 lib/index.js、没有 lib/client.js ⇒ 加载失败。
声明 tarball(预构建 release 资产)把这条路绕开了:用户只是下载,不需要 git、不需要构建授权。
资产名故意不带版本号(.../releases/latest/download/kaipu-platform.tgz)⇒ 下次发版不会 404、不必改投稿件。(这条形态在官方目录里已有先例,不是我们发明的。)
六、下游文档(本仓的上游依据)
| 件 | 位置 | 作用 |
| 008-山海开铺-插件仓 | ../ | ★ 架构评审("一个服务只做一件事、通过接口通信")—— 结论符合;三处留意已处置 |
| 007-阿舟-契约工作基线-v1.1-merged | ../(083 文档目录) | ★ 我编码时的唯一对账依据 |
| 006-星月回复-QA裁决与咬合点处置 | ../ | Q-A 裁决 (A) + 契约增补 #13–#16 |
| 需求书本体/(001 / 001-A / 立项纪要) | ../需求书本体/ | 需求与验收编号的正本 |
| 004-客户端插件化(三件) | 同项目根下 004-客户端插件化/ | 插件化宿主能力 / 插件契约 / 安全边界 / 生命周期 |
| 002-DeepSeek小D-ADR审校-083 | ../ | D2 桌面端架构图(壳 + 侧车 + 服务端) |
| skill dsh-plugin-mount | 用户级 skill 目录 | 挂载方法论 + 白屏坑 + 座位契约 |
★ 路径纪律:本仓不写本机绝对路径(tools/clean-scan.mjs 会 FAIL)。
上面一律用相对路径,换机器不断。
山海不急,每一步都算数。*预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
shanhai-city-states/kaipu-dsh-plugin-release
山海・开铺 — DeepSeek Harness 的「场地」插件:多人会商审校,全程留痕。
相关插件 · 其他
模型破甲清洗HunYiSage/dsh-purge
⚔️ DeepSeek Harness 网络安全红队工具dsh-purge
★ 16,993已汉化DeepSeek 客户端
73
女娲蒸馏alchaincyf/nuwa-skill
输入名人名字,提炼其思维模型与决策方式供你调用
★ 37,308已汉化DSH
72
逆向分析桥接Fanqi89/dsh-rea
REA(Reverse Engineer Anything)MCP 桥接,用来把 REA 逆向工具接入 DSH 插件
★ 51已汉化DSH
72
语音女友beiyege-01/dsh-voice-ai-girlfriend
语音 AI 女友Voice AI girlfriend for DeepSeek Harness:Whisper…
★ 888已汉化DSH
71.6
红队越狱测试套件Minglink/dsh-infinite-gen-5
DeepSeek v4.1 flash 逆向工具无限五代 求 Star 收藏 ⭐欢迎大家提交项目的改进
★ 3,759已汉化DSH
71.4
协同办公空间dream-num/univer-workspace
一个让人类与 AI Agent 共同创作、协作和审阅的开源 Office 工作空间。
★ 2,269已汉化DSH
70.8
这是你的仓库?认领条目