Skip to content

Releases

v0.7.0

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。

v0.6.1

Choose a tag to compare

@ffyfox ffyfox released this 05 Oct 17:40

[0.6.1] - 2026-10-06

修掉两处用户直接看得见的毛病,并把 0.6.0 那次整体更名漏掉的一处补齐。

① 图标串号:deepseek-harness → dsh-lxi。

图标名是全局命名空间:桌面环境按名字查图标,任何软件都能占用同一个名字。官方 Electron 桌面端的入口用的就是 deepseek-harness,而本插件一直也用这个名字,并把自己那张位图写进 ~/.local/share/icons/hicolor/ —— 用户级优先级高于 /usr/share,于是同一个名字下出现了两张完全不同的图。哪一张被取到还取决于查询工具与请求尺寸(实测:GTK 在 ≤64px 命中系统 SVG、≥128px 命中用户级 PNG;Qt 一律命中用户级 PNG),表现就是两个应用的图标互相串、且时好时坏。

本插件改用自己的命名空间 dsh-lxi,与命令、目录、启动器保持一致,不再复用别人的名字。

② 程序启动器里出现两个一模一样的「DeepSeek Harness」。

本插件必须再生成一份文件名等于 Wayland app_id 的 .desktop(别名入口,chrome-<host>__-<profile>.desktop),否则桌面环境找不到这个窗口对应的入口,任务栏会退化成黄色的通用占位图。但这份别名一直是主入口的完整副本,而它同时也是启动器会读的合法入口 —— 两个文件名不同、Name= 却一字不差,于是菜单里把同一项列了两遍。

别名入口现在多一行 NoDisplay=true:它只影响「要不要列进菜单」,条目本身照旧留在桌面环境的索引里,因此按 app_id 找图标、关联任务栏与 Alt+Tab 的逻辑不受影响。这也正是它比「干脆不生成别名」正确的地方 —— 后者会把任务栏图标一起弄丢。

③ 更名补齐:插件行 id linux-desktop → dsh-lxi。

0.6.0 那次「包名、命令名、数据目录整体更名」漏掉了这一个内部标识符 —— 插件行的 id、插件模块导出的 name、日志前缀,以及设置命名空间,四处都还叫 linux-desktop。它们必须永远一致(改一处就得四处一起改),漏改的症状是设置卡片静默不出现,只有真人打开设置页才看得见。

行 id 还有一层新含义:DSH 0.2 起,插件的设置表单按行 id 键控并存进 profile 补丁文档 —— 这个名字会变成永久的设置存储键。本插件在那个旧 id 下还没有存过任何东西,所以现在改是成本最低的时候。

变更

  • 桌面入口与 Wayland app_id 别名入口的 Icon= 改为 dsh-lxi。
  • 图标改写到 ~/.local/share/icons/hicolor/{128,256,512}x*/apps/dsh-lxi.png。
  • 启动器通知(notify-send --icon=)同步改用同一个名字。
  • 图标本身没有换,只是换了个名字挂上去。
  • app_id 别名图标(文件名等于 chrome-<host>__-<profile>)不受影响 —— 那个名字由 Chromium 决定,不能改。
  • 内部标识符一并更名:cordis.patch.yml 的行 id、src/index.js 的 name 与日志前缀、SETTINGS_NAMESPACE、客户端 NAMESPACE,linux-desktop → dsh-lxi。

修正

  • 别名入口(chrome-<host>__-<profile>.desktop)带上 NoDisplay=true,不再在程序启动器里重复出现。主入口 dsh.desktop 不带这一行。
  • renderAliasEntry 找不到主入口的 Terminal=false 锚点时当场抛错,而不是静默生成一份漏了 NoDisplay 的副本 —— 后者只有真人打开程序菜单才看得见,属于最难发现的那种退化。
  • 订正 0.6.0 更新日志里的一处说法:那里写「Hyprland / KWin 的规则名与标记块 dsh-desktop-* → dsh-lxi-*」,但 KWin 的规则标识符(kwinrulesrc 里的 description)从 0.1.0 起一直是 DeepSeek Harness Window Rule —— 它用的是产品名,从来不是 dsh-desktop-*。那次实际只改了 Hyprland。

升级

  • 默认无需任何操作(autoInstall 默认为 true):dsh web 下次启动时会自动清掉用户级那份旧的 deepseek-harness.png(128 / 256 / 512 三档)与 0.1.x 时代留下的 deepseek-harness.svg,同名的图标随即恢复成原本属于它的那一张。
  • 若把 autoInstall 关掉了:手动执行一次 dsh-lxi install。
  • 清理只在确认本插件确实安装过(桌面入口里带本插件的生成标记)时进行;dsh-lxi uninstall 同样覆盖新旧两个名字。
  • 升级后若某个图标仍是旧图,注销重登一次 —— 桌面环境会缓存已解析的图标位图。
  • 若你在另一个 profile 里钉了旧版本:本插件的自动安装会写图标,而这些文件不随 profile 分家,旧版本仍会按旧的图标名写图 —— 谁最后启动谁说了算,图标会退回互相遮挡的状态。把那个 profile 一起升上来即可。
  • 插件行 id 改名不需要迁移:本插件在旧 id 下没有存过任何设置,桌面入口、图标与 KWin / Hyprland 规则也都不以它命名。

已知问题

  • DSH 0.2.x 上设置页那张「桌面集成」卡片不再出现。 DSH 0.2 移除了 settings.yaml 那套「插件自选命名空间」的模型,改成由插件导出的 Config schema 按行 id 自动派生表单,值存进 profile 补丁文档;ctx.settings.installSection 在新版里已不存在。本插件尚未适配,那次调用会失败并被内部的 try/catch 吞掉 —— 只影响这张卡片,其余功能一切照常(dsh web 不会因此起不来)。适配单独排期;在此之前请用 config.json 或 dsh-lxi set 改配置。

其它

  • 新增用例 11 项(158 → 169)。

v0.1.0 —— 首个可用版本

Choose a tag to compare

@ffyfox ffyfox released this 20 Sep 11:54

DeepSeek Harness 的 Linux 原生桌面集成:XDG 桌面入口、无边框独立窗口、关窗自动停服务。

安装

dsh plugin --profile web add /path/to/dsh-linux-desktop

安装后重启一次 dsh web,即可从程序启动器搜索 DeepSeek Harness 启动。

特性

  • 纯净窗口 —— Chromium --app 模式,窗口中只有 dsh web 界面,无地址栏、标签页、书签栏
  • 桌面集成 —— 标准 XDG .desktop 入口 + app_id 别名入口 + 矢量图标,任务栏与 Alt-Tab 显示正确图标
  • 自动生命周期 —— 关闭窗口后停止由自己启动的服务;绝不动不是自己启动的服务
  • 零额外运行时 —— 复用系统已有的 Chromium 系浏览器,不打包 Electron/Tauri
  • 幂等自愈 —— 每次 dsh web 启动时同步桌面入口、图标、启动脚本与 KWin 规则

环境要求

Linux + Chromium 系浏览器(Chrome / Chromium / Brave / Edge / Vivaldi / Opera)+ dsh。

Firefox 不支持:官方已移除 SSB,无法提供无地址栏窗口。

已知限制

  • shared 模式下,Chrome 已在运行时无法感知窗口关闭,因此不会自动停止服务(会弹通知说明)
  • 仅支持回环地址(受 dsh web 自身限制)
  • 仅在 Arch Linux + KDE Plasma 6 + Wayland 上实测;其它桌面环境与 X11 为架构推断,尚未验证

验证

61 项零依赖测试;CI 覆盖 Node 20/22/24 与 macOS。详见 CHANGELOG。