dsh-opencode-palette 2.0.8 → 2.0.9

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.
package/lib/client.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
- * dsh-opencode-palette v2.0.8 — 浏览器半(构建产物,勿手改)
2
+ * dsh-opencode-palette v2.0.9 — 浏览器半(构建产物,勿手改)
3
3
  * 数据驱动管线:opencode v1.18.12 官方主题 JSON → 颜色解析 → DSH 适配注入
4
- * 面板「检查更新」:dsh-plugin-update 客户端入口经构建期内联(vendor)
4
+ * 面板「检查更新」:dsh-plugin-update 客户端入口经构建期内联(宿主半走真依赖)
5
5
  * 源:src/engine/* + runtime/*.mjs + npm 包 dsh-log / dsh-plugin-update 的客户端入口
6
6
  */
7
7
  window.__ModuleLoader__.load({
@@ -12,7 +12,7 @@ window.__ModuleLoader__.load({
12
12
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" })
13
13
  var __mods = {};
14
14
  (function () {
15
- // AUTO-GENERATED by node packages/dsh-plugin-update/build.mjs — DO NOT EDIT. Source: packages/dsh-plugin-update/src/config.ts
15
+ // AUTO-GENERATED by node build.mjs — DO NOT EDIT. Source: src/config.ts
16
16
  const DEFAULT_PREFIX = "wf";
17
17
  const PHONE_ACTIONS = ["updateStatus", "updateCheck", "updateInstall"];
18
18
  const DEFAULT_TARGET_PACKAGE = "dsh-mattpocock-skills-deck";
@@ -91,9 +91,10 @@ __mods["upd-config"] = { BACKUP_FILE, DEFAULT_CHECK_TIMEOUT_MS, DEFAULT_CONFIRMA
91
91
 
92
92
  })();
93
93
  (function () {
94
- // AUTO-GENERATED by node packages/dsh-plugin-update/build.mjs — DO NOT EDIT. Source: packages/dsh-plugin-update/src/commands.ts
94
+ // AUTO-GENERATED by node build.mjs — DO NOT EDIT. Source: src/commands.ts
95
95
  const PACKAGE_NAME = "dsh-mattpocock-skills-deck";
96
96
  const NPM_REGISTRY = "https://registry.npmjs.org/";
97
+ const MANAGER_TARGET_RE = /^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/;
97
98
  const INSTALL_TIMEOUT_MS = 15 * 6e4;
98
99
  function validVersion(v) {
99
100
  return typeof v === "string" && /^\d+\.\d+\.\d+$/.test(v);
@@ -132,11 +133,21 @@ function installRecipe(input) {
132
133
  const version = input?.version;
133
134
  if (!name || !validVersion(version)) return null;
134
135
  const kind = input?.environmentKind;
135
- if (kind !== "desktop" && kind !== "cli") return null;
136
+ if (kind !== "desktop" && kind !== "desktop-manager" && kind !== "cli") return null;
136
137
  const targetName = input?.targetPackageName ?? PACKAGE_NAME;
137
138
  const registry = input?.registryUrl ?? NPM_REGISTRY;
138
139
  const timeoutMs = input?.timeoutMs ?? INSTALL_TIMEOUT_MS;
139
140
  if (!targetName || !registry) return null;
141
+ if (kind === "desktop-manager") {
142
+ if (!MANAGER_TARGET_RE.test(targetName)) return null;
143
+ return {
144
+ route: "desktop-manager",
145
+ profileName: name,
146
+ version,
147
+ pluginArgs: ["add", `${targetName}@${version}`],
148
+ timeoutMs
149
+ };
150
+ }
140
151
  return {
141
152
  route: kind === "desktop" ? "desktop-service" : "cli-process",
142
153
  profileName: name,
@@ -170,7 +181,7 @@ __mods["upd-commands"] = { INSTALL_TIMEOUT_MS, installRecipe, manualCommand };
170
181
 
171
182
  })();
172
183
  (function () {
173
- // AUTO-GENERATED by node packages/dsh-plugin-update/build.mjs — DO NOT EDIT. Source: packages/dsh-plugin-update/src/client.ts
184
+ // AUTO-GENERATED by node build.mjs — DO NOT EDIT. Source: src/client.ts
174
185
  const { buildPhoneNames, DEFAULT_PANEL_POLL_MS, MIN_PANEL_POLL_MS } = __mods["upd-config"];
175
186
  const { buildPhoneName, buildPhoneNames: buildPhoneNames2 } = __mods["upd-config"];
176
187
  const { manualCommand: manualCommand2 } = __mods["upd-commands"];
@@ -10090,7 +10101,7 @@ const STORAGE_KEY = 'dsh.opencode-palette.v2'
10090
10101
  const LEGACY_STORAGE_KEY = 'dsh.opencode-tui-theme.v2'
10091
10102
  const DEFAULT_STATE = { enabled: true, theme: 'opencode', mode: 'mono', size: 13, fontKey: 'JetBrains Mono' }
10092
10103
  // 构建时由 scripts/build-client.mjs 替换为 package.json 版本(面板底部署小字)
10093
- const PALETTE_VERSION = '2.0.8'
10104
+ const PALETTE_VERSION = '2.0.9'
10094
10105
 
10095
10106
  function getReact() {
10096
10107
  if (typeof require === 'function') { try { return require('react') } catch (e) { /* 动态版无 require */ } }
package/lib/index.js CHANGED
@@ -11,13 +11,12 @@
11
11
  * 走 DSH 公开的 /api 载体:宿主 connection.fetch.register 注册精确路由,客户端
12
12
  * connection.rpc.call('/api', 'opencode-palette', { method, payload })——与 deck、im-companion 同构。
13
13
  *
14
- * 更新包为什么走 ./vendor/ 相对路径而不是 import 'dsh-plugin-update':
15
- * 更新包的读取器用 containingPackage(import.meta.url, 目标包名) 从【自己的文件位置】往上找目标包。
16
- * 以 npm 依赖形态安装时它住在 <profile>/node_modules/dsh-plugin-update,往上永远找不到
17
- * dsh-opencode-palette,于是:运行版本读不到(host 入口直接抛 unknown-profile),且环境判定里的
18
- * sameLoadedPackage 恒为假 → blockedReason 恒为 installation-changed → 一键升级永远不可用。
19
- * 把它的 dist 原样放进本包 lib/vendor/ 下,import.meta.url 就落在本包内,两条判定都成立。
20
- * vendor 副本由构建从 npm 包复制(见 scripts/build-client.mjs),门禁断言与 npm 包逐字节一致。
14
+ * 更新包以**普通依赖形态**接入(`import { createHostUpdate } from 'dsh-plugin-update'`,见 package.json
15
+ * 的 `dependencies`)。0.1.x 曾被迫把它的 dist vendor 进本包:那时它用 containingPackage(import.meta.url, …)
16
+ * 从【自己的文件位置】往上找目标包,以依赖形态安装时永远找不到本包 → unknown-profile,且
17
+ * sameLoadedPackage 恒假 → installation-changed → 一键升级永远不可用。
18
+ * 0.2.0 起改为**按包名解析**(清单直解 → 入口反查 → node_modules 步行 → 自锚定兜底),依赖形态直接可用,
19
+ * 于是 vendor 全部删除。历史决策与推翻过程见 docs/adr/0001-vendor-dsh-plugin-update.md。
21
20
  */
22
21
  import { existsSync, readFileSync } from 'node:fs'
23
22
  import { mkdir, readdir, readFile, unlink, writeFile } from 'node:fs/promises'
@@ -25,10 +24,12 @@ import { homedir } from 'node:os'
25
24
  import { dirname, join } from 'node:path'
26
25
  import { fileURLToPath } from 'node:url'
27
26
  import { createHostLog, registerHostLogPhones } from 'dsh-log/host'
28
- import { createHostUpdate } from './vendor/dsh-plugin-update/host.js'
29
- import { buildPhoneNames, DEFAULT_REGISTRY } from './vendor/dsh-plugin-update/config.js'
27
+ import { createHostUpdate } from 'dsh-plugin-update'
30
28
  import { PLUGIN_ID, PHONE_PREFIX, ROUTE_PATH, TARGET_PACKAGE_NAME } from './channel.mjs'
31
29
 
30
+ /** 官方源。更新包不导出这个常量(它的默认值也是它),探针自用,故本地声明一次。 */
31
+ const DEFAULT_REGISTRY = 'https://registry.npmjs.org/'
32
+
32
33
  export const name = PLUGIN_ID
33
34
  // 通道要 connection;subprocess / desktopProfiles / desktopPnpm 由更新包自己按需取(它内部注入),
34
35
  // 不写进顶层 inject:普通 DSH 没有 desktop* 服务,写进顶层会让插件在普通宿主里装配失败。
@@ -295,8 +296,18 @@ export function wrapUpdateCheck(handler, deps) {
295
296
  }
296
297
  }
297
298
 
298
- /** 宿主半装配入口:建日志库 → 建更新电话 → 合成电话表 → 注册通道。 */
299
- export function apply(ctx) {
299
+ /** 宿主半装配入口:建日志库 → 建更新电话 → 合成电话表 → 注册通道。
300
+ *
301
+ * 第二个参数只给测试用:`{ readerOverrides }` 会与默认的 `{ runningVersion }` 合并后
302
+ * 交给更新包。生产环境永远不传(更新包按包名自动解析目标包与使用范围);
303
+ * 只有自动解析对不上时(开发态 checkout、hoisted、多副本)才显式给
304
+ * `targetPackageDir`——更新包 README §6.13 的逃生口,冒烟测试用它搭假使用范围。
305
+ * 绝不传 `environmentKind` / `profileDir` / `profileName`:那两处会挡住自动探测,
306
+ * 传了升级就要改代码(更新包 README「升级本包」一节)。 */
307
+ export function apply(ctx, opts) {
308
+ const extraOverrides = (opts && opts.readerOverrides && typeof opts.readerOverrides === 'object')
309
+ ? opts.readerOverrides
310
+ : {}
300
311
  const homeDir = dshHomeDir(process.env, homedir())
301
312
  const eventList = readEventList()
302
313
 
@@ -323,14 +334,14 @@ export function apply(ctx) {
323
334
  }
324
335
 
325
336
  const update = createHostUpdate(
326
- { ctx: ctx, logCtx: { fire: function (level, event, fields) { return hostLog.store.log(level, event, fields) } }, readerOverrides: { runningVersion: runningVersion } },
337
+ { ctx: ctx, logCtx: { fire: function (level, event, fields) { return hostLog.store.log(level, event, fields) } }, readerOverrides: Object.assign({ runningVersion: runningVersion }, extraOverrides) },
327
338
  { pluginId: PLUGIN_ID, prefix: PHONE_PREFIX, targetPackageName: TARGET_PACKAGE_NAME }
328
339
  )
329
340
  for (const phoneName of Object.keys(update.handlers)) registry.set(phoneName, update.handlers[phoneName])
330
341
 
331
342
  // 查更新外面再包一层:失败重试一次,仍失败就跑探针把真实原因落日志。
332
- // 电话名从更新包派生(本文件不写字面量),装更新与查状态两条保持原样。
333
- const updateCheckPhone = buildPhoneNames(PHONE_PREFIX).updateCheck
343
+ // 电话名从更新包的返回值读(update.phoneNames),不自己拼字符串 —— 拼法与包内同一份真源。
344
+ const updateCheckPhone = update.phoneNames.updateCheck
334
345
  const rawUpdateCheck = registry.get(updateCheckPhone)
335
346
  if (typeof rawUpdateCheck === 'function') {
336
347
  registry.set(updateCheckPhone, wrapUpdateCheck(rawUpdateCheck, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-opencode-palette",
3
- "version": "2.0.8",
3
+ "version": "2.0.9",
4
4
  "description": "让 DeepSeek Harness 穿上 38 款经典皮肤——东京的霓虹夜色、德古拉的暗红月光、复古工坊的暖黄灯火、黑客帝国的数字雨、玫瑰松林间的风……一键换肤,即点即换,重启不丢。38 legendary skins for DeepSeek Harness — tokyonight's neon dusk, dracula's crimson moon, gruvbox's retro glow, the matrix's digital rain, rose-pine's rosewood calm… one click, instant, persisted.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -33,9 +33,11 @@
33
33
  "url": "https://github.com/FeatherHunter/dsh-opencode-palette/issues"
34
34
  },
35
35
  "dependencies": {
36
- "dsh-log": "0.2.1"
36
+ "dsh-log": "0.2.1",
37
+ "dsh-plugin-update": "^0.2.0"
37
38
  },
38
39
  "engines": {
40
+ "node": ">=22",
39
41
  "dsh": ">=0.2.0-rc.1"
40
42
  },
41
43
  "dsh": {
@@ -1,30 +0,0 @@
1
- // 派生文件(构建生成,人手不改):由 npm 包 dsh-plugin-update@0.1.1 的 dist/ 原样复制。
2
- // 为什么必须放进本包:更新包的读取器用 containingPackage(import.meta.url, 目标包名) 从自己的文件位置
3
- // 往上找目标包;以 npm 依赖形态安装时它住在别的目录,会抛 unknown-profile 且环境判定恒为 installation-changed。
4
- // 门禁:tests/update-panel.test.mjs 断言本副本与 npm 包逐字节一致(除本头部)。
5
- // vendor-source: dsh-plugin-update@0.1.1 dist/client.js
6
- // AUTO-GENERATED by node packages/dsh-plugin-update/build.mjs — DO NOT EDIT. Source: packages/dsh-plugin-update/src/client.ts
7
- import { buildPhoneNames, DEFAULT_PANEL_POLL_MS, MIN_PANEL_POLL_MS } from "./config.js";
8
- import { buildPhoneName, buildPhoneNames as buildPhoneNames2 } from "./config.js";
9
- import { manualCommand as manualCommand2 } from "./commands.js";
10
- const CLIENT_POLL = {
11
- defaultMs: DEFAULT_PANEL_POLL_MS,
12
- minMs: MIN_PANEL_POLL_MS
13
- };
14
- function buildClientPhoneNames(prefix) {
15
- return buildPhoneNames(prefix);
16
- }
17
- function assertPollInterval(ms) {
18
- if (typeof ms !== "number" || !Number.isFinite(ms) || ms < MIN_PANEL_POLL_MS) {
19
- throw new Error("[dsh-plugin-update] \u9762\u677F\u8F6E\u8BE2\u95F4\u9694\u975E\u6CD5\uFF1A\u4E0D\u5F97\u5C0F\u4E8E 250 \u6BEB\u79D2\uFF08\u6536\u5230 " + JSON.stringify(ms) + "\uFF09");
20
- }
21
- return ms;
22
- }
23
- export {
24
- CLIENT_POLL,
25
- assertPollInterval,
26
- buildClientPhoneNames,
27
- buildPhoneName,
28
- buildPhoneNames2 as buildPhoneNames,
29
- manualCommand2 as manualCommand
30
- };
@@ -1,85 +0,0 @@
1
- // 派生文件(构建生成,人手不改):由 npm 包 dsh-plugin-update@0.1.1 的 dist/ 原样复制。
2
- // 为什么必须放进本包:更新包的读取器用 containingPackage(import.meta.url, 目标包名) 从自己的文件位置
3
- // 往上找目标包;以 npm 依赖形态安装时它住在别的目录,会抛 unknown-profile 且环境判定恒为 installation-changed。
4
- // 门禁:tests/update-panel.test.mjs 断言本副本与 npm 包逐字节一致(除本头部)。
5
- // vendor-source: dsh-plugin-update@0.1.1 dist/commands.js
6
- // AUTO-GENERATED by node packages/dsh-plugin-update/build.mjs — DO NOT EDIT. Source: packages/dsh-plugin-update/src/commands.ts
7
- const PACKAGE_NAME = "dsh-mattpocock-skills-deck";
8
- const NPM_REGISTRY = "https://registry.npmjs.org/";
9
- const INSTALL_TIMEOUT_MS = 15 * 6e4;
10
- function validVersion(v) {
11
- return typeof v === "string" && /^\d+\.\d+\.\d+$/.test(v);
12
- }
13
- function parseTriple(v) {
14
- const parts = String(v).split(".");
15
- if (parts.length > 3) return null;
16
- const nums = [];
17
- for (const p of parts) {
18
- if (!/^\d+$/.test(p)) return null;
19
- const n = Number(p);
20
- if (!Number.isSafeInteger(n)) return null;
21
- nums.push(n);
22
- }
23
- while (nums.length < 3) nums.push(0);
24
- return [nums[0], nums[1], nums[2]];
25
- }
26
- function compareVersions(a, b) {
27
- const pa = parseTriple(a);
28
- const pb = parseTriple(b);
29
- if (!pa || !pb) throw new Error("invalid-release");
30
- for (let i = 0; i < 3; i++) {
31
- if (pa[i] < pb[i]) return -1;
32
- if (pa[i] > pb[i]) return 1;
33
- }
34
- return 0;
35
- }
36
- function usableProfileName(raw) {
37
- const name = typeof raw === "string" ? raw.trim() : "";
38
- if (!name || name.length > 255 || name.startsWith("-")) return null;
39
- if ([".", "..", "node_modules"].includes(name)) return null;
40
- return name;
41
- }
42
- function installRecipe(input) {
43
- const name = usableProfileName(input?.profileName);
44
- const version = input?.version;
45
- if (!name || !validVersion(version)) return null;
46
- const kind = input?.environmentKind;
47
- if (kind !== "desktop" && kind !== "cli") return null;
48
- const targetName = input?.targetPackageName ?? PACKAGE_NAME;
49
- const registry = input?.registryUrl ?? NPM_REGISTRY;
50
- const timeoutMs = input?.timeoutMs ?? INSTALL_TIMEOUT_MS;
51
- if (!targetName || !registry) return null;
52
- return {
53
- route: kind === "desktop" ? "desktop-service" : "cli-process",
54
- profileName: name,
55
- version,
56
- // 参数数组原样交给命令行工具:使用范围名不做引号包裹、不按空格拆分。
57
- pluginArgs: ["add", "--save-exact", `${targetName}@${version}`, `--registry=${registry}`],
58
- timeoutMs
59
- };
60
- }
61
- function manualCommand(input) {
62
- if (input.sourceInstall || input.blockedReason === "source-install" || input.blockedReason === "unknown-profile") return null;
63
- const name = usableProfileName(input.profileName);
64
- if (!name) return null;
65
- const targetName = input.targetPackageName ?? PACKAGE_NAME;
66
- const registry = input.registryUrl ?? NPM_REGISTRY;
67
- if (!targetName || !registry) return null;
68
- const arg = /^[A-Za-z0-9_.-]+$/.test(name) ? name : JSON.stringify(name);
69
- const picks = [input.latestVersion, input.jobTargetVersion, input.installedVersion].filter(validVersion);
70
- let version = picks.length > 0 ? picks[0] : "latest";
71
- try {
72
- const ranked = picks.filter((v) => compareVersions(v, input.runningVersion) >= 0);
73
- if (ranked.length > 0) {
74
- version = ranked[0];
75
- for (const v of ranked) if (compareVersions(v, version) === 1) version = v;
76
- }
77
- } catch {
78
- }
79
- return `dsh plugin --profile ${arg} add --save-exact ${targetName}@${version} --registry=${registry}`;
80
- }
81
- export {
82
- INSTALL_TIMEOUT_MS,
83
- installRecipe,
84
- manualCommand
85
- };
@@ -1,102 +0,0 @@
1
- // 派生文件(构建生成,人手不改):由 npm 包 dsh-plugin-update@0.1.1 的 dist/ 原样复制。
2
- // 为什么必须放进本包:更新包的读取器用 containingPackage(import.meta.url, 目标包名) 从自己的文件位置
3
- // 往上找目标包;以 npm 依赖形态安装时它住在别的目录,会抛 unknown-profile 且环境判定恒为 installation-changed。
4
- // 门禁:tests/update-panel.test.mjs 断言本副本与 npm 包逐字节一致(除本头部)。
5
- // vendor-source: dsh-plugin-update@0.1.1 dist/config.js
6
- // AUTO-GENERATED by node packages/dsh-plugin-update/build.mjs — DO NOT EDIT. Source: packages/dsh-plugin-update/src/config.ts
7
- const DEFAULT_PREFIX = "wf";
8
- const PHONE_ACTIONS = ["updateStatus", "updateCheck", "updateInstall"];
9
- const DEFAULT_TARGET_PACKAGE = "dsh-mattpocock-skills-deck";
10
- const DEFAULT_REGISTRY = "https://registry.npmjs.org/";
11
- const LEGACY_PLUGIN_ID = "dsh-mattpocock-skills-deck";
12
- const LEGACY_DIR_SEGMENT = "updates";
13
- const STATE_FILE = "state.json";
14
- const LOCK_FILE = "install.lock";
15
- const BACKUP_FILE = "before.json";
16
- const DEFAULT_CHECK_TIMEOUT_MS = 1e4;
17
- const DEFAULT_CONFIRMATION_TTL_MS = 10 * 6e4;
18
- const DEFAULT_INSTALL_TIMEOUT_MS = 15 * 6e4;
19
- const DEFAULT_PANEL_POLL_MS = 1e3;
20
- const RECHECK_WINDOW_MS = 2e3;
21
- const MIN_PANEL_POLL_MS = 250;
22
- function assertPluginId(value) {
23
- if (typeof value !== "string" || value.length === 0) {
24
- throw new Error("[dsh-plugin-update] \u63D2\u4EF6\u6807\u8BC6 pluginId \u5FC5\u586B\uFF1A\u987B\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32\uFF08\u6536\u5230 " + JSON.stringify(value) + "\uFF09");
25
- }
26
- if (value.includes("/") || value.includes("\\") || value.includes("\0")) {
27
- throw new Error("[dsh-plugin-update] \u63D2\u4EF6\u6807\u8BC6 pluginId \u975E\u6CD5\uFF1A\u4E0D\u5F97\u542B\u6709\u8DEF\u5F84\u5206\u9694\u7B26\uFF08\u6536\u5230 " + JSON.stringify(value) + "\uFF09");
28
- }
29
- return value;
30
- }
31
- function assertPrefix(value, role) {
32
- if (typeof value !== "string" || value.length === 0) {
33
- throw new Error("[dsh-plugin-update] " + role + " \u975E\u6CD5\uFF1A\u987B\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32\uFF08\u6536\u5230 " + JSON.stringify(value) + "\uFF09");
34
- }
35
- if (value.includes(".") || value.includes("/") || value.includes("\\") || /\s/.test(value)) {
36
- throw new Error("[dsh-plugin-update] " + role + " \u975E\u6CD5\uFF1A\u4E0D\u5F97\u542B\u6709\u70B9\u3001\u8DEF\u5F84\u5206\u9694\u7B26\u6216\u7A7A\u767D\uFF08\u6536\u5230 " + JSON.stringify(value) + "\uFF09");
37
- }
38
- return value;
39
- }
40
- function assertPositiveFinite(value, role) {
41
- if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
42
- throw new Error("[dsh-plugin-update] " + role + " \u975E\u6CD5\uFF1A\u987B\u4E3A\u6709\u9650\u5927\u4E8E 0 \u7684\u6570\uFF08\u6536\u5230 " + JSON.stringify(value) + "\uFF09");
43
- }
44
- return value;
45
- }
46
- function resolveUpdateConfig(input) {
47
- if (!input || typeof input !== "object") {
48
- throw new Error("[dsh-plugin-update] \u5EFA\u66F4\u65B0\u80FD\u529B\u7F3A\u5C11\u914D\u7F6E\uFF1A\u63D2\u4EF6\u6807\u8BC6 pluginId \u5FC5\u586B");
49
- }
50
- const pluginId = assertPluginId(input.pluginId);
51
- const prefix = input.prefix === void 0 ? DEFAULT_PREFIX : assertPrefix(input.prefix, "\u7535\u8BDD\u540D\u524D\u7F00 prefix");
52
- const targetPackageName = input.targetPackageName === void 0 ? DEFAULT_TARGET_PACKAGE : String(input.targetPackageName);
53
- if (!targetPackageName) {
54
- throw new Error("[dsh-plugin-update] \u76EE\u6807\u5305\u540D targetPackageName \u975E\u6CD5\uFF1A\u987B\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32");
55
- }
56
- const registryUrl = input.registryUrl === void 0 ? DEFAULT_REGISTRY : String(input.registryUrl);
57
- if (!registryUrl) {
58
- throw new Error("[dsh-plugin-update] \u5B98\u65B9\u6E90 registryUrl \u975E\u6CD5\uFF1A\u987B\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32");
59
- }
60
- const homeDir = input.homeDir === void 0 ? null : String(input.homeDir);
61
- const checkTimeoutMs = input.checkTimeoutMs === void 0 ? DEFAULT_CHECK_TIMEOUT_MS : assertPositiveFinite(input.checkTimeoutMs, "\u8054\u7F51\u8D85\u65F6 checkTimeoutMs");
62
- const confirmationTtlMs = input.confirmationTtlMs === void 0 ? DEFAULT_CONFIRMATION_TTL_MS : assertPositiveFinite(input.confirmationTtlMs, "\u51ED\u8BC1\u6709\u6548\u671F confirmationTtlMs");
63
- const installTimeoutMs = input.installTimeoutMs === void 0 ? DEFAULT_INSTALL_TIMEOUT_MS : assertPositiveFinite(input.installTimeoutMs, "\u5B89\u88C5\u65F6\u9650 installTimeoutMs");
64
- const panelPollMs = input.panelPollMs === void 0 ? DEFAULT_PANEL_POLL_MS : assertPositiveFinite(input.panelPollMs, "\u9762\u677F\u8F6E\u8BE2 panelPollMs");
65
- if (panelPollMs < MIN_PANEL_POLL_MS) {
66
- throw new Error("[dsh-plugin-update] \u9762\u677F\u8F6E\u8BE2 panelPollMs \u975E\u6CD5\uFF1A\u4E0D\u5F97\u5C0F\u4E8E 250 \u6BEB\u79D2\uFF08\u6536\u5230 " + JSON.stringify(input.panelPollMs) + "\uFF09");
67
- }
68
- return { pluginId, prefix, targetPackageName, registryUrl, homeDir, checkTimeoutMs, confirmationTtlMs, installTimeoutMs, panelPollMs };
69
- }
70
- function buildPhoneNames(prefix) {
71
- const checked = assertPrefix(prefix, "\u7535\u8BDD\u540D\u524D\u7F00 prefix");
72
- return {
73
- updateStatus: checked + ".updateStatus",
74
- updateCheck: checked + ".updateCheck",
75
- updateInstall: checked + ".updateInstall"
76
- };
77
- }
78
- function buildPhoneName(prefix, action) {
79
- return buildPhoneNames(prefix)[action];
80
- }
81
- export {
82
- BACKUP_FILE,
83
- DEFAULT_CHECK_TIMEOUT_MS,
84
- DEFAULT_CONFIRMATION_TTL_MS,
85
- DEFAULT_INSTALL_TIMEOUT_MS,
86
- DEFAULT_PANEL_POLL_MS,
87
- DEFAULT_PREFIX,
88
- DEFAULT_REGISTRY,
89
- DEFAULT_TARGET_PACKAGE,
90
- LEGACY_DIR_SEGMENT,
91
- LEGACY_PLUGIN_ID,
92
- LOCK_FILE,
93
- MIN_PANEL_POLL_MS,
94
- PHONE_ACTIONS,
95
- RECHECK_WINDOW_MS,
96
- STATE_FILE,
97
- assertPluginId,
98
- assertPrefix,
99
- buildPhoneName,
100
- buildPhoneNames,
101
- resolveUpdateConfig
102
- };
@@ -1,120 +0,0 @@
1
- // 派生文件(构建生成,人手不改):由 npm 包 dsh-plugin-update@0.1.1 的 dist/ 原样复制。
2
- // 为什么必须放进本包:更新包的读取器用 containingPackage(import.meta.url, 目标包名) 从自己的文件位置
3
- // 往上找目标包;以 npm 依赖形态安装时它住在别的目录,会抛 unknown-profile 且环境判定恒为 installation-changed。
4
- // 门禁:tests/update-panel.test.mjs 断言本副本与 npm 包逐字节一致(除本头部)。
5
- // vendor-source: dsh-plugin-update@0.1.1 dist/gate.js
6
- // AUTO-GENERATED by node packages/dsh-plugin-update/build.mjs — DO NOT EDIT. Source: packages/dsh-plugin-update/src/gate.ts
7
- import { assertPluginId } from "./config.js";
8
- const EVENT_LEVELS = ["error", "warn", "info", "debug"];
9
- const EVENT_KINDS = ["resident", "ondemand", "selfmon"];
10
- function isNonEmptyString(value) {
11
- return typeof value === "string" && value.length > 0;
12
- }
13
- function assertStringArray(value, what) {
14
- if (!Array.isArray(value)) throw new Error("[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355 eventList \u975E\u6CD5\uFF1A" + what + " \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u6570\u7EC4");
15
- const seen = [];
16
- for (const item of value) {
17
- if (!isNonEmptyString(item)) throw new Error("[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355 eventList \u975E\u6CD5\uFF1A" + what + " \u91CC\u6709\u7A7A\u5B57\u6BB5\u540D");
18
- if (seen.indexOf(item) >= 0) throw new Error("[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355 eventList \u975E\u6CD5\uFF1A" + what + " \u91CC\u5B57\u6BB5\u540D\u91CD\u590D\uFF1A" + item);
19
- seen.push(item);
20
- }
21
- return seen;
22
- }
23
- function parseEventListManifest(value) {
24
- if (typeof value === "string") {
25
- throw new Error("[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355 eventList \u975E\u6CD5\uFF1A\u8DEF\u5F84\u5F62\u5F0F\u8BF7\u8C03\u7528\u65B9\u81EA\u5DF1\u8BFB\u6210\u5BF9\u8C61\u518D\u4F20\u5165\uFF0C\u66F4\u65B0\u5305\u4E0D\u8BFB\u76D8");
26
- }
27
- if (!value || typeof value !== "object" || Array.isArray(value)) {
28
- throw new Error("[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355 eventList \u975E\u6CD5\uFF1A\u53EA\u6536\u5BF9\u8C61\u5F62\u5F0F\uFF08\u7A7A\u6A21\u677F\u89C1\u5305\u5185\u7684 event-list.template.json\uFF09");
29
- }
30
- const input = value;
31
- if (input["version"] !== 1) {
32
- throw new Error("[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355 eventList \u975E\u6CD5\uFF1Aversion \u73B0\u5728\u53EA\u8BA4 1\uFF08\u6536\u5230 " + JSON.stringify(input["version"]) + "\uFF09");
33
- }
34
- const pluginId = assertPluginId(input["pluginId"]);
35
- const countsRaw = input["counts"];
36
- if (!countsRaw || typeof countsRaw !== "object" || Array.isArray(countsRaw)) {
37
- throw new Error("[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355 eventList \u975E\u6CD5\uFF1Acounts \u5FC5\u987B\u662F\u542B\u4E09\u7C7B\u8BA1\u6570\u7684\u5BF9\u8C61");
38
- }
39
- const countsRecord = countsRaw;
40
- const counts = { resident: 0, ondemand: 0, selfmon: 0 };
41
- for (const kind of EVENT_KINDS) {
42
- const n = countsRecord[kind];
43
- if (typeof n !== "number" || !isFinite(n) || Math.floor(n) !== n || n < 0) {
44
- throw new Error("[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355 eventList \u975E\u6CD5\uFF1Acounts." + kind + " \u5FC5\u987B\u662F\u975E\u8D1F\u6574\u6570");
45
- }
46
- counts[kind] = n;
47
- }
48
- const eventsRaw = input["events"];
49
- if (!eventsRaw || typeof eventsRaw !== "object" || Array.isArray(eventsRaw)) {
50
- throw new Error("[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355 eventList \u975E\u6CD5\uFF1Aevents \u5FC5\u987B\u662F\u4E8B\u4EF6\u540D\u5230\u6761\u76EE\u7684\u5BF9\u8C61");
51
- }
52
- const events = {};
53
- for (const name of Object.keys(eventsRaw)) {
54
- events[name] = parseEventEntry(name, eventsRaw[name]);
55
- }
56
- return { version: 1, pluginId, counts, events };
57
- }
58
- function parseEventEntry(name, value) {
59
- if (!isNonEmptyString(name)) throw new Error("[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355 eventList \u975E\u6CD5\uFF1A\u4E8B\u4EF6\u540D\u4E0D\u80FD\u4E3A\u7A7A");
60
- if (!value || typeof value !== "object" || Array.isArray(value)) {
61
- throw new Error("[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355 eventList \u975E\u6CD5\uFF1A\u4E8B\u4EF6 " + name + " \u5FC5\u987B\u662F\u5BF9\u8C61");
62
- }
63
- const input = value;
64
- if (EVENT_LEVELS.indexOf(input["level"]) < 0) {
65
- throw new Error("[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355 eventList \u975E\u6CD5\uFF1A\u4E8B\u4EF6 " + name + " \u7684 level \u53EA\u8BB8 error\u3001warn\u3001info\u3001debug");
66
- }
67
- if (EVENT_KINDS.indexOf(input["kind"]) < 0) {
68
- throw new Error("[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355 eventList \u975E\u6CD5\uFF1A\u4E8B\u4EF6 " + name + " \u7684 kind \u53EA\u8BB8 resident\u3001ondemand\u3001selfmon");
69
- }
70
- for (const key of Object.keys(input)) {
71
- if (["level", "kind", "fields", "codes", "rules", "guard"].indexOf(key) < 0) {
72
- throw new Error("[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355 eventList \u975E\u6CD5\uFF1A\u4E8B\u4EF6 " + name + " \u6709\u4E0D\u8BA4\u8BC6\u7684\u952E " + key);
73
- }
74
- }
75
- const entry = {
76
- level: input["level"],
77
- kind: input["kind"],
78
- fields: assertStringArray(input["fields"], "\u4E8B\u4EF6 " + name + " \u7684 fields")
79
- };
80
- if (input["codes"] !== void 0) entry.codes = assertStringArray(input["codes"], "\u4E8B\u4EF6 " + name + " \u7684 codes");
81
- if (input["rules"] !== void 0) entry.rules = assertStringArray(input["rules"], "\u4E8B\u4EF6 " + name + " \u7684 rules");
82
- if (input["guard"] !== void 0) {
83
- if (typeof input["guard"] !== "string") {
84
- throw new Error("[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355 eventList \u975E\u6CD5\uFF1A\u4E8B\u4EF6 " + name + " \u7684 guard \u5FC5\u987B\u662F\u5B57\u7B26\u4E32");
85
- }
86
- entry.guard = input["guard"];
87
- }
88
- return entry;
89
- }
90
- function checkEventFields(manifest, eventName, fieldNames) {
91
- const entry = manifest.events[eventName];
92
- if (!entry) return { ok: false, unknownEvent: true, unknownFields: [] };
93
- const allowed = new Set(entry.fields);
94
- const unknownFields = (Array.isArray(fieldNames) ? fieldNames : []).filter(
95
- (field) => !allowed.has(field)
96
- );
97
- return { ok: unknownFields.length === 0, unknownEvent: false, unknownFields };
98
- }
99
- function checkEventCounts(manifest) {
100
- const actual = { resident: 0, ondemand: 0, selfmon: 0 };
101
- for (const name of Object.keys(manifest.events)) {
102
- actual[manifest.events[name].kind] += 1;
103
- }
104
- const problems = [];
105
- for (const kind of EVENT_KINDS) {
106
- if (actual[kind] !== manifest.counts[kind]) {
107
- problems.push(
108
- "[dsh-plugin-update] \u4E8B\u4EF6\u6E05\u5355\u8BA1\u6570\u5BF9\u4E0D\u4E0A\uFF1A" + kind + " \u7C7B\u5B9E\u9645 " + actual[kind] + " \u6761\uFF0C\u6E05\u5355\u81EA\u62A5 " + manifest.counts[kind] + " \u6761"
109
- );
110
- }
111
- }
112
- return { ok: problems.length === 0, problems };
113
- }
114
- export {
115
- EVENT_KINDS,
116
- EVENT_LEVELS,
117
- checkEventCounts,
118
- checkEventFields,
119
- parseEventListManifest
120
- };