Repository navigation
[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。