@rezti/dsh-rez-suite 0.1.26 → 0.1.33

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.
Files changed (39) hide show
  1. package/README.md +1 -1
  2. package/lib/client.d.ts +7 -0
  3. package/lib/client.js +388 -187
  4. package/lib/index.d.ts +4 -0
  5. package/lib/index.js +85 -7
  6. package/lib/style.css +47 -0
  7. package/package.json +7 -7
  8. package/src/boss/mount.ts +2 -0
  9. package/src/client/assets/rez-mark.png +0 -0
  10. package/src/client/brand-mark.ts +4 -0
  11. package/src/client/brand.module.css +51 -0
  12. package/src/client/brand.ts +135 -0
  13. package/src/client/index.ts +11 -0
  14. package/src/client/locales.ts +14 -0
  15. package/src/client/panel/AuditTab.tsx +20 -19
  16. package/src/client/panel/ConfigTab.tsx +57 -39
  17. package/src/client/panel/StatusTab.tsx +11 -10
  18. package/src/client/panel/WeixinTab.tsx +9 -8
  19. package/src/client/panel/helpers.ts +20 -5
  20. package/src/client/settings-card.tsx +48 -42
  21. package/src/client/upgrade-button.tsx +24 -12
  22. package/src/index.ts +11 -0
  23. package/src/observe-mcp.ts +5 -2
  24. package/src/presets.ts +1 -0
  25. package/src/protocol.ts +2 -0
  26. package/src/store.ts +6 -0
  27. package/src/tianyancha.ts +79 -0
  28. package/templates/boss/money/AGENTS.md +2 -0
  29. package/templates/boss/ops/AGENTS.md +2 -0
  30. package/templates/boss/product/AGENTS.md +4 -0
  31. package/templates/staff/finance/.agents/skills/staff-finance/SKILL.md +1 -1
  32. package/templates/staff/finance/AGENTS.md +6 -0
  33. package/templates/staff/finance/MEMORY.md +1 -1
  34. package/templates/staff/hr/.agents/skills/staff-hr/SKILL.md +1 -1
  35. package/templates/staff/hr/AGENTS.md +6 -0
  36. package/templates/staff/hr/MEMORY.md +1 -1
  37. package/templates/staff/legal/.agents/skills/staff-legal/SKILL.md +1 -1
  38. package/templates/staff/legal/AGENTS.md +10 -0
  39. package/templates/staff/legal/MEMORY.md +1 -1
package/lib/client.js CHANGED
@@ -4,10 +4,133 @@ window.__ModuleLoader__.load({
4
4
  var module = { exports: {} };
5
5
  var exports = module.exports;
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
- (function(){var id="dsh-rez-suite-css";if(typeof document==="undefined"||document.getElementById(id))return;var s=document.createElement("style");s.id=id;s.textContent=".LOjPTW_shell {\n flex-direction: column;\n gap: 12px;\n min-width: 0;\n display: flex;\n}\n\n.LOjPTW_card {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-3);\n border-radius: 12px;\n list-style: none;\n transition: border-color .16s, background .16s;\n}\n\n.LOjPTW_card:hover {\n border-color: var(--dsw-alias-label-dimmed);\n}\n\n.LOjPTW_cardOpen {\n background: var(--dsw-alias-bg-layer-2);\n border-color: var(--dsw-alias-label-dimmed);\n}\n\n.LOjPTW_header {\n appearance: none;\n width: 100%;\n font: inherit;\n color: inherit;\n text-align: left;\n cursor: pointer;\n background: none;\n border: 0;\n border-radius: 12px;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n display: flex;\n}\n\n.LOjPTW_header:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n.LOjPTW_headText {\n flex-direction: column;\n flex: 1;\n gap: 4px;\n min-width: 0;\n display: flex;\n}\n\n.LOjPTW_name {\n color: var(--dsw-alias-label-primary);\n font-size: 15px;\n font-weight: 600;\n line-height: 1.4;\n}\n\n.LOjPTW_description {\n color: var(--dsw-alias-label-tertiary);\n font-size: 13px;\n line-height: 1.5;\n}\n\n.LOjPTW_chevron {\n color: var(--dsw-alias-label-tertiary);\n flex: none;\n transition: transform .16s;\n}\n\n.LOjPTW_chevronOpen {\n transform: rotate(180deg);\n}\n\n.LOjPTW_body {\n border-top: 1px solid var(--dsw-alias-border-l2);\n margin: 0 16px 12px;\n padding-top: 8px;\n}\n\n.LOjPTW_tabBar {\n border-bottom: 1px solid var(--dsw-alias-border-l1);\n flex: none;\n gap: 2px;\n display: flex;\n}\n\n.LOjPTW_tab {\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n background: none;\n border: none;\n border-bottom: 2px solid #0000;\n border-radius: 6px 6px 0 0;\n padding: 7px 14px;\n font-size: 13px;\n}\n\n.LOjPTW_tab:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.LOjPTW_tab[data-active] {\n color: var(--dsw-alias-label-primary);\n border-bottom-color: var(--dsw-alias-state-business-primary);\n font-weight: 600;\n}\n\n.LOjPTW_tabBody {\n flex-direction: column;\n gap: 12px;\n min-width: 0;\n padding: 12px 0 4px;\n display: flex;\n}\n\n.LOjPTW_section {\n border: 1px solid var(--dsw-alias-border-l1);\n background: var(--dsw-alias-bg-layer-1, var(--dsw-alias-bg-base));\n border-radius: 10px;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n display: flex;\n}\n\n.LOjPTW_sectionTitle {\n color: var(--dsw-alias-label-primary);\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n}\n\n.LOjPTW_field {\n flex-direction: column;\n align-items: stretch;\n gap: 4px;\n display: flex;\n}\n\n.LOjPTW_label {\n color: var(--dsw-alias-label-secondary);\n font-size: 12.5px;\n}\n\n.LOjPTW_input, .LOjPTW_select {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-specific-input-major, var(--dsw-alias-bg-layer-3));\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 8px;\n outline: none;\n padding: 6px 8px;\n font-size: 13px;\n}\n\n.LOjPTW_checkbox {\n justify-self: start;\n width: 15px;\n height: 15px;\n}\n\n.LOjPTW_toolbar {\n flex-wrap: wrap;\n flex: none;\n align-items: center;\n gap: 8px;\n display: flex;\n}\n\n.LOjPTW_button {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-specific-input-major, var(--dsw-alias-bg-layer-3));\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n border-radius: 8px;\n padding: 7px 12px;\n font-size: 13px;\n}\n\n.LOjPTW_button:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.LOjPTW_button:disabled {\n opacity: .4;\n cursor: default;\n}\n\n.LOjPTW_primaryButton {\n background: var(--dsw-alias-label-primary);\n border-color: var(--dsw-alias-label-primary);\n color: var(--dsw-alias-bg-layer-3);\n}\n\n.LOjPTW_dangerButton {\n background: var(--dsw-alias-state-danger, #c62828);\n border-color: var(--dsw-alias-state-danger, #c62828);\n color: #fff;\n}\n\n.LOjPTW_qr {\n background: #fff;\n border-radius: 8px;\n width: 200px;\n height: 200px;\n margin: 8px 0;\n display: block;\n}\n\n.LOjPTW_message {\n color: var(--dsw-alias-label-secondary);\n margin: 0;\n font-size: 12.5px;\n line-height: 1.5;\n}\n\n.LOjPTW_error {\n color: var(--dsw-alias-state-danger, #c62828);\n}\n\n.LOjPTW_tableWrap {\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n overflow: auto;\n}\n\n.LOjPTW_table {\n border-collapse: collapse;\n width: 100%;\n font-size: 12.5px;\n}\n\n.LOjPTW_table th {\n z-index: 1;\n text-align: left;\n background: var(--dsw-alias-bg-layer-2, var(--dsw-alias-bg-layer-1));\n padding: 8px 10px;\n position: sticky;\n top: 0;\n}\n\n.LOjPTW_table td {\n border-top: 1px solid var(--dsw-alias-border-l1);\n vertical-align: top;\n padding: 8px 10px;\n}\n\n.LOjPTW_badge {\n border-radius: 999px;\n padding: 2px 8px;\n font-size: 11px;\n display: inline-block;\n}\n\n.LOjPTW_badgeOk {\n color: #229a55;\n background: #229a5524;\n}\n\n.LOjPTW_badgeFail {\n color: #c62828;\n background: #c6282824;\n}\n\n.LOjPTW_cards {\n grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));\n gap: 8px;\n display: grid;\n}\n\n.LOjPTW_stat {\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n padding: 10px;\n}\n\n.LOjPTW_cardLabel {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n\n.LOjPTW_cardValue {\n color: var(--dsw-alias-label-primary);\n font-size: 15px;\n font-weight: 600;\n}\n\n.LOjPTW_upgradeLayer {\n flex: none;\n align-items: center;\n width: 100%;\n height: 42px;\n margin: 8px 0 0;\n display: flex;\n position: relative;\n}\n\n.LOjPTW_upgradeLayerRail {\n width: 36px;\n height: 36px;\n margin: 0;\n}\n\n.LOjPTW_upgradeButton {\n width: calc(100% + 4px);\n height: 42px;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n background: none;\n border: none;\n border-radius: 12px;\n align-items: center;\n gap: 8px;\n margin: 0 -2px;\n padding: 0 10px 0 8px;\n font-family: inherit;\n font-size: 14px;\n display: inline-flex;\n overflow: hidden;\n}\n\n.LOjPTW_upgradeButton:hover, .LOjPTW_upgradeButton[data-outdated] {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.LOjPTW_upgradeButton:disabled {\n cursor: progress;\n opacity: .72;\n}\n\n.LOjPTW_upgradeButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n.LOjPTW_upgradeLayerRail .LOjPTW_upgradeButton {\n border-radius: 50%;\n justify-content: center;\n gap: 0;\n width: 36px;\n height: 36px;\n padding: 0;\n}\n\n.LOjPTW_upgradeLabel {\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n overflow: hidden;\n}\n\n.LOjPTW_upgradeMeta {\n color: var(--dsw-alias-label-tertiary);\n font-variant-numeric: tabular-nums;\n flex: none;\n margin-left: auto;\n font-size: 12px;\n line-height: 16px;\n}\n\n.LOjPTW_upgradeDot {\n background: var(--dsw-alias-brand-primary);\n border-radius: 50%;\n flex: none;\n width: 7px;\n height: 7px;\n}\n";document.head.appendChild(s);})();
7
+ (function(){var id="dsh-rez-suite-css";if(typeof document==="undefined"||document.getElementById(id))return;var s=document.createElement("style");s.id=id;s.textContent=".r9dlUa_wordmark {\n min-width: 0;\n color: inherit;\n align-items: center;\n gap: 8px;\n display: inline-flex;\n overflow: hidden;\n}\n\n.r9dlUa_mark {\n object-fit: contain;\n flex: none;\n width: 28px;\n height: 28px;\n display: block;\n}\n\n.r9dlUa_markOnly {\n object-fit: contain;\n width: 100%;\n max-width: 28px;\n height: 100%;\n max-height: 28px;\n display: block;\n}\n\n.r9dlUa_name {\n letter-spacing: .02em;\n white-space: nowrap;\n text-overflow: ellipsis;\n font-size: 15px;\n font-weight: 650;\n overflow: hidden;\n}\n\n.r9dlUa_badge {\n letter-spacing: .06em;\n opacity: .72;\n white-space: nowrap;\n border: 1px solid;\n border-radius: 4px;\n flex: none;\n padding: 2px 6px;\n font-size: 10px;\n font-weight: 700;\n line-height: 1.2;\n}\n.LOjPTW_shell {\n flex-direction: column;\n gap: 12px;\n min-width: 0;\n display: flex;\n}\n\n.LOjPTW_card {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-3);\n border-radius: 12px;\n list-style: none;\n transition: border-color .16s, background .16s;\n}\n\n.LOjPTW_card:hover {\n border-color: var(--dsw-alias-label-dimmed);\n}\n\n.LOjPTW_cardOpen {\n background: var(--dsw-alias-bg-layer-2);\n border-color: var(--dsw-alias-label-dimmed);\n}\n\n.LOjPTW_header {\n appearance: none;\n width: 100%;\n font: inherit;\n color: inherit;\n text-align: left;\n cursor: pointer;\n background: none;\n border: 0;\n border-radius: 12px;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n display: flex;\n}\n\n.LOjPTW_header:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n.LOjPTW_headText {\n flex-direction: column;\n flex: 1;\n gap: 4px;\n min-width: 0;\n display: flex;\n}\n\n.LOjPTW_name {\n color: var(--dsw-alias-label-primary);\n font-size: 15px;\n font-weight: 600;\n line-height: 1.4;\n}\n\n.LOjPTW_description {\n color: var(--dsw-alias-label-tertiary);\n font-size: 13px;\n line-height: 1.5;\n}\n\n.LOjPTW_chevron {\n color: var(--dsw-alias-label-tertiary);\n flex: none;\n transition: transform .16s;\n}\n\n.LOjPTW_chevronOpen {\n transform: rotate(180deg);\n}\n\n.LOjPTW_body {\n border-top: 1px solid var(--dsw-alias-border-l2);\n margin: 0 16px 12px;\n padding-top: 8px;\n}\n\n.LOjPTW_tabBar {\n border-bottom: 1px solid var(--dsw-alias-border-l1);\n flex: none;\n gap: 2px;\n display: flex;\n}\n\n.LOjPTW_tab {\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n background: none;\n border: none;\n border-bottom: 2px solid #0000;\n border-radius: 6px 6px 0 0;\n padding: 7px 14px;\n font-size: 13px;\n}\n\n.LOjPTW_tab:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.LOjPTW_tab[data-active] {\n color: var(--dsw-alias-label-primary);\n border-bottom-color: var(--dsw-alias-state-business-primary);\n font-weight: 600;\n}\n\n.LOjPTW_tabBody {\n flex-direction: column;\n gap: 12px;\n min-width: 0;\n padding: 12px 0 4px;\n display: flex;\n}\n\n.LOjPTW_section {\n border: 1px solid var(--dsw-alias-border-l1);\n background: var(--dsw-alias-bg-layer-1, var(--dsw-alias-bg-base));\n border-radius: 10px;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n display: flex;\n}\n\n.LOjPTW_sectionTitle {\n color: var(--dsw-alias-label-primary);\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n}\n\n.LOjPTW_field {\n flex-direction: column;\n align-items: stretch;\n gap: 4px;\n display: flex;\n}\n\n.LOjPTW_label {\n color: var(--dsw-alias-label-secondary);\n font-size: 12.5px;\n}\n\n.LOjPTW_input, .LOjPTW_select {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-specific-input-major, var(--dsw-alias-bg-layer-3));\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 8px;\n outline: none;\n padding: 6px 8px;\n font-size: 13px;\n}\n\n.LOjPTW_checkbox {\n justify-self: start;\n width: 15px;\n height: 15px;\n}\n\n.LOjPTW_toolbar {\n flex-wrap: wrap;\n flex: none;\n align-items: center;\n gap: 8px;\n display: flex;\n}\n\n.LOjPTW_button {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-specific-input-major, var(--dsw-alias-bg-layer-3));\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n border-radius: 8px;\n padding: 7px 12px;\n font-size: 13px;\n}\n\n.LOjPTW_button:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.LOjPTW_button:disabled {\n opacity: .4;\n cursor: default;\n}\n\n.LOjPTW_primaryButton {\n background: var(--dsw-alias-label-primary);\n border-color: var(--dsw-alias-label-primary);\n color: var(--dsw-alias-bg-layer-3);\n}\n\n.LOjPTW_dangerButton {\n background: var(--dsw-alias-state-danger, #c62828);\n border-color: var(--dsw-alias-state-danger, #c62828);\n color: #fff;\n}\n\n.LOjPTW_qr {\n background: #fff;\n border-radius: 8px;\n width: 200px;\n height: 200px;\n margin: 8px 0;\n display: block;\n}\n\n.LOjPTW_message {\n color: var(--dsw-alias-label-secondary);\n margin: 0;\n font-size: 12.5px;\n line-height: 1.5;\n}\n\n.LOjPTW_error {\n color: var(--dsw-alias-state-danger, #c62828);\n}\n\n.LOjPTW_tableWrap {\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n overflow: auto;\n}\n\n.LOjPTW_table {\n border-collapse: collapse;\n width: 100%;\n font-size: 12.5px;\n}\n\n.LOjPTW_table th {\n z-index: 1;\n text-align: left;\n background: var(--dsw-alias-bg-layer-2, var(--dsw-alias-bg-layer-1));\n padding: 8px 10px;\n position: sticky;\n top: 0;\n}\n\n.LOjPTW_table td {\n border-top: 1px solid var(--dsw-alias-border-l1);\n vertical-align: top;\n padding: 8px 10px;\n}\n\n.LOjPTW_badge {\n border-radius: 999px;\n padding: 2px 8px;\n font-size: 11px;\n display: inline-block;\n}\n\n.LOjPTW_badgeOk {\n color: #229a55;\n background: #229a5524;\n}\n\n.LOjPTW_badgeFail {\n color: #c62828;\n background: #c6282824;\n}\n\n.LOjPTW_cards {\n grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));\n gap: 8px;\n display: grid;\n}\n\n.LOjPTW_stat {\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n padding: 10px;\n}\n\n.LOjPTW_cardLabel {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n\n.LOjPTW_cardValue {\n color: var(--dsw-alias-label-primary);\n font-size: 15px;\n font-weight: 600;\n}\n\n.LOjPTW_upgradeLayer {\n flex: none;\n align-items: center;\n width: 100%;\n height: 42px;\n margin: 8px 0 0;\n display: flex;\n position: relative;\n}\n\n.LOjPTW_upgradeLayerRail {\n width: 36px;\n height: 36px;\n margin: 0;\n}\n\n.LOjPTW_upgradeButton {\n width: calc(100% + 4px);\n height: 42px;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n background: none;\n border: none;\n border-radius: 12px;\n align-items: center;\n gap: 8px;\n margin: 0 -2px;\n padding: 0 10px 0 8px;\n font-family: inherit;\n font-size: 14px;\n display: inline-flex;\n overflow: hidden;\n}\n\n.LOjPTW_upgradeButton:hover, .LOjPTW_upgradeButton[data-outdated] {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.LOjPTW_upgradeButton:disabled {\n cursor: progress;\n opacity: .72;\n}\n\n.LOjPTW_upgradeButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n.LOjPTW_upgradeLayerRail .LOjPTW_upgradeButton {\n border-radius: 50%;\n justify-content: center;\n gap: 0;\n width: 36px;\n height: 36px;\n padding: 0;\n}\n\n.LOjPTW_upgradeLabel {\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n overflow: hidden;\n}\n\n.LOjPTW_upgradeMeta {\n color: var(--dsw-alias-label-tertiary);\n font-variant-numeric: tabular-nums;\n flex: none;\n margin-left: auto;\n font-size: 12px;\n line-height: 16px;\n}\n\n.LOjPTW_upgradeDot {\n background: var(--dsw-alias-brand-primary);\n border-radius: 50%;\n flex: none;\n width: 7px;\n height: 7px;\n}\n";document.head.appendChild(s);})();
8
8
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
9
9
  let react = require("react");
10
10
  let react_jsx_runtime = require("react/jsx-runtime");
11
+ //#region src/client/brand-mark.ts
12
+ /** Cropped circular R from Nextcloud MKT_brand/VI/2.png (transparent).
13
+ * Do not edit by hand — regenerate from src/client/assets/rez-mark.png.
14
+ */
15
+ const REZ_MARK_DATA_URL = "data:image/png;base64,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";
16
+ //#endregion
17
+ //#region src/client/brand.module.css
18
+ var brand_module_default = {
19
+ "badge": "r9dlUa_badge",
20
+ "mark": "r9dlUa_mark",
21
+ "markOnly": "r9dlUa_markOnly",
22
+ "name": "r9dlUa_name",
23
+ "wordmark": "r9dlUa_wordmark"
24
+ };
25
+ /** Official empty-hero headlines we replace. */
26
+ const OFFICIAL_HEADLINES = ["探索未至之境", "Into the Unknown"];
27
+ function normViewBox(value) {
28
+ return (value ?? "").trim().replace(/\s+/g, " ");
29
+ }
30
+ function alreadyBranded(node) {
31
+ return (node instanceof Element ? node : node.parentElement)?.closest("[data-rez-brand]") != null;
32
+ }
33
+ function markImg(kind, className) {
34
+ const img = document.createElement("img");
35
+ img.src = REZ_MARK_DATA_URL;
36
+ img.alt = "";
37
+ img.draggable = false;
38
+ img.className = className;
39
+ img.setAttribute("data-rez-brand", kind);
40
+ return img;
41
+ }
42
+ function paintWordmark(svg, t) {
43
+ const parent = svg.parentNode;
44
+ if (parent === null || alreadyBranded(svg)) return;
45
+ const row = document.createElement("span");
46
+ row.className = brand_module_default.wordmark;
47
+ row.setAttribute("data-rez-brand", "wordmark");
48
+ row.setAttribute("aria-label", t("brand.wordmarkAria"));
49
+ const name = document.createElement("span");
50
+ name.className = brand_module_default.name;
51
+ name.textContent = t("brand.name");
52
+ const badge = document.createElement("span");
53
+ badge.className = brand_module_default.badge;
54
+ badge.textContent = t("brand.badge");
55
+ row.append(markImg("wordmark", brand_module_default.mark), name, badge);
56
+ parent.replaceChild(row, svg);
57
+ }
58
+ function paintFish(svg) {
59
+ const parent = svg.parentNode;
60
+ if (parent === null || alreadyBranded(svg)) return;
61
+ const wrap = document.createElement("span");
62
+ wrap.setAttribute("data-rez-brand", "icon");
63
+ wrap.style.display = "inline-flex";
64
+ wrap.style.alignItems = "center";
65
+ wrap.style.justifyContent = "center";
66
+ const width = svg.getAttribute("width");
67
+ const height = svg.getAttribute("height");
68
+ if (width) wrap.style.width = /px$/.test(width) ? width : `${width}px`;
69
+ if (height) wrap.style.height = /px$/.test(height) ? height : `${height}px`;
70
+ wrap.append(markImg("icon", brand_module_default.markOnly));
71
+ parent.replaceChild(wrap, svg);
72
+ }
73
+ function paintHeadline(el, t) {
74
+ el.setAttribute("data-rez-brand", "headline");
75
+ el.textContent = t("brand.headline");
76
+ }
77
+ function refreshCopy(root, t) {
78
+ for (const row of root.querySelectorAll("[data-rez-brand=\"wordmark\"]")) {
79
+ const name = row.querySelector(`.${brand_module_default.name}`);
80
+ const badge = row.querySelector(`.${brand_module_default.badge}`);
81
+ if (name) name.textContent = t("brand.name");
82
+ if (badge) badge.textContent = t("brand.badge");
83
+ row.setAttribute("aria-label", t("brand.wordmarkAria"));
84
+ }
85
+ for (const el of root.querySelectorAll("[data-rez-brand=\"headline\"]")) el.textContent = t("brand.headline");
86
+ }
87
+ function paintBrand(root, t) {
88
+ refreshCopy(root, t);
89
+ const svgs = root.querySelectorAll("svg[aria-hidden=\"true\"]");
90
+ for (const node of svgs) {
91
+ if (!(node instanceof SVGSVGElement)) continue;
92
+ const box = normViewBox(node.getAttribute("viewBox"));
93
+ if (box === "0 0 182 24") paintWordmark(node, t);
94
+ else if (box === "0 0 23.16 17.04") paintFish(node);
95
+ }
96
+ const doc = root instanceof Document ? root : root.ownerDocument;
97
+ if (doc === null) return;
98
+ const walker = doc.createTreeWalker(root, NodeFilter.SHOW_TEXT);
99
+ const headlines = [];
100
+ while (walker.nextNode()) {
101
+ const text = walker.currentNode;
102
+ const value = text.data.trim();
103
+ if (OFFICIAL_HEADLINES.includes(value)) headlines.push(text);
104
+ }
105
+ for (const text of headlines) {
106
+ const host = text.parentElement;
107
+ if (host) paintHeadline(host, t);
108
+ }
109
+ }
110
+ function mountRezBrand(t) {
111
+ if (typeof document === "undefined") return () => void 0;
112
+ let frame = 0;
113
+ const run = () => {
114
+ frame = 0;
115
+ paintBrand(document, t);
116
+ };
117
+ const schedule = () => {
118
+ if (frame !== 0) return;
119
+ frame = requestAnimationFrame(run);
120
+ };
121
+ run();
122
+ const observer = new MutationObserver(schedule);
123
+ observer.observe(document.documentElement, {
124
+ childList: true,
125
+ subtree: true,
126
+ characterData: true
127
+ });
128
+ return () => {
129
+ observer.disconnect();
130
+ if (frame !== 0) cancelAnimationFrame(frame);
131
+ };
132
+ }
133
+ //#endregion
11
134
  //#region src/client/locales.ts
12
135
  /**
13
136
  * dsh-rez-suite surface copy: zh is the key source, en mirrors every key.
@@ -61,6 +184,9 @@ const zh = {
61
184
  "config.gsc": "Google Search Console",
62
185
  "config.gsc.siteUrl": "站点 URL",
63
186
  "config.gsc.key": "服务账号 JSON 或密钥文件路径",
187
+ "config.tianyancha": "天眼查(法务助理 · 仅老板)",
188
+ "config.tianyancha.url": "天眼查 MCP URL",
189
+ "config.tianyancha.token": "OpenAPI Token",
64
190
  "config.fs": "本地文件 (fs-mcp-server)",
65
191
  "config.fs.root": "根目录",
66
192
  "config.sqlite": "SQLite (sqlite-mcp-server)",
@@ -123,7 +249,11 @@ const zh = {
123
249
  "upgrade.running": "升级中…",
124
250
  "upgrade.reloading": "正在重载",
125
251
  "upgrade.already": "已是 {version}",
126
- "upgrade.reloadTimeout": "升级完成,但网页还没重新连上。请刷新这一页。"
252
+ "upgrade.reloadTimeout": "升级完成,但网页还没重新连上。请刷新这一页。",
253
+ "brand.name": "雷泽智能",
254
+ "brand.badge": "定制版",
255
+ "brand.headline": "雷泽智能定制版",
256
+ "brand.wordmarkAria": "雷泽智能定制版"
127
257
  };
128
258
  const en = {
129
259
  "entry.label": "Rez",
@@ -174,6 +304,9 @@ const en = {
174
304
  "config.gsc": "Google Search Console",
175
305
  "config.gsc.siteUrl": "Site URL",
176
306
  "config.gsc.key": "Service-account JSON or key file path",
307
+ "config.tianyancha": "Tianyancha (Legal assistant, boss only)",
308
+ "config.tianyancha.url": "Tianyancha MCP URL",
309
+ "config.tianyancha.token": "OpenAPI token",
177
310
  "config.fs": "Local files (fs-mcp-server)",
178
311
  "config.fs.root": "Root directory",
179
312
  "config.sqlite": "SQLite (sqlite-mcp-server)",
@@ -236,7 +369,11 @@ const en = {
236
369
  "upgrade.running": "Updating…",
237
370
  "upgrade.reloading": "Reloading",
238
371
  "upgrade.already": "Already {version}",
239
- "upgrade.reloadTimeout": "Update finished, but the page did not reconnect. Refresh this tab."
372
+ "upgrade.reloadTimeout": "Update finished, but the page did not reconnect. Refresh this tab.",
373
+ "brand.name": "ReZ-TI",
374
+ "brand.badge": "Custom",
375
+ "brand.headline": "ReZ-TI Custom Edition",
376
+ "brand.wordmarkAria": "ReZ-TI Custom Edition"
240
377
  };
241
378
  /** Minimal {name} interpolator shared by the panel helpers. */
242
379
  function t(dict, key, values) {
@@ -326,13 +463,21 @@ var RezApi = class {
326
463
  //#endregion
327
464
  //#region src/client/panel/helpers.ts
328
465
  /**
329
- * Shared panel helpers: active-language dictionary pick and error extraction.
466
+ * Official DSH locale seat for ReZ UI copy.
467
+ *
468
+ * Slot components receive `t` from `locale: 'dsh-rez-suite'`. Fallback copy
469
+ * is Chinese only — do not read `<html lang>`. The Host stores zh/en in
470
+ * `locale.preference`, which does not necessarily match the document language.
330
471
  */
472
+ const RezT = (0, react.createContext)(null);
473
+ /** Fallback for tests / code outside a slot. Prefer {@link useT}. */
331
474
  function dictionary() {
332
- return (typeof document !== "undefined" ? document.documentElement.lang : "zh").toLowerCase().startsWith("en") ? { ...en } : { ...zh };
475
+ return { ...zh };
333
476
  }
334
- function tt(key, values) {
335
- return t(dictionary(), key, values);
477
+ function useT() {
478
+ const injected = (0, react.useContext)(RezT);
479
+ if (injected) return injected;
480
+ return (key, params) => t(dictionary(), key, params);
336
481
  }
337
482
  function errorMessage(error) {
338
483
  if (error instanceof Error) return error.message;
@@ -390,6 +535,7 @@ var panel_module_default = {
390
535
  * Audit tab: token/cost summary and recent ledger rows.
391
536
  */
392
537
  function AuditTab({ api }) {
538
+ const t = useT();
393
539
  const [audit, setAudit] = (0, react.useState)(null);
394
540
  const [error, setError] = (0, react.useState)("");
395
541
  const [loading, setLoading] = (0, react.useState)(true);
@@ -408,7 +554,7 @@ function AuditTab({ api }) {
408
554
  load();
409
555
  }, []);
410
556
  const reset = async () => {
411
- if (!window.confirm(tt("audit.resetConfirm"))) return;
557
+ if (!window.confirm(t("audit.resetConfirm"))) return;
412
558
  try {
413
559
  await api.resetAudit();
414
560
  await load();
@@ -418,7 +564,7 @@ function AuditTab({ api }) {
418
564
  };
419
565
  if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
420
566
  className: panel_module_default.message,
421
- children: tt("common.loading")
567
+ children: t("common.loading")
422
568
  });
423
569
  if (audit === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
424
570
  className: panel_module_default.error,
@@ -435,14 +581,14 @@ function AuditTab({ api }) {
435
581
  onClick: () => {
436
582
  load();
437
583
  },
438
- children: tt("common.refresh")
584
+ children: t("common.refresh")
439
585
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
440
586
  type: "button",
441
587
  className: panel_module_default.button + " " + panel_module_default.dangerButton,
442
588
  onClick: () => {
443
589
  reset();
444
590
  },
445
- children: tt("audit.reset")
591
+ children: t("audit.reset")
446
592
  })]
447
593
  }),
448
594
  error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -456,7 +602,7 @@ function AuditTab({ api }) {
456
602
  className: panel_module_default.stat,
457
603
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
458
604
  className: panel_module_default.cardLabel,
459
- children: tt("audit.totalCalls")
605
+ children: t("audit.totalCalls")
460
606
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
461
607
  className: panel_module_default.cardValue,
462
608
  children: audit.totalCalls
@@ -466,7 +612,7 @@ function AuditTab({ api }) {
466
612
  className: panel_module_default.stat,
467
613
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
468
614
  className: panel_module_default.cardLabel,
469
- children: tt("audit.inputTokens")
615
+ children: t("audit.inputTokens")
470
616
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
471
617
  className: panel_module_default.cardValue,
472
618
  children: audit.totalInputTokens
@@ -476,7 +622,7 @@ function AuditTab({ api }) {
476
622
  className: panel_module_default.stat,
477
623
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
478
624
  className: panel_module_default.cardLabel,
479
- children: tt("audit.outputTokens")
625
+ children: t("audit.outputTokens")
480
626
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
481
627
  className: panel_module_default.cardValue,
482
628
  children: audit.totalOutputTokens
@@ -486,7 +632,7 @@ function AuditTab({ api }) {
486
632
  className: panel_module_default.stat,
487
633
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
488
634
  className: panel_module_default.cardLabel,
489
- children: tt("audit.totalCost")
635
+ children: t("audit.totalCost")
490
636
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
491
637
  className: panel_module_default.cardValue,
492
638
  children: audit.totalCost.toFixed(4)
@@ -496,7 +642,7 @@ function AuditTab({ api }) {
496
642
  className: panel_module_default.stat,
497
643
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
498
644
  className: panel_module_default.cardLabel,
499
- children: tt("audit.monthCost")
645
+ children: t("audit.monthCost")
500
646
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
501
647
  className: panel_module_default.cardValue,
502
648
  children: audit.monthCost.toFixed(4)
@@ -506,7 +652,7 @@ function AuditTab({ api }) {
506
652
  className: panel_module_default.stat,
507
653
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
508
654
  className: panel_module_default.cardLabel,
509
- children: tt("audit.budget")
655
+ children: t("audit.budget")
510
656
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
511
657
  className: panel_module_default.cardValue,
512
658
  children: audit.monthlyBudget.toFixed(2)
@@ -519,15 +665,15 @@ function AuditTab({ api }) {
519
665
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
520
666
  className: panel_module_default.table,
521
667
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
522
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: tt("audit.col.time") }),
523
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: tt("audit.col.server") }),
524
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: tt("audit.col.tool") }),
525
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: tt("audit.col.tokens") }),
526
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: tt("audit.col.cost") }),
527
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: tt("audit.col.status") })
668
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("audit.col.time") }),
669
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("audit.col.server") }),
670
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("audit.col.tool") }),
671
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("audit.col.tokens") }),
672
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("audit.col.cost") }),
673
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("audit.col.status") })
528
674
  ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tbody", { children: [audit.recent.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
529
675
  colSpan: 6,
530
- children: tt("audit.empty")
676
+ children: t("audit.empty")
531
677
  }) }), audit.recent.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
532
678
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: new Date(row.ts).toLocaleString() }),
533
679
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: row.server }),
@@ -536,10 +682,10 @@ function AuditTab({ api }) {
536
682
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: row.cost.toFixed(4) }),
537
683
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: row.ok ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
538
684
  className: panel_module_default.badge + " " + panel_module_default.badgeOk,
539
- children: tt("audit.ok")
685
+ children: t("audit.ok")
540
686
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
541
687
  className: panel_module_default.badge + " " + panel_module_default.badgeFail,
542
- children: tt("audit.fail")
688
+ children: t("audit.fail")
543
689
  }) })
544
690
  ] }, row.id))] })]
545
691
  })
@@ -581,7 +727,8 @@ const EMPTY_SECRETS = {
581
727
  wechat: "",
582
728
  homeassistant: "",
583
729
  tapd: "",
584
- gsc: ""
730
+ gsc: "",
731
+ tianyancha: ""
585
732
  };
586
733
  function Field({ label, children }) {
587
734
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -602,6 +749,7 @@ function Section({ title, children }) {
602
749
  });
603
750
  }
604
751
  function SecretField({ label, configured, value, onChange }) {
752
+ const t = useT();
605
753
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
606
754
  label,
607
755
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
@@ -609,7 +757,7 @@ function SecretField({ label, configured, value, onChange }) {
609
757
  type: "password",
610
758
  autoComplete: "off",
611
759
  value,
612
- placeholder: configured ? tt("config.secretConfigured") : tt("config.secretMissing"),
760
+ placeholder: configured ? t("config.secretConfigured") : t("config.secretMissing"),
613
761
  onChange: (event) => {
614
762
  onChange(event.target.value);
615
763
  }
@@ -621,7 +769,7 @@ function McpSection({ title, row, secret, onEnabled, onUrl, onUsername, onSecret
621
769
  title,
622
770
  children: [
623
771
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
624
- label: tt("config.enabled"),
772
+ label: useT()("config.enabled"),
625
773
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
626
774
  className: panel_module_default.checkbox,
627
775
  type: "checkbox",
@@ -666,6 +814,7 @@ function McpSection({ title, row, secret, onEnabled, onUrl, onUsername, onSecret
666
814
  });
667
815
  }
668
816
  function ConfigTab({ api }) {
817
+ const t = useT();
669
818
  const [config, setConfig] = (0, react.useState)(null);
670
819
  const [secrets, setSecrets] = (0, react.useState)(EMPTY_SECRETS);
671
820
  const [loading, setLoading] = (0, react.useState)(true);
@@ -688,7 +837,7 @@ function ConfigTab({ api }) {
688
837
  }, []);
689
838
  if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
690
839
  className: panel_module_default.message,
691
- children: tt("common.loading")
840
+ children: t("common.loading")
692
841
  });
693
842
  if (config === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
694
843
  className: panel_module_default.error,
@@ -745,13 +894,17 @@ function ConfigTab({ api }) {
745
894
  gsc: {
746
895
  ...config.connections.gsc,
747
896
  secret: secrets.gsc || void 0
897
+ },
898
+ tianyancha: {
899
+ ...config.connections.tianyancha,
900
+ secret: secrets.tianyancha || void 0
748
901
  }
749
902
  }
750
903
  };
751
904
  const saved = await api.saveConfig(payload);
752
905
  setConfig(saved);
753
906
  setSecrets(EMPTY_SECRETS);
754
- setMessage(tt("config.saved"));
907
+ setMessage(t("config.saved"));
755
908
  } catch (err) {
756
909
  setError(errorMessage(err));
757
910
  } finally {
@@ -774,49 +927,56 @@ function ConfigTab({ api }) {
774
927
  const renderResult = (result) => {
775
928
  if (result.ok) {
776
929
  if (result.serverInfo !== void 0) return result.serverInfo;
777
- return tt("config.testOk", {
930
+ return t("config.testOk", {
778
931
  tools: result.toolCount ?? 0,
779
932
  latency: result.latencyMs ?? 0
780
933
  });
781
934
  }
782
- return tt("config.testFail", { error: result.error ?? "" });
935
+ return t("config.testFail", { error: result.error ?? "" });
783
936
  };
784
937
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
785
938
  className: panel_module_default.tabBody,
786
939
  children: [
787
940
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
788
941
  className: panel_module_default.message,
789
- children: tt("config.mcpHint")
942
+ children: t("config.mcpHint")
790
943
  }),
791
944
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Section, {
792
- title: tt("config.role"),
793
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
794
- label: tt("config.role"),
795
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
796
- className: panel_module_default.select,
797
- value: config.role,
798
- onChange: (event) => {
799
- setTop("role", event.target.value);
800
- },
801
- children: ROLES.map((role) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
802
- value: role.value,
803
- children: tt(role.label)
804
- }, role.value))
805
- })
806
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
807
- label: tt("config.enabled"),
808
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
809
- className: panel_module_default.checkbox,
810
- type: "checkbox",
811
- checked: config.enabled,
812
- onChange: (event) => {
813
- setTop("enabled", event.target.checked);
814
- }
945
+ title: t("config.role"),
946
+ children: [
947
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
948
+ label: t("config.role"),
949
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
950
+ className: panel_module_default.select,
951
+ value: config.role,
952
+ onChange: (event) => {
953
+ setTop("role", event.target.value);
954
+ },
955
+ children: ROLES.map((role) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
956
+ value: role.value,
957
+ children: t(role.label)
958
+ }, role.value))
959
+ })
960
+ }),
961
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
962
+ className: panel_module_default.message,
963
+ children: t("config.roleHint")
964
+ }),
965
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
966
+ label: t("config.enabled"),
967
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
968
+ className: panel_module_default.checkbox,
969
+ type: "checkbox",
970
+ checked: config.enabled,
971
+ onChange: (event) => {
972
+ setTop("enabled", event.target.checked);
973
+ }
974
+ })
815
975
  })
816
- })]
976
+ ]
817
977
  }),
818
978
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(McpSection, {
819
- title: tt("config.odoo"),
979
+ title: t("config.odoo"),
820
980
  row: config.connections.odoo,
821
981
  secret: secrets.odoo,
822
982
  onEnabled: (enabled) => {
@@ -831,11 +991,11 @@ function ConfigTab({ api }) {
831
991
  odoo: value
832
992
  }));
833
993
  },
834
- urlLabel: tt("config.odoo.url"),
835
- secretLabel: tt("config.odoo.apiKey")
994
+ urlLabel: t("config.odoo.url"),
995
+ secretLabel: t("config.odoo.apiKey")
836
996
  }),
837
997
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(McpSection, {
838
- title: tt("config.nextcloud"),
998
+ title: t("config.nextcloud"),
839
999
  row: config.connections.nextcloud,
840
1000
  secret: secrets.nextcloud,
841
1001
  onEnabled: (enabled) => {
@@ -853,12 +1013,12 @@ function ConfigTab({ api }) {
853
1013
  nextcloud: value
854
1014
  }));
855
1015
  },
856
- urlLabel: tt("config.nextcloud.url"),
857
- usernameLabel: tt("config.nextcloud.username"),
858
- secretLabel: tt("config.nextcloud.appPassword")
1016
+ urlLabel: t("config.nextcloud.url"),
1017
+ usernameLabel: t("config.nextcloud.username"),
1018
+ secretLabel: t("config.nextcloud.appPassword")
859
1019
  }),
860
1020
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(McpSection, {
861
- title: tt("config.wecom"),
1021
+ title: t("config.wecom"),
862
1022
  row: config.connections.wechat,
863
1023
  secret: secrets.wechat,
864
1024
  onEnabled: (enabled) => {
@@ -870,10 +1030,10 @@ function ConfigTab({ api }) {
870
1030
  wechat: value
871
1031
  }));
872
1032
  },
873
- secretLabel: tt("config.wecom.webhook")
1033
+ secretLabel: t("config.wecom.webhook")
874
1034
  }),
875
1035
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(McpSection, {
876
- title: tt("config.ha"),
1036
+ title: t("config.ha"),
877
1037
  row: config.connections.homeassistant,
878
1038
  secret: secrets.homeassistant,
879
1039
  onEnabled: (enabled) => {
@@ -888,18 +1048,18 @@ function ConfigTab({ api }) {
888
1048
  homeassistant: value
889
1049
  }));
890
1050
  },
891
- urlLabel: tt("config.ha.url"),
892
- secretLabel: tt("config.ha.token")
1051
+ urlLabel: t("config.ha.url"),
1052
+ secretLabel: t("config.ha.token")
893
1053
  }),
894
1054
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(McpSection, {
895
- title: tt("config.tapd"),
1055
+ title: t("config.tapd"),
896
1056
  row: config.connections.tapd,
897
1057
  secret: secrets.tapd,
898
1058
  onEnabled: (enabled) => {
899
1059
  patchConnection("tapd", { enabled });
900
1060
  },
901
1061
  extra: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
902
- label: tt("config.tapd.workspaceId"),
1062
+ label: t("config.tapd.workspaceId"),
903
1063
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
904
1064
  className: panel_module_default.input,
905
1065
  value: config.connections.tapd.workspaceId ?? "",
@@ -908,7 +1068,7 @@ function ConfigTab({ api }) {
908
1068
  }
909
1069
  })
910
1070
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
911
- label: tt("config.tapd.nickName"),
1071
+ label: t("config.tapd.nickName"),
912
1072
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
913
1073
  className: panel_module_default.input,
914
1074
  value: config.connections.tapd.nickName ?? "",
@@ -923,17 +1083,17 @@ function ConfigTab({ api }) {
923
1083
  tapd: value
924
1084
  }));
925
1085
  },
926
- secretLabel: tt("config.tapd.token")
1086
+ secretLabel: t("config.tapd.token")
927
1087
  }),
928
1088
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(McpSection, {
929
- title: tt("config.gsc"),
1089
+ title: t("config.gsc"),
930
1090
  row: config.connections.gsc,
931
1091
  secret: secrets.gsc,
932
1092
  onEnabled: (enabled) => {
933
1093
  patchConnection("gsc", { enabled });
934
1094
  },
935
1095
  extra: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
936
- label: tt("config.gsc.siteUrl"),
1096
+ label: t("config.gsc.siteUrl"),
937
1097
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
938
1098
  className: panel_module_default.input,
939
1099
  value: config.connections.gsc.siteUrl ?? "",
@@ -948,13 +1108,32 @@ function ConfigTab({ api }) {
948
1108
  gsc: value
949
1109
  }));
950
1110
  },
951
- secretLabel: tt("config.gsc.key")
1111
+ secretLabel: t("config.gsc.key")
1112
+ }),
1113
+ config.role === "boss" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(McpSection, {
1114
+ title: t("config.tianyancha"),
1115
+ row: config.connections.tianyancha,
1116
+ secret: secrets.tianyancha,
1117
+ onEnabled: (enabled) => {
1118
+ patchConnection("tianyancha", { enabled });
1119
+ },
1120
+ onUrl: (url) => {
1121
+ patchConnection("tianyancha", { url });
1122
+ },
1123
+ onSecret: (value) => {
1124
+ setSecrets((prev) => ({
1125
+ ...prev,
1126
+ tianyancha: value
1127
+ }));
1128
+ },
1129
+ urlLabel: t("config.tianyancha.url"),
1130
+ secretLabel: t("config.tianyancha.token")
952
1131
  }),
953
1132
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Section, {
954
- title: tt("config.billing"),
1133
+ title: t("config.billing"),
955
1134
  children: [
956
1135
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
957
- label: tt("config.billing.input"),
1136
+ label: t("config.billing.input"),
958
1137
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
959
1138
  className: panel_module_default.input,
960
1139
  type: "number",
@@ -972,7 +1151,7 @@ function ConfigTab({ api }) {
972
1151
  })
973
1152
  }),
974
1153
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
975
- label: tt("config.billing.output"),
1154
+ label: t("config.billing.output"),
976
1155
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
977
1156
  className: panel_module_default.input,
978
1157
  type: "number",
@@ -990,7 +1169,7 @@ function ConfigTab({ api }) {
990
1169
  })
991
1170
  }),
992
1171
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
993
- label: tt("config.billing.budget"),
1172
+ label: t("config.billing.budget"),
994
1173
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
995
1174
  className: panel_module_default.input,
996
1175
  type: "number",
@@ -1018,7 +1197,7 @@ function ConfigTab({ api }) {
1018
1197
  onClick: () => {
1019
1198
  save();
1020
1199
  },
1021
- children: tt("config.save")
1200
+ children: t("config.save")
1022
1201
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1023
1202
  type: "button",
1024
1203
  className: panel_module_default.button,
@@ -1026,7 +1205,7 @@ function ConfigTab({ api }) {
1026
1205
  onClick: () => {
1027
1206
  test();
1028
1207
  },
1029
- children: testing ? tt("config.testing") : tt("config.test")
1208
+ children: testing ? t("config.testing") : t("config.test")
1030
1209
  })]
1031
1210
  }),
1032
1211
  message !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -1039,7 +1218,7 @@ function ConfigTab({ api }) {
1039
1218
  }),
1040
1219
  results.map((result) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1041
1220
  className: result.ok ? panel_module_default.message : panel_module_default.error,
1042
- children: tt("config.testResult", {
1221
+ children: t("config.testResult", {
1043
1222
  server: result.server,
1044
1223
  status: renderResult(result)
1045
1224
  })
@@ -1053,6 +1232,7 @@ function ConfigTab({ api }) {
1053
1232
  * Status tab: live MCP server states and registered-tool counts.
1054
1233
  */
1055
1234
  function StatusTab({ api }) {
1235
+ const t = useT();
1056
1236
  const [status, setStatus] = (0, react.useState)(null);
1057
1237
  const [error, setError] = (0, react.useState)("");
1058
1238
  const [loading, setLoading] = (0, react.useState)(true);
@@ -1072,7 +1252,7 @@ function StatusTab({ api }) {
1072
1252
  }, []);
1073
1253
  if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1074
1254
  className: panel_module_default.message,
1075
- children: tt("common.loading")
1255
+ children: t("common.loading")
1076
1256
  });
1077
1257
  if (status === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1078
1258
  className: panel_module_default.error,
@@ -1085,7 +1265,7 @@ function StatusTab({ api }) {
1085
1265
  className: panel_module_default.toolbar,
1086
1266
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1087
1267
  className: panel_module_default.message,
1088
- children: tt("status.total", {
1268
+ children: t("status.total", {
1089
1269
  role: status.role,
1090
1270
  count: status.totalRegisteredTools
1091
1271
  })
@@ -1095,12 +1275,12 @@ function StatusTab({ api }) {
1095
1275
  onClick: () => {
1096
1276
  load();
1097
1277
  },
1098
- children: tt("common.refresh")
1278
+ children: t("common.refresh")
1099
1279
  })]
1100
1280
  }),
1101
1281
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1102
1282
  className: panel_module_default.message,
1103
- children: tt("status.hint")
1283
+ children: t("status.hint")
1104
1284
  }),
1105
1285
  error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1106
1286
  className: panel_module_default.error,
@@ -1111,11 +1291,11 @@ function StatusTab({ api }) {
1111
1291
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
1112
1292
  className: panel_module_default.table,
1113
1293
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
1114
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: tt("status.col.server") }),
1115
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: tt("status.col.state") }),
1116
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: tt("status.col.tools") }),
1117
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: tt("status.col.registered") }),
1118
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: tt("status.col.error") })
1294
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("status.col.server") }),
1295
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("status.col.state") }),
1296
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("status.col.tools") }),
1297
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("status.col.registered") }),
1298
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("status.col.error") })
1119
1299
  ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: status.servers.map((server) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
1120
1300
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: server.server }),
1121
1301
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -1137,6 +1317,7 @@ function StatusTab({ api }) {
1137
1317
  * WeChat / QClaw tab: scan QR once, then talk in WeChat. No CLI, no MCP tools.
1138
1318
  */
1139
1319
  function WeixinTab({ api }) {
1320
+ const t = useT();
1140
1321
  const [status, setStatus] = (0, react.useState)(null);
1141
1322
  const [error, setError] = (0, react.useState)("");
1142
1323
  const [code, setCode] = (0, react.useState)("");
@@ -1197,7 +1378,7 @@ function WeixinTab({ api }) {
1197
1378
  children: [
1198
1379
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1199
1380
  className: panel_module_default.message,
1200
- children: tt("weixin.intro")
1381
+ children: t("weixin.intro")
1201
1382
  }),
1202
1383
  error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1203
1384
  className: panel_module_default.error,
@@ -1210,7 +1391,7 @@ function WeixinTab({ api }) {
1210
1391
  status?.qrDataUrl !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
1211
1392
  className: panel_module_default.qr,
1212
1393
  src: status.qrDataUrl,
1213
- alt: tt("weixin.qrAlt")
1394
+ alt: t("weixin.qrAlt")
1214
1395
  }),
1215
1396
  status?.qrContent !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1216
1397
  className: panel_module_default.message,
@@ -1229,7 +1410,7 @@ function WeixinTab({ api }) {
1229
1410
  onChange: (event) => {
1230
1411
  setCode(event.target.value);
1231
1412
  },
1232
- placeholder: tt("weixin.verifyPlaceholder")
1413
+ placeholder: t("weixin.verifyPlaceholder")
1233
1414
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1234
1415
  type: "button",
1235
1416
  className: panel_module_default.button,
@@ -1237,7 +1418,7 @@ function WeixinTab({ api }) {
1237
1418
  onClick: () => {
1238
1419
  verify();
1239
1420
  },
1240
- children: tt("weixin.verify")
1421
+ children: t("weixin.verify")
1241
1422
  })]
1242
1423
  }),
1243
1424
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -1249,7 +1430,7 @@ function WeixinTab({ api }) {
1249
1430
  onClick: () => {
1250
1431
  login();
1251
1432
  },
1252
- children: status?.loggedIn === true ? tt("weixin.reconnect") : tt("weixin.login")
1433
+ children: status?.loggedIn === true ? t("weixin.reconnect") : t("weixin.login")
1253
1434
  }), status?.loggedIn === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1254
1435
  type: "button",
1255
1436
  className: panel_module_default.button,
@@ -1257,12 +1438,12 @@ function WeixinTab({ api }) {
1257
1438
  onClick: () => {
1258
1439
  logout();
1259
1440
  },
1260
- children: tt("weixin.logout")
1441
+ children: t("weixin.logout")
1261
1442
  })]
1262
1443
  }),
1263
1444
  status !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1264
1445
  className: panel_module_default.message,
1265
- children: status.listening ? tt("weixin.listening") : status.loggedIn ? tt("weixin.loggedIn") : tt("weixin.loggedOut")
1446
+ children: status.listening ? t("weixin.listening") : status.loggedIn ? t("weixin.loggedIn") : t("weixin.loggedOut")
1266
1447
  })
1267
1448
  ]
1268
1449
  });
@@ -1272,91 +1453,99 @@ function WeixinTab({ api }) {
1272
1453
  /**
1273
1454
  * ReZ settings pages: one accordion card in 设置 → 插件 → 插件配置,
1274
1455
  * plus a dedicated Plugins tab for the same content.
1456
+ *
1457
+ * `t` is the official locale seat (zh/en follows 设置 → 语言).
1275
1458
  */
1276
- const TABS = [
1277
- {
1278
- id: "config",
1279
- label: () => tt("tab.config")
1280
- },
1281
- {
1282
- id: "weixin",
1283
- label: () => tt("tab.weixin")
1284
- },
1285
- {
1286
- id: "status",
1287
- label: () => tt("tab.status")
1288
- },
1289
- {
1290
- id: "audit",
1291
- label: () => tt("tab.audit")
1292
- }
1293
- ];
1294
- function RezSettingsPage() {
1459
+ function RezSettingsPage({ t }) {
1295
1460
  const api = (0, react.useMemo)(() => new RezApi(), []);
1296
1461
  const [activeTab, setActiveTab] = (0, react.useState)("config");
1297
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1298
- className: panel_module_default.shell,
1299
- children: [
1300
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1301
- className: panel_module_default.tabBar,
1302
- role: "tablist",
1303
- children: TABS.map((tab) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1304
- type: "button",
1305
- role: "tab",
1306
- "aria-selected": activeTab === tab.id,
1307
- "data-active": activeTab === tab.id ? "" : void 0,
1308
- className: panel_module_default.tab,
1309
- onClick: () => {
1310
- setActiveTab(tab.id);
1311
- },
1312
- children: tab.label()
1313
- }, tab.id))
1314
- }),
1315
- activeTab === "config" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConfigTab, { api }),
1316
- activeTab === "weixin" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WeixinTab, { api }),
1317
- activeTab === "status" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusTab, { api }),
1318
- activeTab === "audit" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AuditTab, { api })
1319
- ]
1462
+ const tabs = [
1463
+ {
1464
+ id: "config",
1465
+ label: t("tab.config")
1466
+ },
1467
+ {
1468
+ id: "weixin",
1469
+ label: t("tab.weixin")
1470
+ },
1471
+ {
1472
+ id: "status",
1473
+ label: t("tab.status")
1474
+ },
1475
+ {
1476
+ id: "audit",
1477
+ label: t("tab.audit")
1478
+ }
1479
+ ];
1480
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RezT.Provider, {
1481
+ value: t,
1482
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1483
+ className: panel_module_default.shell,
1484
+ children: [
1485
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1486
+ className: panel_module_default.tabBar,
1487
+ role: "tablist",
1488
+ children: tabs.map((tab) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1489
+ type: "button",
1490
+ role: "tab",
1491
+ "aria-selected": activeTab === tab.id,
1492
+ "data-active": activeTab === tab.id ? "" : void 0,
1493
+ className: panel_module_default.tab,
1494
+ onClick: () => {
1495
+ setActiveTab(tab.id);
1496
+ },
1497
+ children: tab.label
1498
+ }, tab.id))
1499
+ }),
1500
+ activeTab === "config" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConfigTab, { api }),
1501
+ activeTab === "weixin" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WeixinTab, { api }),
1502
+ activeTab === "status" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusTab, { api }),
1503
+ activeTab === "audit" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AuditTab, { api })
1504
+ ]
1505
+ })
1320
1506
  });
1321
1507
  }
1322
- function RezPluginCard() {
1508
+ function RezPluginCard({ t }) {
1323
1509
  const [open, setOpen] = (0, react.useState)(false);
1324
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
1325
- className: panel_module_default.card + (open ? " " + panel_module_default.cardOpen : ""),
1326
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1327
- type: "button",
1328
- className: panel_module_default.header,
1329
- onClick: () => {
1330
- setOpen(!open);
1331
- },
1332
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1333
- className: panel_module_default.headText,
1334
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1335
- className: panel_module_default.name,
1336
- children: tt("settings.title")
1337
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1338
- className: panel_module_default.description,
1339
- children: tt("settings.description")
1510
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RezT.Provider, {
1511
+ value: t,
1512
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
1513
+ className: panel_module_default.card + (open ? " " + panel_module_default.cardOpen : ""),
1514
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1515
+ type: "button",
1516
+ className: panel_module_default.header,
1517
+ onClick: () => {
1518
+ setOpen(!open);
1519
+ },
1520
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1521
+ className: panel_module_default.headText,
1522
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1523
+ className: panel_module_default.name,
1524
+ children: t("settings.title")
1525
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1526
+ className: panel_module_default.description,
1527
+ children: t("settings.description")
1528
+ })]
1529
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
1530
+ className: panel_module_default.chevron + (open ? " " + panel_module_default.chevronOpen : ""),
1531
+ viewBox: "0 0 14 14",
1532
+ width: "14",
1533
+ height: "14",
1534
+ "aria-hidden": "true",
1535
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1536
+ d: "M3 5l4 4 4-4",
1537
+ fill: "none",
1538
+ stroke: "currentColor",
1539
+ strokeWidth: "1.4",
1540
+ strokeLinecap: "round",
1541
+ strokeLinejoin: "round"
1542
+ })
1340
1543
  })]
1341
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
1342
- className: panel_module_default.chevron + (open ? " " + panel_module_default.chevronOpen : ""),
1343
- viewBox: "0 0 14 14",
1344
- width: "14",
1345
- height: "14",
1346
- "aria-hidden": "true",
1347
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1348
- d: "M3 5l4 4 4-4",
1349
- fill: "none",
1350
- stroke: "currentColor",
1351
- strokeWidth: "1.4",
1352
- strokeLinecap: "round",
1353
- strokeLinejoin: "round"
1354
- })
1355
- })]
1356
- }), open ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1357
- className: panel_module_default.body,
1358
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RezSettingsPage, {})
1359
- }) : null]
1544
+ }), open ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1545
+ className: panel_module_default.body,
1546
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RezSettingsPage, { t })
1547
+ }) : null]
1548
+ })
1360
1549
  });
1361
1550
  }
1362
1551
  //#endregion
@@ -1364,6 +1553,8 @@ function RezPluginCard() {
1364
1553
  /**
1365
1554
  * Sidebar footer action: upgrade @rezti/dsh-rez-suite without a terminal.
1366
1555
  * Host code still needs a process respawn; the button does that after pnpm add.
1556
+ *
1557
+ * `t` is the official locale seat (zh/en follows 设置 → 语言).
1367
1558
  */
1368
1559
  function UpgradeIcon() {
1369
1560
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
@@ -1381,7 +1572,7 @@ function UpgradeIcon() {
1381
1572
  })
1382
1573
  });
1383
1574
  }
1384
- async function waitUntilHostBack(api, timeoutMs = 6e4) {
1575
+ async function waitUntilHostBack(api, timeoutMessage, timeoutMs = 6e4) {
1385
1576
  const deadline = Date.now() + timeoutMs;
1386
1577
  await new Promise((resolve) => setTimeout(resolve, 800));
1387
1578
  while (Date.now() < deadline) try {
@@ -1390,9 +1581,9 @@ async function waitUntilHostBack(api, timeoutMs = 6e4) {
1390
1581
  } catch {
1391
1582
  await new Promise((resolve) => setTimeout(resolve, 700));
1392
1583
  }
1393
- throw new Error(tt("upgrade.reloadTimeout"));
1584
+ throw new Error(timeoutMessage);
1394
1585
  }
1395
- function UpgradeButton({ wide }) {
1586
+ function UpgradeButton({ wide, t }) {
1396
1587
  const api = (0, react.useMemo)(() => new RezApi(), []);
1397
1588
  const [info, setInfo] = (0, react.useState)();
1398
1589
  const [busy, setBusy] = (0, react.useState)(false);
@@ -1408,7 +1599,7 @@ function UpgradeButton({ wide }) {
1408
1599
  cancelled = true;
1409
1600
  };
1410
1601
  }, [api]);
1411
- const label = busy ? tt("upgrade.running") : info?.outdated === true ? tt("upgrade.label") : tt("upgrade.current");
1602
+ const label = busy ? t("upgrade.running") : info?.outdated === true ? t("upgrade.label") : t("upgrade.current");
1412
1603
  const meta = note !== "" ? note : info === void 0 ? "" : info.outdated ? info.latest : info.installed;
1413
1604
  async function onClick() {
1414
1605
  if (busy) return;
@@ -1418,18 +1609,18 @@ function UpgradeButton({ wide }) {
1418
1609
  const snapshot = info ?? await api.updateStatus();
1419
1610
  setInfo(snapshot);
1420
1611
  if (!snapshot.outdated) {
1421
- setNote(tt("upgrade.already", { version: snapshot.installed }));
1612
+ setNote(t("upgrade.already", { version: snapshot.installed }));
1422
1613
  return;
1423
1614
  }
1424
1615
  const result = await api.applyUpdate();
1425
1616
  setInfo(result);
1426
1617
  if (result.restarting) {
1427
- setNote(tt("upgrade.reloading"));
1428
- await waitUntilHostBack(api);
1618
+ setNote(t("upgrade.reloading"));
1619
+ await waitUntilHostBack(api, t("upgrade.reloadTimeout"));
1429
1620
  window.location.reload();
1430
1621
  return;
1431
1622
  }
1432
- setNote(tt("upgrade.already", { version: result.installed }));
1623
+ setNote(t("upgrade.already", { version: result.installed }));
1433
1624
  } catch (error) {
1434
1625
  setNote(error instanceof Error ? error.message : String(error));
1435
1626
  } finally {
@@ -1442,7 +1633,7 @@ function UpgradeButton({ wide }) {
1442
1633
  type: "button",
1443
1634
  className: panel_module_default.upgradeButton,
1444
1635
  "data-outdated": info?.outdated === true ? "" : void 0,
1445
- "aria-label": tt("upgrade.aria"),
1636
+ "aria-label": t("upgrade.aria"),
1446
1637
  disabled: busy,
1447
1638
  onClick: () => {
1448
1639
  onClick();
@@ -1472,6 +1663,16 @@ function apply(ctx) {
1472
1663
  zh,
1473
1664
  en
1474
1665
  }), "dsh-rez-suite: dictionaries");
1666
+ ctx.effect(() => {
1667
+ const stop = mountRezBrand(t);
1668
+ const unsub = ctx.locale.subscribe(() => {
1669
+ if (typeof document !== "undefined") paintBrand(document, t);
1670
+ });
1671
+ return () => {
1672
+ unsub();
1673
+ stop();
1674
+ };
1675
+ }, "dsh-rez-suite: brand");
1475
1676
  ctx.slots.inject("settings.plugin.item", () => ctx.slots.register({
1476
1677
  name: "settings.plugin.item",
1477
1678
  key: NS,