dsh-loopx-plugin
loopx-project/loopxLoopX——面向长周期 Agent 的提供商中立、本地优先状态内核与控制平面:在 DeepSeek Harness 执行层之上持久化 Goal、Todo、门禁、证据、配额、恢复与交接状态;插件负责引导安装 CLI 与技能、准入有界的同会话续跑,并为精确绑定的工作循环提供本地 GoalBar。
★ 本仓主推件。上 DSH 插件市场。装了它,客户就有了"开铺的场地"。
场地插件 = 审计环境标准:编排对接 + 门禁 + 留痕 + 报告面。
它不含任何我方 Agent 资产(那是智囊团插件的事,见 ../plugin-wisdom)。依据:契约 §4.2「场地插件(核心):审计环境标准:编排 + 契约 + 门禁 + 留痕 + 签名 —— 优先上 DSH 插件市场」。
能力 · 期 · 本包位置 :-- · :-: · :-- 总台(Agent 卡片 + 场景卡片) · P1 · client/PlatformPanel.tsx 左栏 运行视图(逐灯 + 判定路由可见) · P1 · client/PlatformPanel.tsx 右栏 角色位(执行 / 审计 / 管理,签名位不可改) · P2 · Step 4 拆子页 能力边界页(cannot 段必须完整展示) · P2 · Step 4 拆子页 自定义场景编辑(登记即生效,不是等审批) · P2 · Step 4 拆子页 报告查看与本地验签 · P3 · Step 6+
★ 预约排期面板 与 外部 Agent 接入配置 在 P2 加: 外部 Agent 接入配置 只做配置面板 + 状态镜像(不代签、不持 agent_secret)。
项 · 定 :-- · :-- 分发 · DSH 插件市场(主路径)· 也支持本地目录安装 宿主 · 客户自己的 DSH(我们不要求客户装我们的壳) 依赖 · @shanhai/kaipu-contract(内部契约包 · 不发市场 · 不在本仓)—— ★ 它是构建期依赖:类型由 tsconfig 的 paths 指向,运行值由打包脚本内联进产物 ⇒ 用户机上不需要它。见下面「契约层不在本仓」 是否可单独装/卸 · ★ 是。卸掉智囊团插件后,本插件必须仍完整可用(见下)
★★ 本仓能做什么、不能做什么(一句话口径): 本仓可 `pnpm install` / 可读源码;完整 build 需配套契约层。
本仓源码里有 import … from '@shanhai/kaipu-contract',但那个包不在本仓 —— 它是与受理侧共管的构建期依赖。三件事说清楚,免得被当成仓坏了:
问 · 答 :-- · :-- pnpm install 能过吗 · ★ 能。本包刻意不把它写进 `dependencies` / `devDependencies` —— workspace 协议的依赖要求该包就在本仓内,而它不在 ⇒ 一旦声明,安装会直接以 ERR_PNPM_WORKSPACE_PKG_NOT_FOUND 失败。「这里有个内部契约包」这件事由 `kaipu.devContract`(人读字段)+ `//contract`(说明)承担,不由一个会破坏安装的依赖承担 —— 边界要看得见,但不该拦路。 那源码怎么编译 · tsconfig.json / tsconfig.client.json 的 paths 显式把它指向 ../contract/lib/index.d.ts ⇒ 完整构建需要同级放一份契约包(本仓源码不含它)。 用户机需要它吗 · 不需要。契约的类型被 tsc 擦除、运行值被 tools/build-client.mjs 内联进 `lib/client.js` ⇒ 市场上分发的那份 tgz 自带一切。这也是它能「不发市场」的原因。
⇒ 一句话:本仓是「插件层」的源码;契约层是它的构建期配套,单独管理、不进这里。
含义 · 怎么验 :-- · :-- 智囊团 = 独立插件;删掉它,场地仍完整可用 · 静态:本包 package.json 不依赖 @shanhai/kaipu-wisdom;patch 各自独立 两者只通过接口通信 · 本包不 import 智囊团内部实现;智囊团也不 import 本包内部 场地不内置任何"必须有的" Agent · 零 Agent ⇒ 界面显「待接入」(SceneLamp.agentId === null),流程仍能走
★ 上面这三条不是洁癖:绕不开的场地没人来;可替换的东西才卖得出去。
步 · 内容 · 状态 :-: · :-- · :-- 结构 · 包结构 / 声明格式 / 结构上可摘除智囊团 · ✅ 运行 · 构建管线 + 真 DSH 装载(Step 2) · ✅ 面板 · 总台(Agent 卡片 + 场景卡片) · ✅ 左栏,含「已停用」灰显与「待接入」计数 面板 · 运行视图(逐灯 + 判定路由可见) · ✅ 右栏,按「第 N 轮」分段 Step 4/6 · 面板接真契约形状的数据 · ✅ 演示数据(界面有徽标明示)· 28 项判据全绿 Step 7 · 14 条错误码文案 + 三条必须显示的约束 · ✅ 静态 + 界面两层判据全绿
还没做:报告验签(P3)· 预约与外部接入(P2)· 三个子页(P2)· 接真服务端。
@shanhai/kaipu-contract 的 translateError()。界面只显示译后文案,裸 code 只出现在 data-* 属性里(给判据用,不给用户看)—— 这是既定的客户端纪律。
duplicate_request / not_checked_in 按契约 clientAction 不弹错,走 Reroute 分支(按 detail.poll 切查询接口 / 说明"该场景需进场")。 ⚠️ 这两个的出路在 `detail` 里 —— 接线时务必一路把 `detail` 传下去 (第一版漏传,界面只能说"别急",用户没有任何出路;见 mock/data.ts 的 MOCK_ERROR_DETAIL)。
文案在 src/client/copy.ts(契约外,出处已注明;建议下一版契约收进去)。
mock/data.ts ─┐
├─→ run-reducer.ts(纯函数)─→ LeftPane / RightPane
真 SSE ─────┘ ↑
与来源无关★ 接真服务端时只动一处:把 PlatformPanel 里的 events 换成订阅来的事件、 把 sourceLabel 置为 null。归约器与两栏渲染都不用改 —— 这是把归约做成独立纯函数换来的。改之前请先读 run-reducer.ts 头部那三条契约约束 ([R1] 归组键 (round,lamp) · [R2] 按轮分段 · [R6] 轮数不得推断)。
★ 演示数据必须明示:mock/data.ts 顶部有"三条纪律",第 3 条就是 "必须在界面上标出这是演示数据"。理由与官方 contributing.md 同源 —— 描述与呈现都不能夸大,否则等于自己给自己造一个"名不副实"的把柄。
外加一条:我方 Agent 的 skill / memory / 内部 prompt 永不出现在任何响应体。
本包现在确实是"一件事"(提供场地),不要按"感觉变大了"拆 —— 没到触发条件就拆,只会多出四个包互相 import,反而破坏上面的约束。
只在这四个触发条件之一成立时才拆(承外部评审意见):
触发条件 · 拆成 · 判据(什么时候才算到) :-- · :-- · :-- 编排逻辑复杂到需要独立测试 / 独立版本节奏 · plugin-orchestration · 编排的契约面能独立成文,且有独立的出错语义 门禁逻辑需要独立安全审(对外一句话说不清) · plugin-gate · 门禁被要求单独过安全评审 / 单独出具证据 留痕需要独立审计(第三方要单独验它) · plugin-trail · 有第三方要求"只验留痕、不装其他" 报告面需要独立部署(验签要脱离场地可用) · plugin-report · 报告验签的可用性要求高于场地本身
★ 共同的拆分判据只有一条:
拆出来的东西,能不能"单独被需要"?
能(有人只想装它)⇒ 拆;不能(永远是场地的零件)⇒ 别拆。
★ 拆的时候守两条:① 拆出的包不许被本包 `dependencies` 依赖(否则白拆); ② 各自独立 `cordis.patch.yml`(摘任一段不影响其他)—— 与 plugin-wisdom 同一套姿势。