Skip to content

v0.7.0

Latest

Choose a tag to compare

@ffyfox ffyfox released this 05 Oct 19:34

[0.7.0] - 2026-10-06

把设置界面接到 DSH 0.2 的新机制上 —— 卡片回来了,但配置的存放位置变了。

DSH 0.2 换掉了整套设置机制:旧的 ctx.settings.installSection(...)(插件自选命名空间、值存 settings.yaml)在新版里已经不存在,改成由插件导出的 Config schema 按插件行 id 派生表单,值存进 profile 补丁文档。0.6.1 在这套新机制下的表现是「卡片消失、其余照常」;这一版把它接上了。

新增

  • 导出 Config(schemastery schema,根节点 volatile)。没有这个导出,宿主侧根本不会报出本插件的设置条目 —— dsh-settings 的 describe() 只认「有 Config 且至少有一个 volatile 字段」的行。
  • 卡片改挂到侧栏「插件」页:老设置页那个 settings.plugin.item 槽位在 0.2 里已经不存在(配置界面搬去了 dsh-client-ui-plugin-manager)。本卡片挂 plugins.row.config,键是 <包名>#<行 id>,行上因此多出一个配置入口。
  • 设置页的输入框给出灰字提示:未覆盖的字段留空,灰字显示「清空后会回落到什么」(= config.json 里归一化后的当前值),一输入即消失。开关与二选一没有灰字可用,改为直接显示当前生效值 —— 否则「它现在是开着的」在界面上根本看不出来,用户还会点反。
    做法是往 schema 根节点的自定义 meta 写一份提示表(宿主每次读到 config.json 就刷新,随 describe() 一起发给浏览器),不用 schema 的 .default():默认值参与 cordis 的配置解析,会把 config.json 里用户改过的值静默压掉,而 meta 只是显示信息。客户端从 configForms.describe() 这面镜像里读回它。
  • DSH_DESKTOP_DEBUG=1 下的设置表单诊断:Loader 树落定后打印本行的表单描述符到底有没有被宿主报出来。设置界面「静默消失」时界面上没有任何报错,宿主这一侧是唯一能看到真相的地方。

变更

  • 配置分层:config.json → DSH 设置层,而设置层只包含用户在设置页里真正动过的键。已有的 config.json 因此继续生效、不需要迁移;卡片上没设置过的字段显示为空,含义是「沿用 config.json」。
  • 为此 schema 里一律不写 .default():写了默认值,cordis 解析后的配置会总是带全部键,从而把用户在 config.json 里改过的值静默压掉。嵌套对象额外显式 default(undefined) —— schemastery 给对象 schema 的默认值是 {},不处理的话缺 window 时会凭空长出一个空对象。
  • schema 只约束类型、不约束范围:范围权威仍是 config.js 的 normalizeConfig(320–20000,非法值回落默认值并警告)。两层判定若不一致,一个手改补丁里的 window.width: 200 会让整行加载失败。
  • Config 改为模块加载时同步构造(cordis 直接读 runtime.Config,「用到才 import」那条路走不通),保留「从正在运行的 dsh 安装目录里找 schemastery」这条退路 —— pnpm 的 link: 协议不解析被链接包自己的依赖,那条安装路只能靠它。
  • 设置变更通知改走事件(settings/document-updated),不再依赖 settings 服务的局部注入。
  • 卡片根元素从 <li> 改成 <div>(配置页里它不再是列表项),并在 view: 'summary' 时返回 null(那一份会被塞进 <p>)。
  • 非法提示改为在输入框失焦之后才显示。框是空的,任何尺寸都得从 1 敲起 —— 1、14、140 一路都不合法,边敲边红既吓人又没有信息量;失焦才是「这个值我认了」的时刻。拦保存的判据没有跟着放宽:值非法时保存按钮照样禁用(判红时机与拦截判据是两件事),放弃修改会把这个「碰过」的记忆一并清掉。

修正

  • 卡片里的折叠箭头用了 0.1.x 的原件名(primitives.IconChevronDownOutline14)。0.2 把图标从「按尺寸命名」改成「按字重命名」(IconChevronDownOutlineRegular / …Medium),旧名取不到 —— 而 jsx(undefined, …) 会让整张卡片在渲染时抛错,React 的表现是把那一块渲染成空白:行详情页其余部分照常、界面上没有任何提示。0.7.0 第一次真机装上去就是这样被发现的(› 出现了、点进去却是空的)。改为按「新名 → 旧名」的候选链解析。
  • 新增两条用例专门盯这类退化,它们都在 src/client.js 上做真实对照而不是文本匹配:
    • 「卡片引用的每个原件都必须在宿主的 dsh-client-ui-primitives 里存在」——把卡片引用的原件名与真实安装的导出表逐一对账,候选链则要求至少命中一个;
    • 「卡片能带着一份完整快照真的渲染一遍」——用会记账的 react / jsx-runtime / 原件桩把九个控件递归渲染一遍,取不到原件时当场抛错。
      把旧名字塞回去,这两条会同时变红(已验证)。
  • 输入框一进入非法态就「塌」成一行高。类名写成了二选一(state.invalid ? CSS.inputInvalid : CSS.input),而 .dsld_inputInvalid 只是「红边框」一个修饰 —— 高度、内边距、圆角、字号全在基类上。于是值一非法就变回浏览器裸 input,实测 34px → 21px、圆角 8px → 0、内边距 12px → 2px、字号 13px → 13.33px,并且把我们用 outline:none 关掉的主题焦点环(2px 蓝框)露了出来。
    这条老代码一直在,但被「空框 + 灰字」暴露了:以前输入框预填当前值,敲第一个键得到的是 12001 这类合法值;现在任何尺寸都得从 1 敲起,而 1 必然 < 320。改成基类 + 修饰叠加(inputClass()),并加用例钉死「非法时类名必须同时含基类」,同时在源码层面禁止再出现二选一写法。
  • 非法提示是黑色的,红边框也不红。卡片引用了 --dsw-alias-label-error,这个名字在 DSH 0.2 主题里根本不存在(真名是 --dsw-alias-state-error-primary)。var() 落空会让整条声明变成无效值:color 继承正文色(于是提示是黑的)、border-color 退回 currentColor。同一个错名字还挂在「保存被拒绝」那行文字上,一并改掉。
    新增用例「卡片 CSS 引用的 --dsw-* 变量都必须在宿主主题里真的定义过」——直接从真实安装的 dsh-client-ui-theme 里抓变量表逐个核对,写错名字当场变红(已验证)。

移除

  • installSettingsNamespace 与 settingsBase:前者是旧机制的注册入口(在 0.2 上必然抛 TypeError 被吞掉),后者是「把 config.json 当 composition base 传进去」的旧路径 —— 新机制下 base 层由 cordis 的配置层决定,插件无法注入。

不再支持

  • DSH 0.1.x:旧的 settingsScope 服务与 settings.plugin.item 槽位都不再兼容,0.1.x 宿主上没有设置界面(其余功能不受影响)。0.1.x 上请用 dsh-lxi set 或直接编辑 config.json。