Skip to content

Releases: Caoran1314/dsh-edict

dsh-edict v0.1.8

Choose a tag to compare

@Caoran1314 Caoran1314 released this 13 Oct 16:37

[0.1.8] — 2026-10-14

修复

  • 独立看板打开是 403 "拒绝访问"。根因是我用错了栅栏:
    connection.requestRejection 内含 login-token cookie 校验(见 dsh-schedule 源码注释),
    而浏览器新标签页的顶层导航不会自动带 cookie —— 拿它当"拒绝外部访问"的栅栏,
    必然把用户自己堵在 403。
    现在区分对待:
    • 页面路由 /edict:放行顶层导航(无 Origin 头),只拒跨站 fetch(有 Origin 且与 Host 不符)
    • 数据路由(/edict/board / audit / task):保留 requestRejection 栅栏
  • 独立看板改为服务端渲染:看板数据与最近审计直接内嵌进 HTML,页面首次打开即可用,
    不再依赖凭据去 fetch。若能带凭据过栅栏,再自动切换为 3 秒实时刷新(页头会显示"内嵌快照 / 实时")。

状态码速查(写给以后的自己)

状态码 含义
401 路由不存在(被 DSH 通用认证中间件拦,响应体为空)
403 路由存在,是插件自己的栅栏拒绝了该请求

dsh-edict v0.1.7

Choose a tag to compare

@Caoran1314 Caoran1314 released this 13 Oct 16:24

[0.1.7] — 2026-10-14

修复

  • 工具调用报 returned invalid output: value is not lossless JSON。
    任务对象的可选字段(如 active[].org、now、remark)常为 undefined,
    而宿主对工具返回值做 lossless JSON 校验,遇到 undefined 直接判为非法(JSON.stringify 会静默丢弃,
    所以本地自测发现不了)。
    新增 toLossless() 深度清洗:剥掉 undefined(字段整体删除)、function/symbol → null、
    bigint → 字符串、Date → ISO、Buffer → utf8、NaN/Infinity → null、检测循环引用。
    在 execute 出口与 render 两处生效。

这个缺陷是作者自己调用工具时发现的 —— 说明"发布后真用一遍"比任何自测都重要。

dsh-edict v0.1.6 — 首次真正可用(修复三个致命缺陷)

Choose a tag to compare

@Caoran1314 Caoran1314 released this 13 Oct 16:19

dsh-edict v0.1.6

这是首次真正可用的版本。0.1.0–0.1.2 存在致命缺陷,请勿使用。


⚠️ 三个致命缺陷(本版修复)

1. 声明了 dsh.client 却未导出 ./client → 整个 DSH 启动失败

dsh-edict declares dsh.client but exports no "./client" bundle

宿主 ClientModuleRegistry 抛出后,DSH 启动失败并触发自愈逻辑清空 profile 里所有插件层
(用户侧表现为"我的插件怎么全没了")。0.1.0 / 0.1.1 均为此缺陷版本。

2. 15 个工具与 5 条看板路由全部注册失败(且无任何报错)

两个叠加原因:

问题 后果
工具缺少必需的 output { schema, render } tools.register() 抛 must declare output ...,异常被静默吞掉
apply() 时 tools/webServer 服务尚未就绪,取不到即永久放弃 看板路由 0 条 → /edict 返回裸 401

现改为:统一 withOutput() 补齐契约 + 监听 internal/service 事件 + 1.5 秒定时重试双保险。

3. 独立看板无法打开(新标签页不带凭据)

window.open('/edict') 是顶层导航,不携带 DSH 浏览器凭据,被认证中间件拦掉。
新增 GET /edict/url,由宿主用 connection.authenticatedUrl 生成带 token 的地址。
(签名是从 dsh-host-frontend-static 里挖出来的:要传完整 base URL。)


修复清单(按版本)

版本 修复
0.1.2 补 exports["./client"](致命启动缺陷)
0.1.3 工具 output 契约 + 服务晚到重试;edict_role 用错 store 实例
0.1.4 新增 /edict/url(带凭据地址)
0.1.5 last-load.json 写入 store.dir(此前测试会覆盖真实加载证据,造成误判)
0.1.6 修正 authenticatedUrl 调用签名

新增的诊断能力

  • ~/.dsh/edict/last-load.json —— 记录每次加载的 tools / routes 数量,
    用于区分"插件没加载"与"加载了但没注册"
  • 注册失败不再静默:走 logger.warn

测试

  • 单元测试 28/28 通过(状态机转换表与上游 task.py 的 EXPECTED_TRANSITIONS 逐条对齐)
  • 冒烟测试新增 3 条回归守卫(本版的三类缺陷各一条):
    • 每个工具必须声明 output { schema, render } 与 execute
    • 5 条看板路由必须注册
    • 服务晚到时必须能补注册(模拟 apply 时服务未就绪)
  • mock 宿主已改为符合真实契约(ctx.get('tools') + ctx.effect + internal/service 事件)

安装

dsh plugin --profile desktop add dsh-edict

完整变更

见 CHANGELOG.md。
踩坑记录见 docs/RELEASE.md
与 docs/PLUGIN-RELEASE-CHECKLIST.md。

v0.1.0 — 三省六部审核流程 DSH 插件

Choose a tag to compare

@Caoran1314 Caoran1314 released this 13 Oct 14:40

把 edict(OpenClaw 三省六部制多智能体编排,MIT)的审核流程逻辑移植为 DeepSeek Harness 插件,规则逐条对齐。

规则(与原版一致)

  • 12 状态状态机 —— 转换表对齐上游 task.py 的 STATE_TRANSITIONS;终态 {Done, Cancelled} 无出边
  • 门下省封驳 —— Menxia → Zhongshu 打回重做;confirm reject 退回 Review 复审
  • 高风险操作确认 —— Review→Done(menxia)、Doing→Cancelled(shangshu)、Menxia→Cancelled(zhongshu) 先落 PendingConfirm
  • 越权矩阵 —— 11 个衙门角色的命令白名单(六部不能改状态、门下省不能 create 等)
  • done 前置硬校验 —— 状态须为 Doing/Next 且 todos 全部完成
  • 单一 in-progress 约束 / 委派防死锁(深度≤3、成环拒绝、权限链)
  • 审计留痕 —— ts/task/agent/action/from/to/reason,上限 5000 条,拒绝也记录

提供的能力

  • 15 个工具:edict_create/move/flow/progress/todo/done/block/confirm/delegate/delegate_result/memory/task_memo/shared_memo/status/role
  • 3 个命令:edict(看板)、edict-audit、edict-reset-role
  • 军机处看板 UI:设置页「三省六部」面板 + 独立看板页 /edict
  • 零依赖 —— 只用 Node 内置模块;数据存 ~/.dsh/edict/,原子写 + 跨进程锁

安装

dsh plugin --profile desktop add dsh-edict

测试

  • 28 项单元测试(node test/edict.test.mjs),含从上游 test_state_machine_consistency.py 移植的状态机守卫
  • 冒烟测试(node test/smoke.mjs):mock ctx 加载插件并跑通完整旨意

相比上游的两处行为增强

项 上游 本版 原因
progress 替换 todos 后 不重算 ready_to_close 重算 上游内部不一致
todos 清单解析 item[:-1] 截断 按码位删除 emoji 是代理对,JS 里会留半个字符

致谢

流程设计来自 cft0808/edict(MIT)。本移植保留其规则语义并注明出处,实现代码独立编写。

完整变更见 CHANGELOG.md