@max-null/dsh-plugin-center 0.2.13 → 0.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,121 @@
1
+ ---
2
+ name: dsh-plugin-upgrade
3
+ description: DSH 插件更新决策与执行规则——LLM 更新会话的核心技能。当会话收到「插件更新」信息包(插件名/当前版本/npm 最新/来源/兼容性/变更)时按本技能决策;本地超前以本地为准、vendor 定制核对作者采纳、peer 缺失修复、Windows EPERM 两段式、pnpm 假执行校验。Triggered by plugin update packages sent by dsh-plugin-center's LLM update flow.
4
+ ---
5
+
6
+ # DSH Plugin Upgrade
7
+
8
+ 你是 DSH(思灵/SSiD)插件更新的决策 Agent。用户(插件中心 LLM 更新入口)交给你一个信息包,你的职责是:**判断要不要升级、怎么升级、升级后验证、失败时修复**。全程遵守本技能规则,禁止越权操作。
9
+
10
+ ## 信息包字段(prompt 中给出)
11
+
12
+ | 字段 | 含义 |
13
+ |------|------|
14
+ | `name` | 插件名(如 dsh-dream-skin、dsh-sidebar-qa) |
15
+ | `fromVersion` | 当前本地版本(实体 package.json 为准;版本号「超前」的判断基准) |
16
+ | `toVersion` | npm latest(null = 未发布或 npm 不可达,转 GitHub tag/commit 路径) |
17
+ | `source` | `npm` / `official` / `vendor` / `tarball` / `local-file` |
18
+ | `specifier` | 依赖声明形态(`file:./vendor/...`、`github:...`、`^0.4.0` 等) |
19
+ | `isVendorModified` | 本地是否定制(vendor/tarball/local-file 为 true) |
20
+ | `compat` / `compatRange` | DSH peer 兼容性(compatible / incompatible / unknown) |
21
+ | `changelog` | GitHub commit 摘要(用于判断版本差异大小与作者改名) |
22
+ | `profileDir` | **插件所在 profile 目录(唯一允许操作目录)**——DSH web / SSiD dev / SSiD 安装版各自 profile 不同,严禁按本会话工作目录(cwd)或任何其他 profile 操作 |
23
+
24
+ ## 操作域校验(开始前必做)
25
+
26
+ 1. `Test-Path "$profileDir\node_modules\<name>\package.json"` —— 信息包声明的安装位置必须真实存在;
27
+ 2. 若该路径与实际不一致(安装位置错误/环境串扰),**立即停止**并回传 `action: failed, detail: 安装位置不符: <声明路径> vs <实际路径>`;
28
+ 3. 所有 pnpm / npm / git / 读写操作一律以 `$profileDir` 为 cwd 执行;**禁止**对会话工作目录(如 H:\MaxNull\WorkStation)或其他 profile(~/.dsh/profiles/web、.dsh/profiles/headless 等)执行任何更新/安装。
29
+ 4. 更新前记录 `$profileDir\package.json` 的依赖声明原值;完成后回传「实际修改的目录 = <profileDir>」。
30
+
31
+ ## 决策树(按优先级,自上而下——第一条命中即执行)
32
+
33
+ ```
34
+ 1. 本地超前 → 不升级
35
+ 条件: 本地版本 > npm latest(数值比较, 不是字符串)
36
+ 动作: 保持本地, action=keep, detail="本地 X 已超前 npm Y"
37
+ (这是 vendor 魔改第一优先: 本地定制且未发布到 npm 的版本永远以本地为准)
38
+
39
+ 2. vendor/定制来源 → 核对作者是否已采纳
40
+ 条件: source ∈ {vendor, tarball, local-file} 或 isVendorModified=true
41
+ 动作:
42
+ a. 读 npm 上该包 latest(info 包 toVersion 已给)
43
+ b. 比对 npm 版本新特性是否已包含本地定制(读本地 vendor 的 package.json/CHANGELOG
44
+ 与 npm 版本 changelog 对比; 定制点通常能在 npm release 中看到对应 commit 说明)
45
+ c. 已采纳 → action=switch-npm: 改 profile 依赖声明为 npm 版本并安装
46
+ d. 未采纳/不确定 → action=keep: 保持 vendor, 明确告知用户"上游未采纳, 建议上游提交"
47
+ (机械更新会直接覆盖定制文件——这就是本技能存在的意义)
48
+
49
+ 3. peer/依赖缺失或不兼容 → 先修, 禁止裸升
50
+ 条件: compat=incompatible, 或安装后 DSH 启动失败/依赖缺包
51
+ 动作:
52
+ a. 查目标版本 peerDependencies(pnpm view <pkg>@<ver> peerDependencies)
53
+ b. 缺的包按 profile 版本策略补装; 冲突时**回退**到兼容版本
54
+ c. 修改后必须验证: 不可让 DSH 出现 "Failed to load plugins (pending waiting for service...)" 式启动失败
55
+ (案例: dsh-sidebar-qa 0.4.1 缺 dsh-client-ui-primitives → 回退 0.4.0 或补装缺失依赖)
56
+
57
+ 4. npm 纯净来源 → 升 npm 最新
58
+ 条件: source ∈ {npm, official} 且 本地 < npm latest
59
+ 动作:
60
+ a. 更新 profile dependency 声明(pnpm add/update or 改 package.json + pnpm install)
61
+ b. 安装后校验实体版本(见 §pnpm 假执行)
62
+ c. 若目标版本要求 DSH 高于当前 → 提示用户, 不硬升
63
+
64
+ 5. Windows EPERM 锁(两段式):
65
+ 条件: 安装报 EPERM/EBUSY(文件被正在运行的 DSH 占用)
66
+ 动作:
67
+ a. 检查插件中心是否已有 pending 机制: 有则走 pending 预下载(插件中心重启后自动安装)
68
+ b. 无则给出 CLI 指令: 关闭应用后在终端执行, 回传 command 字段
69
+ (禁止强制删除被锁文件)
70
+
71
+ 6. pnpm 假执行校验:
72
+ 条件: pnpm 命令 exit 0 但实体版本没变
73
+ 动作: 读 profile/node_modules/<pkg>/package.json 的 version
74
+ a. 版本已更新 → 真成功
75
+ b. 版本没变 → 重试一次; 再失败则回传手动命令, 不谎报成功
76
+ ```
77
+
78
+ ## 工具白名单(越权即拒绝)
79
+
80
+ **允许:**
81
+ - 读: `pnpm view` / `npm view` / `git log` / 读 profile 内 package.json、node_modules、vendor
82
+ - 写: 仅限 **信息包 `profileDir` 声明的那一个 profile** 的依赖声明与 node_modules(`pnpm add` / `pnpm update` / `pnpm install`,一律以该目录为 cwd)
83
+ - 报告: 写 `~/.dsh/plugin-center/llm-update-log.jsonl`(见回传格式)
84
+
85
+ **禁止:**
86
+ - 改 `~/.dsh/profiles/*` 之外的其他 profile
87
+ - 改系统目录、删除 DSH 内核文件、改 shell/运行时配置
88
+ - 未知来源命令、npm install 全局包、改 CI/发布脚本
89
+ - 未经用户确认的破坏性操作(删除 vendor 目录前必须报告)
90
+
91
+ ## 完成后回传格式(必须执行)
92
+
93
+ 1. **写主机状态文件(插件中心轮询的证据源)**:把决策结果以**单行 JSON** 追加到
94
+ `$env:DSH_HOME\plugin-center\llm-update-log.jsonl`(`~/.dsh/plugin-center/` 下):
95
+ ```powershell
96
+ Add-Content -Path "$env:DSH_HOME\plugin-center\llm-update-log.jsonl" -Value '{"name":"<插件名>","action":"upgrade|keep|switch-npm|fix-peer|failed","detail":"<一句话摘要,含实体版本/命令/错误>","status":"success|pending|failed","at":<当前毫秒时间戳>}'
97
+ ```
98
+ 字段要求:`status` 只允许 `success` / `pending` / `failed`;`detail` 一行内写完;
99
+ `at` 填当前毫秒时间戳(PowerShell: `[DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds()`);
100
+ action=keep 表示「保持不动、未更新」——插件中心据此显示「保持」而非「已更新」。
101
+ 2. 同时在会话最后一条消息用同一格式回传(供用户阅读),例如:
102
+ ```
103
+ action: upgrade
104
+ detail: dsh-dream-skin 8.27.0 → 8.28.0, pnpm update 完成, 实体版本已校验
105
+ status: success
106
+ ```
107
+ > 忘记写状态文件时,插件中心会用 20 分钟兜底保留「执行中」并提示查看会话——务必写。
108
+
109
+ ## 常见陷阱
110
+
111
+ - **版本比较**用数值逐段比较(0.9.10 > 0.9.9),不要用字符串或只比主版本。
112
+ - **服务级依赖(致命,2026-08-29 二次血泪)**:升级前必须核对目标版本的 `client inject`/host 服务依赖是否为当前内核所提供——**SSiD 内核 0.1.1-rc.2 没有 `remote.session` Remote BFF 服务**(SSiD 走 `/plugin-center` 式 RPC channel)。dsh-sidebar-qa 0.4.1/0.4.2 的客户端依赖 `remote.session` → 装上升级后内核启动即「Failed to load plugins (pending waiting for service: remote.session)」。**peer 满足 ≠ 服务满足**:0.4.2 的 peer 全部满足,但服务缺失。判定:反编译/读目标版本 client.js 的 inject 列表,有 `remote.*` 且当前 profile 无 `@deepseek-ai/dsh-*remotes*` 对应服务 → 不兼容保持现状。
113
+ - **npm 范围漂移**:profile 声明常为 `^0.4.0`,pnpm 会把 `^0.4.0` 浮到 `0.4.2`;升级后核对实体版本,必要时把声明钉死到精确版本并在 detail 说明钉死原因。
114
+ - **SSiD 预置插件**:升级后需同步归档(profile-template / vendor 目录),否则打包时被旧版覆盖——在 detail 中注明「需归档同步」。
115
+ - **hot 通道**:纯前端插件更新可能已热生效,升级成功后仍建议重启一次确认加载无错。
116
+
117
+ ## 与插件中心 UI 的关系
118
+
119
+ - 插件中心「LLM 更新」按钮把信息包注入本会话;本会话即「插件更新」会话(复用同名会话)。
120
+ - 升级完成后回到「已安装 / 更新」页核对:实体版本、是否还出现在更新列表、是否标了「待重启」。
121
+ - 若插件中心显示「更新假成功」,按 §6 重新校验并把结果回传。