vb2250158/dsh-environment-sync

dsh-environment-sync

Open-source DSH environment synchronization and personal plugin management

待分类

dsh-environment-sync

本仓库的 npm test 覆盖环境、安装与恢复流程。独立插件维护各自的测试,不以拆仓前的 plugins/ 目录或整体仓库的 loader ID 作为依赖。

npm test covers environment synchronization, installation and recovery. Independent plugins own their tests without depending on the former monorepo's plugins/ directory or combined loader IDs.

环境同步客户端在管理面板首次打开时读取完整状态,启动时不预热插件目录;面板继续支持刷新和操作后的状态更新,并合并同时发生的状态请求。

The client reads full environment status when the management panel opens, without prefetching the plugin catalog during startup. Refresh, status updates after operations, and concurrent status-request coalescing remain available.

Web 两阶段安装在冻结锁文件安装完成后启用本次新增且声明 dsh.bundle 的包;保留已有 bundle 的启停选择和顺序,不启用普通依赖或仅含客户端的包。启用写入纳入原安装事务,失败恢复原 profile。

Web two-stage installation enables newly added packages declaring dsh.bundle after the frozen-lockfile install. Existing bundle choices and order remain intact; ordinary dependencies and client-only packages are not added to the bundle list. Activation belongs to the installation transaction and failures restore the previous profile.

Desktop profile

接口描述读取插件自身的 Zod 依赖,独立 Desktop Home 不要求初始化 Web profile。

pnpm 安装私有 Git 仓库时可能省略依赖声明中的提交。仅在直接依赖的锁文件同时确认仓库和完整提交时,恢复固定来源声明及锁文件的 specifier;缺少记录或提交不匹配时拒绝并恢复,锁定的安装内容不改变。

插件默认使用应用启动器提供的 profile 和 Home。Desktop 安装及恢复通过本应用的官方 pluginManager,保留随应用提供的依赖,不写入源码 link: 覆盖,也不启动 Web Host。Web 的源码安装与重启流程保持不变。

Desktop 安装期间临时设置 saveExact,结束后恢复该设置并保留安装器产生的其他工作区设置;安装后回读版本与固定来源,不匹配即恢复旧包。恢复记录仅包含本次变更的第三方包,不重装无关包或随应用提供的包。

Web 与 Desktop 共用插件版本清单、主题、模型和其他可移植设置;清单中的 profile 标记导出来源,不阻止这两种宿主相互导入。实际安装写入明确指定的目标 profile,不复制 node_modules。源 profile patch 的可移植设置与启停配置应用到目标,目标自身的 Web Server 配置保留;随应用提供的必需 bundle 不被替换。Desktop 安装不提前启用新包,环境应用后再同步 bundle 选择,完全退出并重新打开后生效,关闭窗口仅隐藏应用。外部脚本不能用源码 CLI 修改 Desktop profile。

This release requires DSH 0.2.1-alpha.1 or a compatible 0.2 release. See compatibility details.

通过 Git 同步整套 DSH 插件与共享配置。公开和私有插件均使用固定提交,私有环境仓库保存清单、配置和加密凭据;聊天、附件、运行日志和本机资料库不上传。

通用注意事项

以下各条与具体电脑无关:换机、换目录、换 Windows 用户后依然成立。多数同步事故都源于其中某一条被忽略。

路径与设备不跨机成立

不同 Windows 用户、不同 DSH Home 的安装互不代表对方。不要从另一台电脑的盘符或目录推断本机路径,每次先确认当前 DSH Home、profile、实际进程与授权再动手。网络地址、NAS 路径、资料库位置等设备相关设置不进入共享配置;机器专用的额外字段登记在本机 private-sync.local.yaml。资料库与会话数据不随本仓库复制。

固定提交必须已推送到远端,且稳定可取

Git 服务端支持过滤时,来源预检只取提交、目录和选定的包信息,其他素材留到正式安装阶段;不支持过滤时保留 Git 的普通传输。预检仍按完整提交核对包名和版本。

On Git servers that support filtering, source preflight fetches commit/tree objects and the selected package manifest. Unrelated assets remain for the official installer. Servers without filtering retain ordinary Git transfer; fixed-commit package name/version checks still run before profile changes.

仓库子目录中的插件使用 github:owner/repository#&path:packages/plugin,也支持 git+https://github.com/owner/repository.git#&path:packages/plugin。子目录仅接受由字母、数字、下划线和连字符组成的相对路径段,不接受绝对路径、点路径段、反斜杠、编码路径或其他参数。安装前读取该提交中子目录的 package.json,核对包名和版本;Desktop 恢复被安装器规范化的来源时,锁文件也必须确认同一子目录。

清单中的 specifier 钉的是完整提交,安装时会到远端按该提交取包。三条相关约束:

  • 钉一个只在本地存在的提交,会在取包阶段失败,并把本机仓库弄脏——脏仓库会阻塞下一次同步。「本地能拉到」不代表远端有,以远端能列出该提交为准。
  • 「远端现在能取到」也不等于永久能取到。 只有从某个分支头可达的提交是稳定的;仅存在于本地、之后才推送或从未推送的提交,可能现在取得到、被回收后就取不到。核对该提交与远端分支的关系,而不是只确认「取到过一次」。
  • 核对时使用完整提交号。 用缩写向远端取包会被当成引用名解析并报「找不到该引用」,这是取法错了,不代表提交缺失。

fork 类插件通常同时存在自己的仓库与原作者远端,而分支的上游跟踪可能指向原作者仓库——据此判断「有没有推送」会得出相反结论。先确认远端列表,以清单中声明的那个仓库为准。

密钥只在机器之间人工传递

同步密钥保存在本机 private-sync.key,不进入仓库;不能在新电脑上重新生成去代替原有密钥,它是解密既有快照的唯一凭据。只能从一台能解密当前快照的电脑通过安全渠道传递。密钥、解密后的凭据、资料库与会话数据都不得提交,也不应出现在日志或分享内容里。

清单管不到的东西

  • 浏览器配套扩展是独立对象:它由某个插件附带的目录提供,需要在浏览器扩展管理页以「加载已解压的扩展程序」手动加载,与插件清单是两回事。不要因为提示缺少扩展就认为清单缺项。
  • 扩展更新是两个动作:先在扩展管理页重新加载扩展(浏览器只在加载那一刻读取清单文件),再刷新已打开的页面。只做前者,页面上已注入的旧脚本仍会报错,看起来像「更新没生效」。
  • 首次接入不会卸载清单之外的已有插件;只有已被同步基线接管的插件才参与自动删除。

以当前文件为准,不以历史印象为准

  • 插件数量随增删变化,读取当前清单,不要把过去截图或记录中的数字当成目标。
  • 取到 Git 引用不等于已安装、已加载;旧索引与「已安装插件无更新」都不构成完整清单。
  • 磁盘上的版本正确不等于页面已生效:需要重启并核对运行版本。安装完成不等同于旧进程已加载新代码。

冲突与外部改动

  • 冲突是按文件选择本机或远端完整版本,不是逐字段合并。先读差异,不要随意覆盖双方都改过的文件。
  • 仓库中由外部程序留下的未提交改动会被保留并阻止覆盖,应先用 Git 客户端提交或另行保存,不要用 reset / clean 覆盖。
  • 重复同步应无新提交,这是判断同步是否健康的一个简单信号。

首次安装

使用已安装并构建的 Windows DSH 源码环境,设置 DSH_SOURCE_ROOT。当前兼容检查使用 DSH 0.1.3-alpha.1 源码接口(上游提交 d347e703908d0406b7a7ef80e3a0e594d86b2215)。本插件不更新或覆盖 DSH 源码。

克隆本插件的 v0.6.1 发布标签并记录其完整提交,在 PowerShell 执行:

./scripts/bootstrap-environment.ps1 -SourceRoot <DSH源码目录> -Repository https://github.com/<owner>/<private-environment>.git

Git 必须已获得私有仓库读取权限。首次进入“插件 → 环境同步 → 配置”,填写与原电脑相同的同步密钥,然后点击“拉取并应用”。密钥只保存在本机 private-sync.key,通过仓库之外的安全渠道传递。安装目录中的恢复运行时须保留;本机 Recover DSH.vbs 提供不依赖 DSH 页面启动的恢复窗口。

日常操作

接管遗留环境事务(仅维护窗口)

如果 profile 中遗留 applying、restore-failed 或其它未完成事务,不要直接点击重试、拉取并应用、上传或安装插件;旧流程可能先恢复旧快照并继承上传意图。确认所有 Agent/网页工作已妥善收尾,并从当前运行 profile、清单、锁文件和实际进程完成只读核对后,才可在同一台机器的维护窗口运行:

node scripts/takeover-stale-transactions.mjs `
  --dsh-home <绝对 DSH Home> `
  --profile <profile> `
  --repository <绝对私库克隆> `
  --backup-directory <DSH Home/backups/本轮目录> `
  --confirm-preserve-current `
  --acknowledge-unverified-installation `
  --confirm-exclusive-maintenance

该入口只备份当前文件并原样移出遗留 journal,不恢复快照、不安装、不上传、不重启;回执中的安装一致性、旧事务成功和同步成功仍为未证明。备份目录必须位于该 DSH Home 的 backups 子目录;任何锁、路径漂移、符号链接、备份不一致或中断都会拒绝并保留 pending 门禁。接管完成后,另行按当前清单执行官方安装入口并核对固定提交、解析目录、loader、运行进程和页面;不能把接管回执当作新版已加载。不要从备份目录运行旧脚本,也不要在 Agent 仍活动时调用重启入口。

重启电脑后可双击 DSH Home 中的 Start DSH.vbs 启动服务,再打开本机 DSH 页面。启动器保存本机源码与 Home 路径,不依赖旧聚合包环境变量;需要自动启动时可将该入口的快捷方式放入 Windows 启动目录。

  • 检查更新:只获取远端引用。
  • 上传改动:自动记录插件新增、删除、版本和共享配置;先保存本机修改,再合并远端并上传。
  • 拉取并应用 / 重试:保存已接入电脑的本机修改,合并 Git 更新,预检固定提交和密钥,安装、升级、删除插件并应用配置。首次恢复直接使用共享环境。
  • 安装 / 更新插件:输入 GitHub 仓库地址,自动解析固定提交。卸载保留插件用户数据;上传后其他电脑可以同步这一变化。
  • 冲突选择:查看本机与远端文件,选择保留的完整版本。双方历史均保留;冲突解决前不覆盖运行配置。加密凭据不以明文显示。
  • 重启并加载:插件或环境更新需要重启时会先显示确认对话框;确认后调用受管 Windows 重启入口。取消、关闭或选择稍后再说会写入本机待重启标记,显示待生效备注并保留此按钮。安装完成不等同于旧进程已经加载新代码。
  • 恢复上次环境:恢复配置和插件;网络造成恢复失败时保留恢复点供重试。

管理器自身记录在共享清单中,能随其他插件更新;普通清单删除不会卸载管理器。首次接入不会卸载清单之外的已有插件;之后只自动删除本机同步基线中已接管的插件。当前安装对象应先完成来源整理,本地开发 link 不能冒充可恢复版本。

配置与凭据

environment.json 格式 2 保存同步范围,旧格式 1 只读迁移。config/plugins.json 保存精确版本与来源。原作者和 fork 信息随记录保留,不改变仓库的公开或私有属性。

0.7.0 起,Home 下的 .agent-presets// 随共享环境上传并恢复,包括 agent.cordis.yml、可选 preset.yml、技能和二进制资产;内置预设与额外配置根目录不在该范围。文件保留原目录和 Git 历史,冲突按文件选择;environment.json.agentPresets 记录文件、执行权限与明确删除。只有此前记录过的文件会同步删除,目标电脑的其他预设保留。没有此字段的旧快照不改动本机预设;两台电脑均须升级管理器至 0.7.0 后同步预设,旧管理器仍可读取格式 2 并安装共享清单中的新管理器。

预设是受信任的可执行配置。该目录只能放准备跨机共享的定义、技能与资产;不要放凭据、聊天、附件或机器路径。链接、特殊文件、路径越界、已知凭据与运行数据目录、缺少组装文件或错误 YAML 均在预检时拒绝,不递归读取链接目标。预设文件纳入同一应用恢复记录,失败时恢复原内容与权限。

0.7.1 起,Home 的 .dsh-agent-presets-sync-baseline.json 区分已受管文件与尚未恢复的远端文件。首次升级或接入时,缺少远端文件不代表删除;应用后才接管删除语义。该基线只留在本机,并随应用失败恢复。

插件展示数据(catalog.json)

管理页面的插件显示名、作用范围分类和说明来自插件自带的 catalog.json,与版本和来源(私有仓库的 config/plugins.json)分开维护。每个条目必须带:

  • name —— 面向用户的显示名,中文短名,不是包名。
  • scope —— 作用范围,取值 session(会话插件)或 global(全局插件)。
  • description —— 一句话说明;details 补充边界和生效方式。

scope 按效果的作用范围划分,不按仓库或作者:只改变单个会话界面与行为的算会话插件(主题、聊天展示、模型下拉、按会话挂载的面板);提供跨会话能力、注入约束或注册全局工具的算全局插件(网络、搜索与模型提供方、约束注入)。取值缺失或非法时按 global 处理,避免把全局插件误显示成只影响一个对话。完整字段表与判定顺序见 docs/plugin-manager.md。

settings.yaml、home/profile patch 和 AGENTS.md 使用 Git 历史。NAS 设置、情感资料库路径及会话绑定、Rabi Manager 地址不进入共享 settings;目标电脑的 webserver 配置保持本机值。其他机器专用字段可登记在 private-sync.local.yaml。

.credentials.yaml 与 plugins/subscriptions/auth.json 共同加密到 credentials.enc.json,使用 AES-256-GCM 和 scrypt。显式删除的凭据不会从旧文件复活;可选文件只有明确删除记录才会从目标移除。同步密钥、解密后的凭据、资料库及会话数据不得提交。

源码版 DSH 的官方接口依赖在每台电脑上自动绑定到同一份 DSH_SOURCE_ROOT,避免旧 npm 接口与新源码混用。这些官方依赖路径和本机锁文件不进入共享插件清单;共享插件本身保持固定 Git 来源。

失败与恢复

Git 操作、插件安装和环境应用分别互斥。操作阶段和恢复点保存在 profile 下的 .dsh-environment-operation.json、.dsh-plugin-operation.json、.dsh-environment-restore.json。这些本机文件可能包含设置或凭据,只留在本机。

拉取前保存本机共享修改;应用前验证所需文件、密钥和变更插件的 Git 提交。报告安装失败时,尝试按原清单与锁文件恢复;进程中断后下一次操作先处理未完成的恢复。断网不能保证立即恢复全部包,但不会丢弃恢复记录。

仓库中由外部程序留下的未提交改动会被保留并阻止覆盖,可通过 Git 客户端提交后继续。上传被远端新提交拒绝时,重试会重新合并。完整回退仍需原固定提交可获取。

开发检查

pnpm test
pnpm run check
npm pack --dry-run

测试包含两个真实 Git 克隆的修改保留、冲突选择与失败重试;插件安装单元测试使用模拟安装器。发布验收另行执行真实 Git 包安装、启动和 GUI 检查。测试结果不能代替目标电脑的设备、网络或真实模型请求验收。

MIT

插件同步没有执行安装命令时,0.7.2 的配置回滚只恢复保存的文件;中断安装和旧恢复记录仍通过官方安装器恢复依赖。

Plugin display metadata

The plugin list shows Environment sync in English and 环境同步 in Chinese, following the DSH interface language. locale/en.json and locale/zh.json provide the title and description; icon.svg supplies self-contained artwork. The package exports and publishes these resources. The icon is adapted from Lucide; see ICON_LICENSE.txt.

插件设置入口

在插件列表中点击本插件进入详情页,即可使用原有配置和操作界面;设置菜单不再重复显示该插件入口。

The icon uses a centered 36 × 36 viewBox to leave more space around the artwork inside the plugin icon frame.

Fresh profiles may omit dependencies. Source alignment creates the dependency map before adding the official interfaces required by their plugins.