dsh-plugin-update 0.5.2 → 0.5.3
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/CHANGELOG.md +11 -0
- package/dist/host.js +34 -1
- package/dist/panel.d.ts +9 -2
- package/dist/panel.js +47 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
格式为 Keep-a-Changelog 子集:`Added/Fixed/Changed` 必写,`Deprecated/Removed/Security` 有则透传,`Unreleased` 面板忽略,禁止 git-log 直倒。面板缺日志时中性提示,不挡安装。
|
|
4
4
|
|
|
5
|
+
## [0.5.3] - 2026-10-06
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- 进入面板自动查一次新版(#46 结论固化 #48):首绘 loading 后先只读本地刷新,拿到活体快照后条件自动查一次;轮询心跳永远只读本地、不触发查新版;抑制谓词 `pendingAutoCheck` 为纯函数,仅快照任务态 installing/verifying 或已有查/装在途时不发起,同范围忙/凭证过期/各类阻拦一律不抑制,无活体快照不发起;复用手动查同一通路与“正在查新版…”提示;并发只信服务端真相源(面板 busyAct 互斥 + checking 在途复用 + 2s 复用窗口),卸载靠 mounted 丢弃;失败无退避,只渲染既有失败文案与复制诊断,手动查清日志退避、关闭重开立即重问;embedded/dialog 一致;pollMs 不影响时机;四电话形状与快照六字段零变更。
|
|
9
|
+
- 关闭按钮住右下角独立 footer 区(#47 定案 A):第一章 actions 不再画 close-view,内核末尾 05 章之后新增 `.dsh-upd-footer`(dialog + 非只读渲染才有),按钮原 title/data-action 原样搬入;embedded 无面板自带关闭(宿主框架自带关);默认 + D5 只换肤、DOM 同序;act/Esc/onCloseRequested 语义一字未动。
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- 入口件 direct 断言收紧:区分入口自身空参预查与面板挂载带 includeQueue 自查(面板挂载即自查归面板)。
|
|
13
|
+
- 面板安装复用断言更新:mount 自动查已拿凭证时安装直接复用,不另查(无 receipt 回退见 panel-auto-check 用例)。
|
|
14
|
+
- 测试:新增 tests/panel-auto-check.test.mjs 11 项(纯函数、正常/抑制/阻拦仍查、慢网单发、卸载丢弃、手动重问、轮询不查、失败无退避、安装复用凭证),tests/panel-close-footer-47.test.mjs 5 项随前一提交;全量 637 计、636 过、0 败、1 跳(既有 derive-client 跳过)。
|
|
15
|
+
|
|
5
16
|
## [0.5.2] - 2026-10-06
|
|
6
17
|
|
|
7
18
|
### Added
|
package/dist/host.js
CHANGED
|
@@ -532,7 +532,40 @@ function loggedPhone(method, kind, pluginId, fn, diagCtx) {
|
|
|
532
532
|
} catch {
|
|
533
533
|
diag = void 0;
|
|
534
534
|
}
|
|
535
|
-
|
|
535
|
+
let failReader = null;
|
|
536
|
+
try {
|
|
537
|
+
const failConfig = diagCtx?.config;
|
|
538
|
+
const failOverrides = diagCtx?.readerOverrides ?? {};
|
|
539
|
+
if (failConfig && (wantsEnv(safeArgs) || queueArgsOf(safeArgs).includeQueue)) {
|
|
540
|
+
failReader = await getSharedReader(pluginId, failConfig, {
|
|
541
|
+
...failOverrides,
|
|
542
|
+
profileDir: safeArgs && safeArgs.profileDir ? String(safeArgs.profileDir) : failOverrides.profileDir
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
} catch {
|
|
546
|
+
failReader = null;
|
|
547
|
+
}
|
|
548
|
+
let envPatch = {};
|
|
549
|
+
try {
|
|
550
|
+
if (failReader && wantsEnv(safeArgs)) {
|
|
551
|
+
const env = await readEnvForPanel(failReader);
|
|
552
|
+
if (env) envPatch = { env };
|
|
553
|
+
}
|
|
554
|
+
} catch {
|
|
555
|
+
envPatch = {};
|
|
556
|
+
}
|
|
557
|
+
let queuePatch = {};
|
|
558
|
+
try {
|
|
559
|
+
const { includeQueue, showOthers } = queueArgsOf(safeArgs);
|
|
560
|
+
if (failReader && includeQueue) {
|
|
561
|
+
const requestIdForQueue = safeArgs && typeof safeArgs.requestId === "string" ? String(safeArgs.requestId) : void 0;
|
|
562
|
+
const q = visibleQueueFor(await failReader.readQueuePruned(), pluginId, showOthers, requestIdForQueue);
|
|
563
|
+
if (q) queuePatch = { queue: q };
|
|
564
|
+
}
|
|
565
|
+
} catch {
|
|
566
|
+
queuePatch = {};
|
|
567
|
+
}
|
|
568
|
+
return { ok: false, ...payload, ...diag ? { diag } : {}, ...envPatch, ...queuePatch };
|
|
536
569
|
}
|
|
537
570
|
};
|
|
538
571
|
}
|
package/dist/panel.d.ts
CHANGED
|
@@ -139,7 +139,7 @@ export interface PanelDiagnosticInput {
|
|
|
139
139
|
installedVersion?: string | null;
|
|
140
140
|
latestVersion?: string | null;
|
|
141
141
|
hostKind?: string | null;
|
|
142
|
-
/** 使用范围名:装到哪个 profile
|
|
142
|
+
/** 使用范围名:装到哪个 profile 是排错第一信息;旧复制不传则该段不出现,新复制块恒显(缺省为未知)。 */
|
|
143
143
|
profileName?: string | null;
|
|
144
144
|
queuePosition?: number | null;
|
|
145
145
|
requestId?: string | null;
|
|
@@ -182,7 +182,7 @@ export interface UpdateDiagCopyInput extends PanelDiagnosticInput {
|
|
|
182
182
|
* 组出 [update-diag] 复制块(双形态同序;调用方直接拿去粘工单/issue,已脱敏)。
|
|
183
183
|
* 第一性:顺序码→摘要→来源(#18 定),怎么办是面板页脚放最后,不插断三元组;
|
|
184
184
|
* 缺省即省略(#18):路由/请求/检查/阶段等缺失即不出现,不占位“未知”;
|
|
185
|
-
*
|
|
185
|
+
* 插件/版本/宿主/使用范围/队列恒显(面板侧显式值兜底),摘要缺省给人话,源缺省给人话(省略本身即信息,人读不懂所以必须说)。
|
|
186
186
|
*/
|
|
187
187
|
export declare function buildUpdateDiagCopy(input: UpdateDiagCopyInput): string;
|
|
188
188
|
export declare function createMemorySkipStore(now?: () => number): PanelSkipStore;
|
|
@@ -257,6 +257,13 @@ export interface PanelRenderInput extends PanelViewInput {
|
|
|
257
257
|
export declare function renderUpdatePanelKernel(input: PanelRenderInput, view: PanelView): string;
|
|
258
258
|
/** 整面板 HTML(含样式;重绘即整体替换 innerHTML,故每次都带 style 也只留一份)。 */
|
|
259
259
|
export declare function renderUpdatePanelHTML(input: PanelRenderInput): string;
|
|
260
|
+
/**
|
|
261
|
+
* mount 自动查抑制谓词(#48:#46 结论固化,纯函数):
|
|
262
|
+
* 仅当快照任务态为 installing/verifying,或已有查/装在途动作时不发起;
|
|
263
|
+
* 同范围忙、凭证过期、各类阻拦一律不抑制(前两者正是要刷新/重建凭证时)。
|
|
264
|
+
* 无活体快照(null)也不发起:首个只读刷新没拿到快照时不猜。
|
|
265
|
+
*/
|
|
266
|
+
export declare function pendingAutoCheck(snapshot: UpdateSnapshot | null, busyAct: 'check' | 'install' | null): boolean;
|
|
260
267
|
/**
|
|
261
268
|
* 挂载整组件(面板侧一行即跑):
|
|
262
269
|
* ```js
|
package/dist/panel.js
CHANGED
|
@@ -206,6 +206,7 @@ function buildUpdateDiagCopy(input) {
|
|
|
206
206
|
const checkRaw = diag.checkId ?? input.checkId;
|
|
207
207
|
const queue = queueTextOf(input.queuePosition ?? null);
|
|
208
208
|
const prov = [`\u63D2\u4EF6=${pluginName}`, `\u7248\u672C=${runVer}\u2192${instVer}`, `\u5BBF\u4E3B=${host}`];
|
|
209
|
+
prov.push(`\u4F7F\u7528\u8303\u56F4=${pickText(input.profileName, "\u672A\u77E5")}`);
|
|
209
210
|
if (typeof routeRaw === "string" && routeRaw.trim()) prov.push(`\u8DEF\u7531=${routeRaw.trim()}`);
|
|
210
211
|
if (diag.stage) prov.push(`\u9636\u6BB5=${diag.stage}`);
|
|
211
212
|
if (diag.method) prov.push(`\u65B9\u6CD5=${diag.method}`);
|
|
@@ -541,6 +542,10 @@ const UPDATE_PANEL_CSS = [
|
|
|
541
542
|
".dsh-upd-strip-k{display:block;font-size:11px;letter-spacing:.14em;opacity:.7}",
|
|
542
543
|
".dsh-upd-strip-v{font-family:Consolas,Menlo,monospace;font-size:12.5px}",
|
|
543
544
|
".dsh-upd-chapter{margin-top:14px;padding-top:10px;border-top:1px solid var(--dsh-upd-line,#e5e7eb)}",
|
|
545
|
+
// 右下角独立 footer 区(#47 定案 A):与第一章 actions 脱钩,右对齐,一次找到。
|
|
546
|
+
".dsh-upd-footer{display:flex;align-items:center;justify-content:flex-end;gap:10px;margin-top:14px;padding-top:10px;border-top:1px solid var(--dsh-upd-line,#e5e7eb)}",
|
|
547
|
+
".dsh-upd-foot-note{margin-right:auto;font-size:12px;opacity:.7}",
|
|
548
|
+
".dsh-upd-footer button{margin:0}",
|
|
544
549
|
".dsh-upd-chap-head{display:flex;align-items:baseline;gap:10px;margin-bottom:6px}",
|
|
545
550
|
".dsh-upd-chap-no{font-size:13px;font-style:italic;opacity:.6}",
|
|
546
551
|
".dsh-upd-chap-title{font-size:14px;margin:0}",
|
|
@@ -665,6 +670,9 @@ const UPDATE_PANEL_D5_CSS = [
|
|
|
665
670
|
'background:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2720%27 height=%2720%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27%238a5a00%27 stroke-width=%272%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27%3E%3Cpath d=%27M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z%27/%3E%3Cline x1=%2712%27 y1=%279%27 x2=%2712%27 y2=%2713%27/%3E%3Cline x1=%2712%27 y1=%2717%27 x2=%2712.01%27 y2=%2717%27/%3E%3C/svg%3E") no-repeat center/20px 20px}',
|
|
666
671
|
'.dsh-upd[data-theme="d5-paper"] .dsh-upd-banner>div:first-child{overflow:hidden;text-overflow:ellipsis}',
|
|
667
672
|
'.dsh-upd[data-theme="d5-paper"] .dsh-upd-actions{flex-wrap:wrap}',
|
|
673
|
+
// footer 只换肤(#47 定案 A + D5 约束:不换 DOM 顺序;复制诊断永不隐藏,本串不动它)。
|
|
674
|
+
'.dsh-upd[data-theme="d5-paper"] .dsh-upd-footer{margin-top:26px;padding-top:16px;border-top:1px solid var(--d5-line)}',
|
|
675
|
+
'.dsh-upd[data-theme="d5-paper"] .dsh-upd-foot-note{color:var(--d5-muted)}',
|
|
668
676
|
// —— 档案头(原型 :208-211 `.filehead`:serif 插件名 22px + 使用范围 + profile 牌;右侧留章位)——
|
|
669
677
|
'.dsh-upd[data-theme="d5-paper"] .dsh-upd-head{display:flex;gap:16px;align-items:baseline;flex-wrap:wrap;padding-right:120px}',
|
|
670
678
|
'.dsh-upd[data-theme="d5-paper"] .dsh-upd-name{font-family:var(--d5-serif);font-size:22px;font-weight:700}',
|
|
@@ -776,9 +784,6 @@ function renderUpdatePanelKernel(input, view) {
|
|
|
776
784
|
if (snapshot) {
|
|
777
785
|
actions.push(`<button type="button" data-action="copy-diag" title="\u590D\u5236\u5DF2\u8131\u654F\u8BCA\u65AD\uFF0C\u76F4\u63A5\u7C98\u7ED9\u63D2\u4EF6\u4F5C\u8005">\u590D\u5236\u8BCA\u65AD</button>`);
|
|
778
786
|
}
|
|
779
|
-
if (mode === "dialog") {
|
|
780
|
-
actions.push(`<button type="button" data-action="close-view" title="\u5173\u95ED\u9762\u677F\uFF08\u5B89\u88C5\u5728\u5BBF\u4E3B\u4FA7\u7EE7\u7EED\u8DD1\uFF0C\u53EF\u91CD\u5F00\u6062\u590D\u663E\u793A\uFF09">\u5173\u95ED</button>`);
|
|
781
|
-
}
|
|
782
787
|
actions.push("</div>");
|
|
783
788
|
}
|
|
784
789
|
actions.push(progressBar(snapshot));
|
|
@@ -889,6 +894,11 @@ ${changelogHTML}
|
|
|
889
894
|
view.showManual && manual ? `<div class="dsh-upd-manual"><div>\u624B\u5DE5\u515C\u5E95\u547D\u4EE4\uFF08\u590D\u5236\u6574\u884C\u6267\u884C\uFF09\uFF1A</div><code>${escapeHtml(manual)}</code></div>` : `<div class="dsh-upd-manual"><div class="dsh-upd-changelog-neutral">\u5F53\u524D\u6CA1\u6709\u53EF\u7528\u7684\u624B\u5DE5\u547D\u4EE4\uFF08\u8BA4\u4E0D\u51FA\u4F7F\u7528\u8303\u56F4\u6216\u5C5E\u6E90\u7801\u5B89\u88C5\u65F6\u4E0D\u7ED9\uFF09\u3002</div></div>`
|
|
890
895
|
)
|
|
891
896
|
);
|
|
897
|
+
if (showActions && mode === "dialog") {
|
|
898
|
+
parts.push(
|
|
899
|
+
`<div class="dsh-upd-footer"><span class="dsh-upd-foot-note">\u5B89\u88C5\u5728\u5BBF\u4E3B\u4FA7\u7EE7\u7EED\u8DD1\uFF0C\u91CD\u5F00\u6062\u590D\u663E\u793A</span><button type="button" data-action="close-view" title="\u5173\u95ED\u9762\u677F\uFF08\u5B89\u88C5\u5728\u5BBF\u4E3B\u4FA7\u7EE7\u7EED\u8DD1\uFF0C\u53EF\u91CD\u5F00\u6062\u590D\u663E\u793A\uFF09">\u5173\u95ED</button></div>`
|
|
900
|
+
);
|
|
901
|
+
}
|
|
892
902
|
return parts.join("\n");
|
|
893
903
|
}
|
|
894
904
|
function renderUpdatePanelHTML(input) {
|
|
@@ -958,6 +968,13 @@ async function defaultCopyText(text) {
|
|
|
958
968
|
} catch {
|
|
959
969
|
}
|
|
960
970
|
}
|
|
971
|
+
function pendingAutoCheck(snapshot, busyAct) {
|
|
972
|
+
if (busyAct === "check" || busyAct === "install") return false;
|
|
973
|
+
if (!snapshot) return false;
|
|
974
|
+
const st = snapshot?.job?.state;
|
|
975
|
+
if (st === "installing" || st === "verifying") return false;
|
|
976
|
+
return true;
|
|
977
|
+
}
|
|
961
978
|
function mountUpdatePanel(container, options) {
|
|
962
979
|
if (!container || typeof container.innerHTML !== "string") {
|
|
963
980
|
throw new Error("[dsh-plugin-update] \u6302\u8F7D\u9762\u677F\u9700\u8981\u4E00\u4E2A\u6709 innerHTML \u7684\u5BB9\u5668");
|
|
@@ -1076,8 +1093,8 @@ function mountUpdatePanel(container, options) {
|
|
|
1076
1093
|
if (isObject(env)) {
|
|
1077
1094
|
const pn = env["profileName"];
|
|
1078
1095
|
const hk = env["environmentKind"];
|
|
1079
|
-
if (typeof pn === "string" && pn) envProfileName = pn;
|
|
1080
|
-
if (typeof hk === "string" && hk) envHostKind = hk;
|
|
1096
|
+
if (typeof pn === "string" && pn.trim()) envProfileName = pn.trim();
|
|
1097
|
+
if (typeof hk === "string" && hk.trim()) envHostKind = hk.trim();
|
|
1081
1098
|
}
|
|
1082
1099
|
lastError = null;
|
|
1083
1100
|
lastErrorKind = null;
|
|
@@ -1086,6 +1103,21 @@ function mountUpdatePanel(container, options) {
|
|
|
1086
1103
|
lastError = typeof reply["error"] === "string" ? reply["error"] : "check-failed";
|
|
1087
1104
|
lastErrorKind = typeof reply["errorKind"] === "string" && reply["errorKind"].trim() ? reply["errorKind"].trim() : null;
|
|
1088
1105
|
lastDiag = Object.prototype.hasOwnProperty.call(reply, "diag") ? reply["diag"] : null;
|
|
1106
|
+
try {
|
|
1107
|
+
const env = reply["env"];
|
|
1108
|
+
if (isObject(env)) {
|
|
1109
|
+
const pn = env["profileName"];
|
|
1110
|
+
const hk = env["environmentKind"];
|
|
1111
|
+
if (typeof pn === "string" && pn.trim()) envProfileName = pn.trim();
|
|
1112
|
+
if (typeof hk === "string" && hk.trim()) envHostKind = hk.trim();
|
|
1113
|
+
}
|
|
1114
|
+
} catch {
|
|
1115
|
+
}
|
|
1116
|
+
try {
|
|
1117
|
+
const q = asQueue(reply["queue"]);
|
|
1118
|
+
if (q) queue = q;
|
|
1119
|
+
} catch {
|
|
1120
|
+
}
|
|
1089
1121
|
}
|
|
1090
1122
|
}
|
|
1091
1123
|
function pendingAutoChangelogVersion() {
|
|
@@ -1278,7 +1310,8 @@ function mountUpdatePanel(container, options) {
|
|
|
1278
1310
|
runningVersion: snapshot?.runningVersion ?? null,
|
|
1279
1311
|
installedVersion: snapshot?.installedVersion ?? null,
|
|
1280
1312
|
latestVersion: snapshot?.latestVersion ?? null,
|
|
1281
|
-
hostKind,
|
|
1313
|
+
hostKind: hostKind ?? envHostKind,
|
|
1314
|
+
profileName: profileNameOption ?? envProfileName,
|
|
1282
1315
|
queuePosition: queue?.position ?? null,
|
|
1283
1316
|
requestId,
|
|
1284
1317
|
checkId: receipt?.checkId ?? null,
|
|
@@ -1410,7 +1443,13 @@ function mountUpdatePanel(container, options) {
|
|
|
1410
1443
|
if (h && typeof h.unref === "function") h.unref();
|
|
1411
1444
|
} catch {
|
|
1412
1445
|
}
|
|
1413
|
-
void
|
|
1446
|
+
void (async () => {
|
|
1447
|
+
await refresh();
|
|
1448
|
+
try {
|
|
1449
|
+
if (pendingAutoCheck(snapshot, busyAct)) void act("check");
|
|
1450
|
+
} catch {
|
|
1451
|
+
}
|
|
1452
|
+
})();
|
|
1414
1453
|
return { refresh, act, setMode, setTheme, setShowOthers, setChangelogMarkdown, unmount };
|
|
1415
1454
|
}
|
|
1416
1455
|
import { buildPhoneNames as buildPhoneNames2 } from "./config.js";
|
|
@@ -1485,6 +1524,7 @@ export {
|
|
|
1485
1524
|
normalizeQueueState,
|
|
1486
1525
|
panelViewModel,
|
|
1487
1526
|
parseChangelog2 as parseChangelog,
|
|
1527
|
+
pendingAutoCheck,
|
|
1488
1528
|
queuePositionOf,
|
|
1489
1529
|
readDiagTolerant,
|
|
1490
1530
|
redactForCopy,
|