@noob-stupid/dsh-plugin-console 0.3.53 → 0.3.55

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/README.md CHANGED
@@ -308,7 +308,7 @@ MIT
308
308
 
309
309
  The layered-refactor preview lives in its **own repository**: [**`Noob-stupid/dsh-plugin-hub-refactor`**](https://github.com/Noob-stupid/dsh-plugin-hub-refactor)
310
310
 
311
- - **What it is**: the monolithic `lib/index.js` (7637 lines) split into layers — `lib/index.js` **142 lines** + `lib/server/**` **36 modules**; **feature-equivalent to `0.3.53`**, maintainability only;
312
- - **Verified**: 18 test suites green · 8 architecture-guard assertions · **47/47 routes identical** (`status` + response fields) against the stable build;
313
- - **Not yet exercised**: real framework upgrade / rollback, restart guardian, real install/uninstall, component start/stop, real AI run, Gitee OAuth (~10–25% long-tail risk, subjective);
314
- - **For everyday use** stick to npm `@noob-stupid/dsh-plugin-console@0.3.53`, or `main` of this repo.
311
+ - **What it is**: the monolithic `lib/index.js` (8547 lines) split into layers — `lib/index.js` **141 lines** + `lib/server/**` **38 modules**; **feature-equivalent to `0.3.55`**, maintainability only;
312
+ - **Verified**: 19 test suites green · 8 architecture-guard assertions · **route inventory identical** (`status` + response fields) against the stable build;
313
+ - **Not yet exercised**: real framework upgrade / rollback, restart guardian, component start/stop, real AI run, Gitee OAuth (~10–25% long-tail risk, subjective);
314
+ - **For everyday use** stick to npm `@noob-stupid/dsh-plugin-console@0.3.55`, or `main` of this repo.
package/README.zh.md CHANGED
@@ -275,8 +275,9 @@ MIT
275
275
 
276
276
  分层重构预览线在**独立仓库**:[**`Noob-stupid/dsh-plugin-hub-refactor`**](https://github.com/Noob-stupid/dsh-plugin-hub-refactor)
277
277
 
278
- - **它是什么**:把单体 `lib/index.js`(7637 行)拆成分层结构 —— `lib/index.js` **142 行** + `lib/server/**` **36 个模块**,**功能与 `0.3.53` 等价**,只为可维护性;
279
- - **已验证**:18 套测试全绿 · 8 条架构守卫断言 · 与稳定版逐条对打 **47 条路由,`status` + 响应字段 47/47 一致**;
280
- - **尚未实测**:真框架升级 / 真回滚、重启守护链路、真装真卸、组件进程启停、AI 真跑、Gitee OAuth 回调(长尾风险主观估计 **10%~25%**);
281
- - **日常使用请继续用**:npm `@noob-stupid/dsh-plugin-console@0.3.53`,或本仓库 `main`。
278
+ - **它是什么**:把单体 `lib/index.js`(8547 行)拆成分层结构 —— `lib/index.js` **141 行** + `lib/server/**` **38 个模块**,**功能与 `0.3.55` 等价**,只为可维护性;
279
+ - **已验证**:19 套测试全绿 · 8 条架构守卫断言 · 与稳定版逐条对打**路由清单一致**(`status` + 响应字段);
280
+ - **已实测**(2026-09-20 真装真卸演练):普通插件 / bundle 插件 / 无 npm 仓库 / 套装 / 技能 / 聚合仓库子包 / 仓库落地 / 服务器组件启停;
281
+ - **尚未实测**:真框架升级 / 真回滚、重启守护链路、AI 真跑、Gitee OAuth 回调(长尾风险主观估计 **10%~25%**);
282
+ - **日常使用请继续用**:npm `@noob-stupid/dsh-plugin-console@0.3.55`,或本仓库 `main`。
282
283
  - 请多反馈问题
package/lib/client.js CHANGED
@@ -6,7 +6,7 @@ window.__ModuleLoader__.load({
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
7
  let react = require("react");
8
8
  //#region styles
9
- const css = ".pc_section{width:100%;max-width:760px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:14px;display:flex}.pc_section h3{margin:0;font-size:13px;font-weight:600;line-height:20px}.pc_message{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:20px;margin:0}.pc_messageRow{display:flex;align-items:center;gap:10px}.pc_spinner{width:14px;height:14px;border:2px solid var(--dsw-alias-border-l2);border-top-color:var(--dsw-alias-state-business-primary);border-radius:50%;animation:pcspin 1s linear infinite;flex:none}@keyframes pcspin{to{transform:rotate(360deg)}}.pc_message[data-error=true]{color:var(--dsw-alias-state-error-primary)}.pc_message[data-warn=true]{color:var(--dsw-alias-state-warning-primary)}.pc_list{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin:0;padding:0;list-style:none;display:grid}.pc_row{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;min-width:0;padding:10px 12px;flex-direction:column;gap:6px;display:flex}.pc_rowTop{align-items:center;gap:8px;display:flex}.pc_name{font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.pc_tag{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);border-radius:999px;padding:1px 8px;font-size:11px;line-height:16px;flex:none}.pc_tag[data-enabled=true]{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary)}.pc_tag[data-user=true]{border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_tag[data-pending=true]{border-color:var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary)}.pc_status[data-pending=true]{color:var(--dsw-alias-state-warning-primary)}.pc_toggle[data-pending=true]{border-color:var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary)}.pc_tag[data-skill=true]{border-color:var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary)}.pc_tag[data-system=true]{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-2)}.pc_tag[data-disabled=true]{border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}.pc_tag[data-suite=true]{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary)}.pc_tag[data-error=true]{border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}.pc_tabGroup{display:inline-flex;gap:4px;align-items:center}.pc_meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px;gap:6px;display:flex;align-items:center}.pc_phase[data-phase=failed]{color:var(--dsw-alias-state-error-primary)}.pc_phase[data-phase=active]{color:var(--dsw-alias-state-success-primary)}.pc_toggle{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:0 0;font:inherit;cursor:pointer;border-radius:6px;padding:4px 12px;align-self:flex-start}.pc_toggle:hover:not(:disabled){border-color:var(--dsw-alias-state-business-primary)}.pc_toggle:disabled{opacity:.5;cursor:default}.pc_search{gap:8px;display:flex}.pc_search input{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);height:34px;flex:1;color:var(--dsw-alias-label-primary);font:inherit;border-radius:8px;outline:none;padding:0 12px;font-size:13px}.pc_search input:focus-visible{border-color:var(--dsw-alias-state-business-primary)}.pc_search button{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);font:inherit;cursor:pointer;border-radius:8px;padding:0 14px;font-size:13px}.pc_search button:hover{border-color:var(--dsw-alias-state-business-primary)}.pc_market{flex-direction:column;gap:10px;margin:0;padding:0;list-style:none;display:flex}.pc_item{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;min-width:0;padding:10px 12px;flex-direction:column;gap:6px;display:flex}.pc_itemTop{align-items:center;gap:8px;display:flex}.pc_itemTop a{color:var(--dsw-alias-state-business-primary);font-size:13px;font-weight:600;text-decoration:none;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pc_stars{color:var(--dsw-alias-label-tertiary);font-size:11px;flex:none}.pc_desc{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;margin:0}.pc_item button{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:0 0;font:inherit;cursor:pointer;border-radius:6px;padding:3px 10px;align-self:flex-start;font-size:12px}.pc_item button:hover:not(:disabled){border-color:var(--dsw-alias-state-business-primary)}.pc_item button:disabled{opacity:.5;cursor:default}.pc_detail{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;padding:10px 12px;flex-direction:column;gap:6px;display:flex}.pc_status{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;margin:0}.pc_note{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px;margin:0}.pc_marketHead{display:flex;align-items:center;justify-content:space-between;gap:10px}.pc_descWrap{flex-direction:column;display:flex}.pc_installedHead{display:flex;align-items:center;gap:10px}.pc_backTopWrap{position:fixed;top:56px;right:20px;z-index:100;display:flex;flex-direction:column;gap:8px}.pc_backTop{width:34px;height:34px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;background:rgba(22,27,34,.72);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);cursor:pointer;backdrop-filter:blur(4px);opacity:.7}.pc_backTop:hover{opacity:1;border-color:var(--dsw-alias-state-business-primary)}.pc_descTopbar{display:flex;justify-content:flex-end;margin:2px 0}.pc_ghpill{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);border-radius:999px;padding:1px 10px;font-size:11px;line-height:18px}.pc_ghpill[data-on=true]{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary)}.pc_extraBtn{opacity:.75;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:0 0;font:inherit;cursor:pointer;border-radius:6px;padding:4px 10px;font-size:12px;line-height:16px;flex:none;transition:opacity .15s ease,border-color 1.5s ease,color 1.5s ease}.pc_extraBtn:hover{opacity:1}.pc_extraBtn[data-active=true]{opacity:1;border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_extraBtn[data-flash=true]{border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_view{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:0 0;font:inherit;cursor:pointer;border-radius:6px;padding:2px 10px;font-size:12px;line-height:18px;flex:none}.pc_floatPanel{position:fixed;left:20px;top:50%;transform:translateY(-50%);width:340px;max-height:75vh;overflow-y:auto;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;padding:12px;box-shadow:0 8px 24px rgba(0,0,0,.18);z-index:50;flex-direction:column;gap:8px;display:flex}.pc_refresh{position:sticky;bottom:14px;align-self:flex-end;margin-top:8px;z-index:60;opacity:1;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:transparent;font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_refresh:hover{opacity:.9}.pc_date{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px;flex:none}.pc_searchInner{position:relative;flex:1;display:flex;align-items:center;min-width:0}.pc_searchInner input{padding-right:32px;width:100%}.pc_starBtn{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-tertiary);cursor:pointer;font-size:13px;line-height:1;padding:4px 8px;border-radius:6px;opacity:.75;transition:opacity .15s ease;flex:none}.pc_starBtn:hover{opacity:1}.pc_starBtn[data-active=true]{opacity:1;color:var(--dsw-alias-state-business-primary)}.pc_restartBtn{position:fixed;right:20px;top:50%;transform:translateY(-50%);z-index:60;opacity:1;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:transparent;font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_restartBtn:hover{opacity:.9}.pc_relaunchFloat{position:fixed;left:20px;top:50%;transform:translateY(-50%);z-index:70;opacity:.85;border:1px solid var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-bg-layer-3);font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_relaunchFloat:hover{opacity:1}.pc_aiToggle{position:fixed;right:20px;top:20px;z-index:70;opacity:1;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_aiToggle:hover{opacity:1}.pc_aiToggle[data-active=true]{opacity:1;border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_sourcesFloat{position:fixed;right:20px;top:104px;z-index:70;opacity:1;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3);font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_sourcesFloat:hover{opacity:1;border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_modeFloat{position:fixed;right:20px;top:204px;z-index:70;opacity:1;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3);font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_modeFloat:hover{opacity:1;border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_modeFloat[data-mode=true]{opacity:1;border-color:var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary)}.pc_trashBtn{border:0;background:0 0;color:var(--dsw-alias-label-tertiary);cursor:pointer;font-size:12px;line-height:16px;padding:2px 6px;flex:none;display:flex;align-items:center;border-radius:6px;transition:color .15s ease}.pc_trashBtn:hover{color:var(--dsw-alias-state-error-primary)}.pc_consentRemember{display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;color:var(--dsw-alias-label-secondary);cursor:pointer}.pc_modalBackdrop{position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:1000;display:flex;align-items:center;justify-content:center}.pc_modalCard{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:12px;padding:16px 18px;width:min(760px,calc(100vw - 64px));max-height:calc(100vh - 96px);overflow-y:auto;overscroll-behavior:contain;flex-direction:column;gap:10px;display:flex;box-shadow:0 12px 32px rgba(0,0,0,.25)}.pc_modalCard::-webkit-scrollbar{width:8px}.pc_modalCard::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:4px}.pc_srcUrl{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;color:var(--dsw-alias-label-tertiary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;max-width:100%}.pc_accWrap{display:flex;flex-direction:column;gap:8px}.pc_acc{border:1px solid var(--dsw-alias-border-l2);border-radius:10px;overflow:hidden;background:var(--dsw-alias-bg-layer-2)}.pc_accHead{width:100%;text-align:left;background:transparent;border:0;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;font-weight:600;line-height:20px;padding:8px 12px;cursor:pointer;display:flex;align-items:center;gap:6px}.pc_accHead:hover{background:var(--dsw-alias-bg-layer-3)}.pc_accHead[data-open=true]{border-bottom:1px solid var(--dsw-alias-border-l2)}.pc_accBody{padding:10px 12px;display:flex;flex-direction:column;gap:8px}.pc_ghpill{background:0 0;cursor:pointer}.pc_ghwrap{position:relative;display:inline-flex}.pc_sourceMenu{position:absolute;right:0;top:calc(100% + 6px);z-index:90;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:8px;padding:4px;flex-direction:column;display:flex;min-width:120px;box-shadow:0 8px 24px rgba(0,0,0,.18)}.pc_sourceOpt{border:0;background:0 0;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:6px;padding:6px 10px;text-align:left;font-size:12px;line-height:16px}.pc_sourceOpt[data-active=true]{color:var(--dsw-alias-state-business-primary);font-weight:600}.pc_sourceOpt:hover{background:var(--dsw-alias-bg-layer-3)}.pc_aiEmpower{position:fixed;right:20px;top:48px;z-index:70;opacity:1;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_aiEmpower:hover{opacity:.9}.pc_aiEmpower[data-busy=true]{opacity:1;border-color:var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary)}.pc_aiEmpower[data-active=true]{opacity:1;border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_compCard{position:fixed;left:8px;top:20px;width:320px;max-height:70vh;overflow-y:auto;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;padding:12px;box-shadow:0 8px 24px rgba(0,0,0,.18);z-index:45;flex-direction:column;gap:8px;display:flex}.pc_compCard .pc_rowTop{flex-wrap:wrap}.pc_compCard .pc_toggle{padding:3px 8px;font-size:11px}.pc_compCard[data-hidden=true]{display:none}.pc_compDrop{background:rgba(24,28,34,.92);backdrop-filter:blur(6px);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:4px;box-shadow:0 8px 24px rgba(0,0,0,.35);flex-direction:column;display:flex;gap:2px}.pc_compDropRow{border:0;background:0 0;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:6px;padding:6px 8px;text-align:left;font-size:12px;line-height:16px;flex-direction:column;display:flex;gap:2px}.pc_compDropRow:hover{background:var(--dsw-alias-bg-layer-2)}.pc_compDropUrl{color:var(--dsw-alias-label-tertiary);font-size:11px;word-break:break-all}.pc_compToggle{position:fixed;left:336px;top:20px;z-index:46;opacity:.55;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:rgba(22,27,34,.72);font:inherit;cursor:pointer;width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:11px;line-height:1;backdrop-filter:blur(4px);transition:opacity .15s ease}.pc_compToggle:hover{opacity:1;border-color:var(--dsw-alias-state-business-primary)}.pc_toolbarMain{position:fixed;right:70px;top:20px;z-index:71;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:border-color .15s ease}.pc_toolbarMain:hover{border-color:var(--dsw-alias-state-business-primary)}.pc_toolbarMain[data-active=true]{border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_toolbarGroup{position:fixed;right:70px;top:56px;z-index:70;flex-direction:column;gap:8px;display:flex;transform-origin:top right;animation:pcDrawerIn .3s cubic-bezier(.34,1.56,.64,1)}@media (max-width:1160px){.pc_toolbarMain{top:104px}.pc_toolbarGroup{top:140px}.pc_aiToggle{top:104px}.pc_aiEmpower{top:132px}.pc_sourcesFloat{top:188px}.pc_modeFloat{top:288px}}@keyframes pcDrawerIn{from{opacity:0;transform:translateX(28px) scale(.94)}to{opacity:1;transform:translateX(0) scale(1)}}.pc_toolItem{opacity:.85;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3);font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_toolItem:hover{opacity:1;border-color:var(--dsw-alias-state-business-primary)}.pc_toolItem[data-active=true]{opacity:1;border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_toolItem[data-mode=true]{opacity:1;border-color:var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary)}.pc_switch{width:34px;height:18px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);position:relative;cursor:pointer;flex:none;transition:background .15s ease,border-color .15s ease}.pc_switch:hover{border-color:var(--dsw-alias-state-business-primary)}.pc_switch[data-on=true]{background:var(--dsw-alias-state-success-primary);border-color:var(--dsw-alias-state-success-primary)}.pc_switchKnob{position:absolute;top:2px;left:2px;width:12px;height:12px;border-radius:50%;background:#fff;transition:left .15s ease}.pc_switch[data-on=true] .pc_switchKnob{left:18px}.pc_aiSpinner{width:12px;height:12px;border:2px solid var(--dsw-alias-border-l2);border-top-color:var(--dsw-alias-state-business-primary);border-radius:50%;animation:pcspin 1s linear infinite;flex:none}.pc_aiSpinBtn{position:fixed;right:152px;top:20px;z-index:71;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px}.pc_aiSpinBtn:hover{border-color:var(--dsw-alias-state-business-primary)}.pc_tag[data-bad=true]{border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}";
9
+ const css = ".pc_section{width:100%;max-width:760px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:14px;display:flex}.pc_section h3{margin:0;font-size:13px;font-weight:600;line-height:20px}.pc_message{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:20px;margin:0}.pc_messageRow{display:flex;align-items:center;gap:10px}.pc_spinner{width:14px;height:14px;border:2px solid var(--dsw-alias-border-l2);border-top-color:var(--dsw-alias-state-business-primary);border-radius:50%;animation:pcspin 1s linear infinite;flex:none}@keyframes pcspin{to{transform:rotate(360deg)}}.pc_message[data-error=true]{color:var(--dsw-alias-state-error-primary)}.pc_message[data-warn=true]{color:var(--dsw-alias-state-warning-primary)}.pc_list{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin:0;padding:0;list-style:none;display:grid}.pc_row{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;min-width:0;padding:10px 12px;flex-direction:column;gap:6px;display:flex}.pc_rowTop{align-items:center;gap:8px;display:flex}.pc_name{font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.pc_tag{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);border-radius:999px;padding:1px 8px;font-size:11px;line-height:16px;flex:none}.pc_tag[data-enabled=true]{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary)}.pc_tag[data-user=true]{border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_tag[data-pending=true]{border-color:var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary)}.pc_status[data-pending=true]{color:var(--dsw-alias-state-warning-primary)}.pc_toggle[data-pending=true]{border-color:var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary)}.pc_tag[data-skill=true]{border-color:var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary)}.pc_tag[data-system=true]{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-2)}.pc_tag[data-disabled=true]{border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}.pc_tag[data-suite=true]{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary)}.pc_tag[data-error=true]{border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}.pc_tabGroup{display:inline-flex;gap:4px;align-items:center}.pc_meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px;gap:6px;display:flex;align-items:center}.pc_phase[data-phase=failed]{color:var(--dsw-alias-state-error-primary)}.pc_phase[data-phase=active]{color:var(--dsw-alias-state-success-primary)}.pc_toggle{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:0 0;font:inherit;cursor:pointer;border-radius:6px;padding:4px 12px;align-self:flex-start}.pc_toggle:hover:not(:disabled){border-color:var(--dsw-alias-state-business-primary)}.pc_toggle:disabled{opacity:.5;cursor:default}.pc_search{gap:8px;display:flex}.pc_search input{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);height:34px;flex:1;color:var(--dsw-alias-label-primary);font:inherit;border-radius:8px;outline:none;padding:0 12px;font-size:13px}.pc_search input:focus-visible{border-color:var(--dsw-alias-state-business-primary)}.pc_search button{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);font:inherit;cursor:pointer;border-radius:8px;padding:0 14px;font-size:13px}.pc_search button:hover{border-color:var(--dsw-alias-state-business-primary)}.pc_market{flex-direction:column;gap:10px;margin:0;padding:0;list-style:none;display:flex}.pc_item{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;min-width:0;padding:10px 12px;flex-direction:column;gap:6px;display:flex}.pc_itemTop{align-items:center;gap:8px;display:flex}.pc_itemTop a{color:var(--dsw-alias-state-business-primary);font-size:13px;font-weight:600;text-decoration:none;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pc_stars{color:var(--dsw-alias-label-tertiary);font-size:11px;flex:none}.pc_desc{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;margin:0}.pc_item button{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:0 0;font:inherit;cursor:pointer;border-radius:6px;padding:3px 10px;align-self:flex-start;font-size:12px}.pc_item button:hover:not(:disabled){border-color:var(--dsw-alias-state-business-primary)}.pc_item button:disabled{opacity:.5;cursor:default}.pc_detail{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;padding:10px 12px;flex-direction:column;gap:6px;display:flex}.pc_status{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;margin:0}.pc_note{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px;margin:0}.pc_marketHead{display:flex;align-items:center;justify-content:space-between;gap:10px}.pc_descWrap{flex-direction:column;display:flex}.pc_installedHead{display:flex;align-items:center;gap:10px}.pc_backTopWrap{position:fixed;top:56px;right:20px;z-index:100;display:flex;flex-direction:column;gap:8px}.pc_backTop{width:34px;height:34px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;background:rgba(22,27,34,.72);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);cursor:pointer;backdrop-filter:blur(4px);opacity:.7}.pc_backTop:hover{opacity:1;border-color:var(--dsw-alias-state-business-primary)}.pc_descTopbar{display:flex;justify-content:flex-end;margin:2px 0}.pc_ghpill{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);border-radius:999px;padding:1px 10px;font-size:11px;line-height:18px}.pc_ghpill[data-on=true]{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary)}.pc_extraBtn{opacity:.75;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:0 0;font:inherit;cursor:pointer;border-radius:6px;padding:4px 10px;font-size:12px;line-height:16px;flex:none;transition:opacity .15s ease,border-color 1.5s ease,color 1.5s ease}.pc_extraBtn:hover{opacity:1}.pc_extraBtn[data-active=true]{opacity:1;border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_extraBtn[data-flash=true]{border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_view{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:0 0;font:inherit;cursor:pointer;border-radius:6px;padding:2px 10px;font-size:12px;line-height:18px;flex:none}.pc_floatPanel{position:fixed;left:20px;top:50%;transform:translateY(-50%);width:340px;max-height:75vh;overflow-y:auto;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;padding:12px;box-shadow:0 8px 24px rgba(0,0,0,.18);z-index:50;flex-direction:column;gap:8px;display:flex}.pc_refresh{position:sticky;bottom:14px;align-self:flex-end;margin-top:8px;z-index:60;opacity:1;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:transparent;font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_refresh:hover{opacity:.9}.pc_date{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px;flex:none}.pc_searchInner{position:relative;flex:1;display:flex;align-items:center;min-width:0}.pc_searchInner input{padding-right:32px;width:100%}.pc_starBtn{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-tertiary);cursor:pointer;font-size:13px;line-height:1;padding:4px 8px;border-radius:6px;opacity:.75;transition:opacity .15s ease;flex:none}.pc_starBtn:hover{opacity:1}.pc_starBtn[data-active=true]{opacity:1;color:var(--dsw-alias-state-business-primary)}.pc_restartBtn{position:fixed;right:20px;top:50%;transform:translateY(-50%);z-index:60;opacity:1;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:transparent;font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_restartBtn:hover{opacity:.9}.pc_relaunchFloat{position:fixed;left:20px;top:50%;transform:translateY(-50%);z-index:70;opacity:.85;border:1px solid var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-bg-layer-3);font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_relaunchFloat:hover{opacity:1}.pc_aiToggle{position:fixed;right:20px;top:20px;z-index:70;opacity:1;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_aiToggle:hover{opacity:1}.pc_aiToggle[data-active=true]{opacity:1;border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_sourcesFloat{position:fixed;right:20px;top:104px;z-index:70;opacity:1;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3);font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_sourcesFloat:hover{opacity:1;border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_modeFloat{position:fixed;right:20px;top:204px;z-index:70;opacity:1;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3);font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_modeFloat:hover{opacity:1;border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_modeFloat[data-mode=true]{opacity:1;border-color:var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary)}.pc_trashBtn{border:0;background:0 0;color:var(--dsw-alias-label-tertiary);cursor:pointer;font-size:12px;line-height:16px;padding:2px 6px;flex:none;display:flex;align-items:center;border-radius:6px;transition:color .15s ease}.pc_trashBtn:hover{color:var(--dsw-alias-state-error-primary)}.pc_consentRemember{display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;color:var(--dsw-alias-label-secondary);cursor:pointer}.pc_modalBackdrop{position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:1000;display:flex;align-items:center;justify-content:center}.pc_modalCard{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:12px;padding:16px 18px;width:min(760px,calc(100vw - 64px));max-height:calc(100vh - 96px);overflow-y:auto;overscroll-behavior:contain;flex-direction:column;gap:10px;display:flex;box-shadow:0 12px 32px rgba(0,0,0,.25)}.pc_modalCard::-webkit-scrollbar{width:8px}.pc_modalCard::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:4px}.pc_srcUrl{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;color:var(--dsw-alias-label-tertiary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;max-width:100%}.pc_accWrap{display:flex;flex-direction:column;gap:8px}.pc_acc{border:1px solid var(--dsw-alias-border-l2);border-radius:10px;overflow:hidden;background:var(--dsw-alias-bg-layer-2)}.pc_accHead{width:100%;text-align:left;background:transparent;border:0;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;font-weight:600;line-height:20px;padding:8px 12px;cursor:pointer;display:flex;align-items:center;gap:6px}.pc_accHead:hover{background:var(--dsw-alias-bg-layer-3)}.pc_accHead[data-open=true]{border-bottom:1px solid var(--dsw-alias-border-l2)}.pc_accBody{padding:10px 12px;display:flex;flex-direction:column;gap:8px}.pc_ghpill{background:0 0;cursor:pointer}.pc_ghwrap{position:relative;display:inline-flex}.pc_sourceMenu{position:absolute;right:0;top:calc(100% + 6px);z-index:90;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:8px;padding:4px;flex-direction:column;display:flex;min-width:120px;box-shadow:0 8px 24px rgba(0,0,0,.18)}.pc_sourceOpt{border:0;background:0 0;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:6px;padding:6px 10px;text-align:left;font-size:12px;line-height:16px}.pc_sourceOpt[data-active=true]{color:var(--dsw-alias-state-business-primary);font-weight:600}.pc_sourceOpt:hover{background:var(--dsw-alias-bg-layer-3)}.pc_aiEmpower{position:fixed;right:20px;top:48px;z-index:70;opacity:1;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_aiEmpower:hover{opacity:.9}.pc_aiEmpower[data-busy=true]{opacity:1;border-color:var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary)}.pc_aiEmpower[data-active=true]{opacity:1;border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_compCard{position:fixed;left:8px;top:20px;width:320px;max-height:70vh;overflow-y:auto;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;padding:12px;box-shadow:0 8px 24px rgba(0,0,0,.18);z-index:45;flex-direction:column;gap:8px;display:flex}.pc_compCard .pc_rowTop{flex-wrap:wrap}.pc_compCard .pc_toggle{padding:3px 8px;font-size:11px}.pc_compCard[data-hidden=true]{display:none}.pc_compDrop{background:rgba(24,28,34,.92);backdrop-filter:blur(6px);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:4px;box-shadow:0 8px 24px rgba(0,0,0,.35);flex-direction:column;display:flex;gap:2px}.pc_compDropRow{border:0;background:0 0;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:6px;padding:6px 8px;text-align:left;font-size:12px;line-height:16px;flex-direction:column;display:flex;gap:2px}.pc_compDropRow:hover{background:var(--dsw-alias-bg-layer-2)}.pc_compDropUrl{color:var(--dsw-alias-label-tertiary);font-size:11px;word-break:break-all}.pc_compToggle{position:fixed;left:336px;top:20px;z-index:46;opacity:.55;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:rgba(22,27,34,.72);font:inherit;cursor:pointer;width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:11px;line-height:1;backdrop-filter:blur(4px);transition:opacity .15s ease}.pc_compToggle:hover{opacity:1;border-color:var(--dsw-alias-state-business-primary)}.pc_toolbarMain{position:fixed;right:70px;top:20px;z-index:71;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:border-color .15s ease}.pc_toolbarMain:hover{border-color:var(--dsw-alias-state-business-primary)}.pc_toolbarMain[data-active=true]{border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_toolbarGroup{position:fixed;right:70px;top:56px;z-index:70;flex-direction:column;gap:8px;display:flex;transform-origin:top right;animation:pcDrawerIn .3s cubic-bezier(.34,1.56,.64,1)}@media (max-width:1160px){.pc_toolbarMain{top:104px}.pc_toolbarGroup{top:140px}.pc_aiToggle{top:104px}.pc_aiEmpower{top:132px}.pc_sourcesFloat{top:188px}.pc_modeFloat{top:288px}}@keyframes pcDrawerIn{from{opacity:0;transform:translateX(28px) scale(.94)}to{opacity:1;transform:translateX(0) scale(1)}}.pc_toolItem{opacity:.85;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3);font:inherit;cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;transition:opacity .15s ease}.pc_toolItem:hover{opacity:1;border-color:var(--dsw-alias-state-business-primary)}.pc_toolItem[data-active=true]{opacity:1;border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}.pc_toolItem[data-mode=true]{opacity:1;border-color:var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary)}.pc_switch{width:34px;height:18px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);position:relative;cursor:pointer;flex:none;transition:background .15s ease,border-color .15s ease}.pc_switch:hover{border-color:var(--dsw-alias-state-business-primary)}.pc_switch[data-on=true]{background:var(--dsw-alias-state-success-primary);border-color:var(--dsw-alias-state-success-primary)}.pc_switchKnob{position:absolute;top:2px;left:2px;width:12px;height:12px;border-radius:50%;background:#fff;transition:left .15s ease}.pc_switch[data-on=true] .pc_switchKnob{left:18px}.pc_aiSpinner{width:12px;height:12px;border:2px solid var(--dsw-alias-border-l2);border-top-color:var(--dsw-alias-state-business-primary);border-radius:50%;animation:pcspin 1s linear infinite;flex:none}.pc_aiSpinBtn{position:fixed;right:152px;top:20px;z-index:71;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);cursor:pointer;border-radius:8px;padding:6px 10px;display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px}.pc_aiSpinBtn:hover{border-color:var(--dsw-alias-state-business-primary)}.pc_tag[data-bad=true]{border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}.pc_progress{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px;margin:0;font-variant-numeric:tabular-nums}.pc_consentCard{border:2px solid var(--dsw-alias-state-warning-primary);background:var(--dsw-alias-bg-layer-2);border-radius:10px;padding:12px 14px;flex-direction:column;gap:8px;display:flex;box-shadow:0 0 0 3px rgba(255,176,32,.10)}.pc_consentCountdown{margin-left:auto;flex:none;font-size:14px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--dsw-alias-state-warning-primary)}.pc_consentApprove{border:1px solid var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary);background:0 0;font:inherit;font-weight:600;cursor:pointer;border-radius:6px;padding:4px 12px;align-self:flex-start}.pc_consentApprove:hover{border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}";
10
10
  const tagId = "@noob-stupid/dsh-plugin-console/PluginConsoleTab.css";
11
11
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
12
12
  const tag = document.createElement("style");
@@ -64,6 +64,10 @@ window.__ModuleLoader__.load({
64
64
  modeFloat: "pc_modeFloat",
65
65
  trashBtn: "pc_trashBtn",
66
66
  consentRemember: "pc_consentRemember",
67
+ consentCard: "pc_consentCard",
68
+ consentCountdown: "pc_consentCountdown",
69
+ consentApprove: "pc_consentApprove",
70
+ progress: "pc_progress",
67
71
  modalBackdrop: "pc_modalBackdrop",
68
72
  modalCard: "pc_modalCard",
69
73
  ghwrap: "pc_ghwrap",
@@ -242,10 +246,24 @@ window.__ModuleLoader__.load({
242
246
  deleting: "删除中…",
243
247
  deleteNote: "已删除插件并卸载包,正在刷新",
244
248
  deleteBundleNote: "已移除插件所属 bundle,重启服务后生效",
249
+ pendingRestartTag: "已安装·重启后生效",
250
+ pendingRestartHint: "包已装好,重启服务后才会出现在上面的插件列表里;现在删除可直接撤回这次安装",
251
+ pendingRestartDelete: "撤销这次安装(删补丁行 / bundles 清单 / 包目录)",
252
+ pendingRestartNote: "已撤销这次安装(补丁行、bundles 清单、包目录均已清理)",
253
+ pendingRestartPartial: "撤销未完全生效,请按提示手动处理",
245
254
  aiConsentText: "常规安装通道均已尝试失败。下一步将让本地 AI 接管安装——这会调用 DeepSeek API 模型,可能产生 API 费用。是否继续?",
246
255
  aiConsentNotifyTitle: "插件安装需要授权",
247
256
  aiConsentApprove: "同意,继续(可能产生费用)",
248
257
  aiConsentDecline: "取消",
258
+ aiConsentCardTitle: "⚠ 需要你的授权:本地 AI 兜底",
259
+ aiConsentCountdown: "剩余",
260
+ aiConsentTimeoutNote: "超过 {min} 分钟不做选择将自动取消(不会产生任何费用)",
261
+ aiConsentLastError: "确定性通道最后一个错误",
262
+ aiConsentTopHint: "⚠ 有安装任务在等你授权:确定性安装通道都失败了,可使用本地 AI 兜底(会调用模型 API 产生费用)——请在安装进度处选择「同意 / 取消」",
263
+ progressSubpackage: "正在装第 {index}/{total} 个子包:{name}",
264
+ progressSuiteClone: "正在拉取第 {index}/{total} 个子模块:{name}",
265
+ progressSuiteAssemble: "正在装配第 {index}/{total} 个子模块:{name}",
266
+ progressDone: "已完成(共 {total} 个)",
249
267
  aiFallbackLabel: "AI 兜底",
250
268
  aiEmpowerLabel: "AI 赋能",
251
269
  aiEmpowerTitle: "AI 赋能:读文档自动规划并部署组件;识别到服务器类组件后自动加启动/停止按钮",
@@ -625,10 +643,24 @@ window.__ModuleLoader__.load({
625
643
  deleting: "Deleting…",
626
644
  deleteNote: "Plugin deleted and package uninstalled; refreshing",
627
645
  deleteBundleNote: "Owning bundle removed; takes effect after service restart",
646
+ pendingRestartTag: "Installed · after restart",
647
+ pendingRestartHint: "The package is installed and will show up in the list above after a restart; deleting now revokes this install",
648
+ pendingRestartDelete: "Revoke this install (drop patch row, bundles entry and package dir)",
649
+ pendingRestartNote: "Install revoked (patch row, bundles entry and package dir cleaned)",
650
+ pendingRestartPartial: "Revoke incomplete — handle the leftovers manually as reported",
628
651
  aiConsentText: "All regular install channels failed. Next, the local AI takes over the install, which calls a DeepSeek API model and may incur API costs. Continue?",
629
652
  aiConsentNotifyTitle: "Plugin install needs approval",
630
653
  aiConsentApprove: "Agree, continue (may incur costs)",
631
654
  aiConsentDecline: "Cancel",
655
+ aiConsentCardTitle: "⚠ Approval needed: local AI fallback",
656
+ aiConsentCountdown: "Time left",
657
+ aiConsentTimeoutNote: "No choice within {min} minutes cancels it automatically (no cost at all)",
658
+ aiConsentLastError: "Last error from the deterministic channels",
659
+ aiConsentTopHint: "⚠ An install is waiting for your approval: every deterministic channel failed, and the local AI fallback (which calls the model API and may incur costs) needs your consent — choose Agree / Cancel in the install progress area",
660
+ progressSubpackage: "Installing subpackage {index}/{total}: {name}",
661
+ progressSuiteClone: "Cloning submodule {index}/{total}: {name}",
662
+ progressSuiteAssemble: "Assembling submodule {index}/{total}: {name}",
663
+ progressDone: "Completed ({total} total)",
632
664
  aiFallbackLabel: "AI fallback",
633
665
  aiEmpowerLabel: "AI Empower",
634
666
  aiEmpowerTitle: "AI Empower: read docs, plan and deploy a component automatically; server-type components get start/stop buttons",
@@ -2430,6 +2462,12 @@ window.__ModuleLoader__.load({
2430
2462
  call("/plugin-console/install-status", { jobId }).then(
2431
2463
  (data) => {
2432
2464
  setJobs((prev) => ({ ...prev, [jobId]: data }));
2465
+ // 授权请求必须"看得见"(2026-09-20 真装实测事故:面板只把 stage 变成
2466
+ // ai-consent,用户不知道要做什么 → 干等 10 分钟被超时取消)。顶部消息先说一句,
2467
+ // 详情卡在下面的安装进度区(同一位置的醒目卡片 + 倒计时 + 同意/取消)。
2468
+ if (data.status === "installing" && data.stage === "ai-consent" && data.aiConsent?.pending === true && !aiAutoDeclinedRef.current[jobId]) {
2469
+ setMessage(t("aiConsentTopHint"));
2470
+ }
2433
2471
  // 需要用户授权时(面板页后台/失焦也能看到):系统通知 + 标题闪烁提示
2434
2472
  if (data.status === "installing" && data.stage === "ai-consent" && aiFallback && !aiRemember && !aiAutoDeclinedRef.current[jobId]) {
2435
2473
  aiAutoDeclinedRef.current[jobId] = true;
@@ -2514,6 +2552,33 @@ window.__ModuleLoader__.load({
2514
2552
  (error) => setMessage(t("failed") + ":" + friendlyGithubError(error).message),
2515
2553
  );
2516
2554
  };
2555
+ /** 安装进度文案:服务端 progress{channel,phase,index,total,name,done} → 一行人话。
2556
+ * 2026-09-20 真装实测:11 个子包的聚合仓库跑 19 分钟,面板只有"安装中"——用户不知道
2557
+ * 在第几个、还剩几个、当前装的是谁。这里把服务端下发的进度翻成"第 i/n 个:<名字>"。 */
2558
+ const progressText = (progress) => {
2559
+ if (progress === null || progress === undefined) return "";
2560
+ if (progress.done === true) return t("progressDone").replace("{total}", String(progress.total ?? 0));
2561
+ const key = progress.channel === "suite"
2562
+ ? (progress.phase === "clone" ? "progressSuiteClone" : "progressSuiteAssemble")
2563
+ : "progressSubpackage";
2564
+ return t(key)
2565
+ .replace("{index}", String(progress.index ?? 0))
2566
+ .replace("{total}", String(progress.total ?? 0))
2567
+ .replace("{name}", progress.name ?? "");
2568
+ };
2569
+ /** 授权倒计时(剩余 mm:ss):服务端只给请求时间 + 超时上限,剩余量在前端算。
2570
+ * 轮询每 2s 触发一次重渲染,倒计时随之刷新,不需要额外的定时器。 */
2571
+ const consentRemaining = (job) => {
2572
+ const consent = job?.aiConsent ?? null;
2573
+ if (consent === null || consent.pending !== true || typeof consent.since !== "number") return null;
2574
+ const timeoutMs = typeof consent.timeoutMs === "number" && consent.timeoutMs > 0 ? consent.timeoutMs : 600000;
2575
+ const left = Math.max(0, Math.round((consent.since + timeoutMs - Date.now()) / 1000));
2576
+ return Math.floor(left / 60) + ":" + String(left % 60).padStart(2, "0");
2577
+ };
2578
+ const consentTimeoutMinutes = (job) => {
2579
+ const timeoutMs = job?.aiConsent?.timeoutMs;
2580
+ return String(Math.max(1, Math.round((typeof timeoutMs === "number" && timeoutMs > 0 ? timeoutMs : 600000) / 60000)));
2581
+ };
2517
2582
  /** 软件源管理:打开时拉取当前配置。 */
2518
2583
  const openSources = () => {
2519
2584
  setSourcesOpen(true);
@@ -3121,7 +3186,62 @@ window.__ModuleLoader__.load({
3121
3186
  const root = section.head !== null ? section.head.key.slice("family-".length) : null;
3122
3187
  if (root === null || familyCollapsed[root] !== true) familySectionEls.push(...section.cards);
3123
3188
  }
3124
- const rows = state.status === "ready" ? [...nonFamilyCards, ...familySectionEls] : [];
3189
+ // 已安装但尚未生效(bundle 型要重启才被加载;对应服务端 /state 的 pendingRestart):
3190
+ // 演练实测(2026-09-20)装完这类插件时 entryId 为 null、loader 里也没有新条目 ——
3191
+ // 用户以为没装上,删除按钮也无处可点。这里渲染成同样的行 + 「已安装·重启后生效」徽标,
3192
+ // 行上的删除按钮按 jobId 撤销这次安装(服务端删补丁行 / bundles 清单 / 包目录)。
3193
+ const pendingCards = (state.status === "ready" ? state.data.pendingRestart ?? [] : [])
3194
+ .filter((job) => installedQueryNorm === "" || [job.packageName, job.repo, job.jobId]
3195
+ .some((value) => String(value ?? "").toLowerCase().includes(installedQueryNorm)))
3196
+ .map((job) => el("li", { key: "pending-" + job.jobId, className: styles.row },
3197
+ el("div", { className: styles.rowTop },
3198
+ el("strong", { className: styles.name, title: job.packageName }, job.packageName),
3199
+ el("span", { className: styles.tag, "data-pending": "true", title: t("pendingRestartHint") }, t("pendingRestartTag")),
3200
+ ),
3201
+ el("div", { className: styles.meta },
3202
+ el("code", null, job.jobId),
3203
+ job.repo ? el("code", null, job.repo) : null,
3204
+ ),
3205
+ el("div", { className: styles.rowTop, style: { justifyContent: "space-between" } },
3206
+ el("p", { className: styles.desc }, t("pendingRestartHint")),
3207
+ el("div", { className: styles.rowTop },
3208
+ el("button", {
3209
+ type: "button",
3210
+ className: styles.trashBtn,
3211
+ title: t("pendingRestartDelete"),
3212
+ "aria-label": t("pendingRestartDelete"),
3213
+ disabled: deleteBusy === job.jobId,
3214
+ onClick: () => {
3215
+ if (confirmDeleteRowId === job.jobId) {
3216
+ setDeleteBusy(job.jobId);
3217
+ call("/plugin-console/uninstall", { jobId: job.jobId }).then(
3218
+ (data) => {
3219
+ setConfirmDeleteRowId(null);
3220
+ setMessage(data && data.warn
3221
+ ? t("pendingRestartPartial") + ":" + data.warn
3222
+ : t("pendingRestartNote") + ":" + (data?.packageName ?? "") + (data?.uninstallError ? "(包卸载警告:" + data.uninstallError + ")" : ""));
3223
+ refresh();
3224
+ },
3225
+ (error) => setMessage(t("failed") + ":" + friendlyGithubError(error).message),
3226
+ ).finally(() => setDeleteBusy(null));
3227
+ } else {
3228
+ setConfirmDeleteRowId(job.jobId);
3229
+ window.setTimeout(() => setConfirmDeleteRowId((v) => (v === job.jobId ? null : v)), 3000);
3230
+ }
3231
+ },
3232
+ }, deleteBusy === job.jobId
3233
+ ? t("deleting")
3234
+ : confirmDeleteRowId === job.jobId
3235
+ ? t("confirmDelete")
3236
+ : el("svg", { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" },
3237
+ el("polyline", { points: "3 6 5 6 21 6" }),
3238
+ el("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }),
3239
+ el("line", { x1: "10", y1: "11", x2: "10", y2: "17" }),
3240
+ el("line", { x1: "14", y1: "11", x2: "14", y2: "17" }))),
3241
+ ),
3242
+ ),
3243
+ ));
3244
+ const rows = state.status === "ready" ? [...nonFamilyCards, ...familySectionEls, ...pendingCards] : [];
3125
3245
  const marketShown = market === null || market.status !== "ready"
3126
3246
  ? []
3127
3247
  : officialOnly
@@ -3731,7 +3851,12 @@ setMessage(t("installing"));
3731
3851
  call("/plugin-console/self-update", {}).then(
3732
3852
  (data) => {
3733
3853
  if (data && data.ok === true) {
3734
- setMessage((data.note ?? "已更新") + ",正在重启生效…");
3854
+ // 未写进 lockfile 时必须**显眼**说清(用户实测报告:只铺文件不写 lock → 之后任何 pnpm 操作
3855
+ // 都会把版本还原,而用户以为升级成功了)
3856
+ const lockWarn = data.lockUpdated === false && typeof data.lockNote === "string" && data.lockNote !== ""
3857
+ ? "⚠️ " + data.lockNote
3858
+ : "";
3859
+ setMessage((data.note ?? "已更新") + (lockWarn === "" ? "" : "。" + lockWarn) + ",正在重启生效…");
3735
3860
  call("/plugin-console/restart", {}).then(() => {}, () => {});
3736
3861
  } else {
3737
3862
  setMessage(t("failed") + ":" + (data?.reason ?? "未知"));
@@ -4079,21 +4204,36 @@ setMessage(t("failed") + ":" + (data?.reason ?? "未知"));
4079
4204
  : null,
4080
4205
  Object.values(jobs).filter((job) => job.status === "installing").map((job) => {
4081
4206
  if (job.stage === "ai-consent") {
4082
- // 需要用户同意时由最上层模态框负责展示,列表内只留状态行;
4083
- // 已关闭兜底或已勾选"不再提醒"时显示对应说明
4084
- const autoNote = !aiFallback ? t("aiFallbackOff") : (aiRemember ? t("aiRememberNote") : t("consentWaiting"));
4085
- return el("div", { key: job.jobId, className: styles.detail },
4207
+ // 授权请求就摆在**安装进度所在位置**(用户盯着进度看,授权提示不能只在模态框里)。
4208
+ // 这块卡片是要显眼的:警告色描边 + 倒计时 + 同意/取消,而不是一行小字。
4209
+ // 关掉兜底或勾了"不再提醒"时给出对应说明(这两种情况前端会自动同意/取消)。
4210
+ const autoNote = !aiFallback ? t("aiFallbackOff") : (aiRemember ? t("aiRememberNote") : null);
4211
+ const remain = consentRemaining(job);
4212
+ const lastError = job.aiConsent?.lastError ?? null;
4213
+ const progressLine = progressText(job.progress);
4214
+ return el("div", { key: job.jobId, className: styles.consentCard },
4086
4215
  el("div", { className: styles.rowTop },
4087
4216
  el("span", { className: styles.spinner }),
4088
- el("strong", { className: styles.name }, t("installingLocal") + ":" + (job.packageName ?? job.repo))),
4089
- el("p", { className: styles.message }, autoNote));
4217
+ el("strong", { className: styles.name }, t("aiConsentCardTitle")),
4218
+ remain !== null ? el("span", { className: styles.consentCountdown }, t("aiConsentCountdown") + " " + remain) : null),
4219
+ el("p", { className: styles.message }, t("installingLocal") + ":" + (job.packageName ?? job.repo)),
4220
+ progressLine !== "" ? el("p", { className: styles.progress }, progressLine) : null,
4221
+ el("p", { className: styles.message }, t("aiConsentText")),
4222
+ lastError !== null ? el("p", { className: styles.note }, t("aiConsentLastError") + ":" + lastError) : null,
4223
+ remain !== null ? el("p", { className: styles.note }, t("aiConsentTimeoutNote").replace("{min}", consentTimeoutMinutes(job))) : null,
4224
+ autoNote !== null ? el("p", { className: styles.note }, autoNote) : null,
4225
+ el("div", { className: styles.rowTop },
4226
+ el("button", { type: "button", className: styles.consentApprove, onClick: () => aiConsent(job.jobId, true) }, t("aiConsentApprove")),
4227
+ el("button", { type: "button", className: styles.toggle, onClick: () => aiConsent(job.jobId, false) }, t("aiConsentDecline"))));
4090
4228
  }
4091
4229
  const stageKey = job.stage === "preparing" ? "stagePreparing" : job.stage === "configuring" ? "stageConfiguring" : job.stage === "repairing" ? "stageRepairing" : "stageInstalling";
4092
4230
  const elapsed = Math.max(0, Math.round((Date.now() - (job.startedAt ?? Date.now())) / 1000));
4231
+ const progressLine = progressText(job.progress);
4093
4232
  return el("div", { key: job.jobId, className: styles.detail },
4094
4233
  el("div", { className: styles.rowTop },
4095
4234
  el("span", { className: styles.spinner }),
4096
4235
  el("strong", { className: styles.name }, t("installingLocal") + ":" + (job.packageName ?? job.repo))),
4236
+ progressLine !== "" ? el("p", { className: styles.progress }, progressLine) : null,
4097
4237
  el("p", { className: styles.status },
4098
4238
  t("stageLabel") + ":" + t(stageKey) + " · " + t("elapsed") + " " + elapsed + "s"));
4099
4239
  }),
@@ -4224,7 +4364,7 @@ setMessage(t("failed") + ":" + (data?.reason ?? "未知"));
4224
4364
  ? el("div", { className: styles.detail },
4225
4365
  el("p", { className: styles.status, "data-error": "true" }, t("error")),
4226
4366
  el("button", { type: "button", className: styles.toggle, onClick: refresh }, t("retry")))
4227
- : state.data.entries.length === 0
4367
+ : state.data.entries.length === 0 && pendingCards.length === 0
4228
4368
  ? el("p", { className: styles.status }, t("empty"))
4229
4369
  : installedQueryNorm !== "" && rows.length === 0
4230
4370
  ? el("p", { className: styles.status }, t("noMatch"))
@@ -4257,26 +4397,36 @@ setMessage(t("failed") + ":" + (data?.reason ?? "未知"));
4257
4397
  (() => {
4258
4398
  // 最上层模态框:需要 AI 兜底授权时无论如何都让用户看到
4259
4399
  const consentJob = Object.values(jobs).find((job) => job.status === "installing" && job.stage === "ai-consent" && aiFallback && !aiRemember);
4260
- return consentJob === undefined
4261
- ? null
4262
- : el("div", { className: styles.modalBackdrop },
4263
- el("div", { className: styles.modalCard },
4264
- el("strong", { className: styles.name }, t("installingLocal") + ":" + (consentJob.packageName ?? consentJob.repo)),
4265
- el("p", { className: styles.message }, t("aiConsentText")),
4266
- el("label", { className: styles.consentRemember },
4267
- el("input", {
4268
- type: "checkbox",
4269
- checked: aiRemember,
4270
- onChange: (event) => {
4271
- const checked = event.currentTarget.checked;
4272
- setAiRemember(checked);
4273
- try { localStorage.setItem("pc-ai-remember", checked ? "1" : "0"); } catch {}
4274
- },
4275
- }),
4276
- t("aiConsentRemember")),
4277
- el("div", { className: styles.rowTop },
4278
- el("button", { type: "button", className: styles.toggle, onClick: () => { try { localStorage.setItem("pc-ai-remember", aiRemember ? "1" : "0"); } catch {} aiConsent(consentJob.jobId, true); } }, t("aiConsentApprove")),
4279
- el("button", { type: "button", className: styles.toggle, onClick: () => aiConsent(consentJob.jobId, false) }, t("aiConsentDecline")))));
4400
+ if (consentJob === undefined) return null;
4401
+ // 倒计时与进度也放进模态框:用户在模态框上做决定,不用回去翻进度区
4402
+ const remain = consentRemaining(consentJob);
4403
+ const lastError = consentJob.aiConsent?.lastError ?? null;
4404
+ const progressLine = progressText(consentJob.progress);
4405
+ return el("div", { className: styles.modalBackdrop },
4406
+ el("div", { className: styles.modalCard },
4407
+ el("strong", { className: styles.name }, t("aiConsentCardTitle")),
4408
+ el("p", { className: styles.message }, t("installingLocal") + ":" + (consentJob.packageName ?? consentJob.repo)),
4409
+ progressLine !== "" ? el("p", { className: styles.progress }, progressLine) : null,
4410
+ remain !== null
4411
+ ? el("p", { className: styles.message, "data-warn": "true" },
4412
+ t("aiConsentCountdown") + " " + remain + " · " + t("aiConsentTimeoutNote").replace("{min}", consentTimeoutMinutes(consentJob)))
4413
+ : null,
4414
+ el("p", { className: styles.message }, t("aiConsentText")),
4415
+ lastError !== null ? el("p", { className: styles.note }, t("aiConsentLastError") + ":" + lastError) : null,
4416
+ el("label", { className: styles.consentRemember },
4417
+ el("input", {
4418
+ type: "checkbox",
4419
+ checked: aiRemember,
4420
+ onChange: (event) => {
4421
+ const checked = event.currentTarget.checked;
4422
+ setAiRemember(checked);
4423
+ try { localStorage.setItem("pc-ai-remember", checked ? "1" : "0"); } catch {}
4424
+ },
4425
+ }),
4426
+ t("aiConsentRemember")),
4427
+ el("div", { className: styles.rowTop },
4428
+ el("button", { type: "button", className: styles.consentApprove, onClick: () => { try { localStorage.setItem("pc-ai-remember", aiRemember ? "1" : "0"); } catch {} aiConsent(consentJob.jobId, true); } }, t("aiConsentApprove")),
4429
+ el("button", { type: "button", className: styles.toggle, onClick: () => aiConsent(consentJob.jobId, false) }, t("aiConsentDecline")))));
4280
4430
  })(),
4281
4431
  sourcesOpen
4282
4432
  ? el("div", { className: styles.modalBackdrop },