@rezti/dsh-rez-suite 0.1.49 → 0.1.50

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 (60) hide show
  1. package/CHANGELOG.md +8 -2
  2. package/README.md +3 -3
  3. package/README.zh.md +2 -2
  4. package/cordis.patch.yml +1 -1
  5. package/lib/client.d.ts +31 -3
  6. package/lib/client.js +329 -7
  7. package/lib/index.js +241 -15
  8. package/lib/style.css +7 -0
  9. package/package.json +4 -3
  10. package/src/boss/mount.ts +4 -3
  11. package/src/boss/register.ts +1 -1
  12. package/src/boss/seed.ts +29 -0
  13. package/src/changelog.ts +33 -0
  14. package/src/channel-board.ts +55 -0
  15. package/src/client/locales.ts +62 -6
  16. package/src/client/panel/BoardTab.tsx +136 -0
  17. package/src/client/panel/ConfigTab.tsx +2 -2
  18. package/src/client/panel/StatusTab.tsx +31 -0
  19. package/src/client/panel/panel.module.css +7 -0
  20. package/src/client/settings-card.tsx +4 -1
  21. package/src/index.ts +3 -2
  22. package/src/protocol.ts +14 -0
  23. package/src/routes.ts +7 -1
  24. package/src/tools.ts +49 -6
  25. package/src/wecom-cli.ts +125 -0
  26. package/templates/boss/ops/AGENTS.md +2 -0
  27. package/templates/shared/wecom-cli.SOURCE.md +5 -0
  28. package/templates/shared/wecom-office/SKILL.md +31 -0
  29. package/templates/shared/wecomcli-calendar/SKILL.md +303 -0
  30. package/templates/shared/wecomcli-contact/SKILL.md +58 -0
  31. package/templates/shared/wecomcli-disk/SKILL.md +389 -0
  32. package/templates/shared/wecomcli-doc/SKILL.md +137 -0
  33. package/templates/shared/wecomcli-doc-manage/SKILL.md +132 -0
  34. package/templates/shared/wecomcli-email/SKILL.md +218 -0
  35. package/templates/shared/wecomcli-media/SKILL.md +98 -0
  36. package/templates/shared/wecomcli-meeting/SKILL.md +373 -0
  37. package/templates/shared/wecomcli-message/SKILL.md +200 -0
  38. package/templates/shared/wecomcli-shared/SKILL.md +73 -0
  39. package/templates/shared/wecomcli-sheet/SKILL.md +172 -0
  40. package/templates/shared/wecomcli-smartpage/SKILL.md +170 -0
  41. package/templates/shared/wecomcli-smartsheet/SKILL.md +154 -0
  42. package/templates/shared/wecomcli-todo/SKILL.md +76 -0
  43. package/templates/staff/design/AGENTS.md +2 -1
  44. package/templates/staff/ecommerce/.agents/skills/ops-ecommerce/SKILL.md +6 -0
  45. package/templates/staff/ecommerce/AGENTS.md +48 -0
  46. package/templates/staff/ecommerce/BOOTSTRAP.md +23 -0
  47. package/templates/staff/ecommerce/IDENTITY.md +8 -0
  48. package/templates/staff/ecommerce/MEMORY.md +9 -0
  49. package/templates/staff/ecommerce/PRIORITIES.md +3 -0
  50. package/templates/staff/ecommerce/SOUL.md +5 -0
  51. package/templates/staff/ecommerce/USER.md +8 -0
  52. package/templates/staff/hr/.agents/skills/staff-onboard-keys/SKILL.md +1 -1
  53. package/templates/staff/publish/.agents/skills/ops-publish/SKILL.md +6 -0
  54. package/templates/staff/publish/AGENTS.md +56 -0
  55. package/templates/staff/publish/BOOTSTRAP.md +23 -0
  56. package/templates/staff/publish/IDENTITY.md +8 -0
  57. package/templates/staff/publish/MEMORY.md +9 -0
  58. package/templates/staff/publish/PRIORITIES.md +3 -0
  59. package/templates/staff/publish/SOUL.md +6 -0
  60. package/templates/staff/publish/USER.md +8 -0
package/lib/client.js CHANGED
@@ -4,7 +4,7 @@ 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=".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_wecomRow {\n grid-template-columns: minmax(7rem, .8fr) minmax(8rem, 1fr) minmax(8rem, 1fr) auto;\n align-items: end;\n gap: 8px;\n display: grid;\n}\n\n.LOjPTW_wecomRow .LOjPTW_message {\n grid-column: 1 / -1;\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\n.LOjPTW_changelogDate {\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-tertiary);\n margin-left: 8px;\n font-weight: 500;\n}\n\n.LOjPTW_changelogBlock {\n flex-direction: column;\n gap: 6px;\n display: flex;\n}\n\n.LOjPTW_changelogHeading {\n color: var(--dsw-alias-label-secondary);\n font-size: 12.5px;\n font-weight: 600;\n}\n\n.LOjPTW_changelogList {\n color: var(--dsw-alias-label-primary);\n flex-direction: column;\n gap: 6px;\n margin: 0;\n padding-left: 18px;\n font-size: 13px;\n line-height: 1.55;\n display: flex;\n}\n\n.LOjPTW_changelogList li + li {\n margin: 0;\n}\n\n.LOjPTW_changelogCode {\n background: var(--dsw-alias-bg-layer-3);\n border: 1px solid var(--dsw-alias-border-l2);\n word-break: break-all;\n border-radius: 6px;\n padding: 1px 6px;\n font-size: 12px;\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_wecomRow {\n grid-template-columns: minmax(7rem, .8fr) minmax(8rem, 1fr) minmax(8rem, 1fr) auto;\n align-items: end;\n gap: 8px;\n display: grid;\n}\n\n.LOjPTW_wecomRow .LOjPTW_message {\n grid-column: 1 / -1;\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_boardTitle {\n color: var(--dsw-alias-label-primary);\n margin: 16px 0 4px;\n font-size: 13px;\n font-weight: 600;\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\n.LOjPTW_changelogDate {\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-tertiary);\n margin-left: 8px;\n font-weight: 500;\n}\n\n.LOjPTW_changelogBlock {\n flex-direction: column;\n gap: 6px;\n display: flex;\n}\n\n.LOjPTW_changelogHeading {\n color: var(--dsw-alias-label-secondary);\n font-size: 12.5px;\n font-weight: 600;\n}\n\n.LOjPTW_changelogList {\n color: var(--dsw-alias-label-primary);\n flex-direction: column;\n gap: 6px;\n margin: 0;\n padding-left: 18px;\n font-size: 13px;\n line-height: 1.55;\n display: flex;\n}\n\n.LOjPTW_changelogList li + li {\n margin: 0;\n}\n\n.LOjPTW_changelogCode {\n background: var(--dsw-alias-bg-layer-3);\n border: 1px solid var(--dsw-alias-border-l2);\n word-break: break-all;\n border-radius: 6px;\n padding: 1px 6px;\n font-size: 12px;\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");
@@ -142,12 +142,13 @@ const zh = {
142
142
  "settings.description": "公司 MCP(Odoo / Nextcloud / HA / TAPD / GSC)和企业微信智能机器人。个人微信在「微信」页签扫码。",
143
143
  "panel.title": "Rez Suite",
144
144
  "tab.config": "配置",
145
+ "tab.board": "看板",
145
146
  "tab.weixin": "微信",
146
147
  "tab.status": "状态",
147
148
  "tab.audit": "用量",
148
149
  "tab.changelog": "更新日志",
149
150
  "config.role": "角色",
150
- "config.roleHint": "选身份后左侧自动出现工作区。人事/财务/法务助理全员可见;设计房间仅「运营」;实验室仅「工程师」;搞钱/产品/运营仅「老板」。",
151
+ "config.roleHint": "选身份后左侧自动出现工作区。人事/财务/法务助理全员可见;设计、发布、电商房间仅「运营」;实验室仅「工程师」;搞钱/产品/运营仅「老板」。",
151
152
  "role.all": "全部",
152
153
  "role.boss": "老板",
153
154
  "role.engineer": "工程师",
@@ -175,7 +176,7 @@ const zh = {
175
176
  "config.wecom.botId": "Bot ID",
176
177
  "config.wecom.secret": "Secret",
177
178
  "config.wecom.webhook": "群机器人 Webhook",
178
- "config.wecom.hint": "Accio 同款:一个房间绑一个智能机器人。同事在企微跟哪个 bot 说话,就进网页左侧那个房间。密钥只存本机 ~/.dsh/wecom-channels.json,不要写进 compose。BotID / Secret 在企业微信管理后台 → 智能机器人。",
179
+ "config.wecom.hint": "Accio 同款:一个房间绑一个智能机器人。同事在企微跟哪个 bot 说话,就进网页左侧那个房间的同一条会话。密钥只存本机 ~/.dsh/wecom-channels.json,不要写进 compose。BotID / Secret 在企业微信管理后台 → 智能机器人。",
179
180
  "config.wecom.room": "房间",
180
181
  "config.wecom.add": "添加绑定",
181
182
  "config.wecom.remove": "删除",
@@ -215,7 +216,7 @@ const zh = {
215
216
  "config.testResult": "{server}: {status}",
216
217
  "config.testOk": "成功({tools} 个工具, {latency}ms)",
217
218
  "config.testFail": "失败:{error}",
218
- "status.hint": "绿标表示本机已注册 mcp__<系统>__* 工具。远端 MCP 通了但这里仍红,说明 dsh-mcp-client 还没挂上。企查查只在法务助理房间可用;其它房间不显示或显示「房间未启用」。",
219
+ "status.hint": "绿标表示本机已注册 mcp__<系统>__* 工具。远端 MCP 通了但这里仍红,说明 dsh-mcp-client 还没挂上。企微办公能力看下方 wecom-cli,不是 MCP 表。企查查只在法务助理房间可用;其它房间不显示或显示「房间未启用」。",
219
220
  "status.total": "当前角色 {role},共注册 {count} 个 MCP 工具",
220
221
  "status.col.server": "Server",
221
222
  "status.col.state": "状态",
@@ -223,6 +224,12 @@ const zh = {
223
224
  "status.col.registered": "已注册",
224
225
  "status.col.error": "错误",
225
226
  "status.none": "暂无状态",
227
+ "status.wecomCli": "企业微信办公(官方 wecom-cli,不是 MCP)",
228
+ "status.wecomCli.installed": "CLI",
229
+ "status.wecomCli.authorized": "授权",
230
+ "status.wecomCli.yes": "已就绪",
231
+ "status.wecomCli.no": "未就绪",
232
+ "status.wecomCli.modules": "品类",
226
233
  "audit.totalCalls": "调用次数",
227
234
  "audit.inputTokens": "输入 token",
228
235
  "audit.outputTokens": "输出 token",
@@ -244,6 +251,27 @@ const zh = {
244
251
  "audit.empty": "暂无记录",
245
252
  "changelog.current": "当前 {version}",
246
253
  "changelog.upgrade": "升级:",
254
+ "board.hint": "合同 Account 拆两室:媒体走「发布」,电商走「电商」(一期只阿里巴巴国际站;Amazon 等有号)。不是独立后台。密钥不在这里。",
255
+ "board.people": "People / 权限",
256
+ "board.peopleHint": "继续 Odoo 员工帐号(公司/记录规则)+ 企业微信一房间一 bot。不新建权限库,不改 Odoo 权限组。",
257
+ "board.role": "当前 Harness 身份:{role}(只决定侧栏房间)",
258
+ "board.media": "媒体连接",
259
+ "board.mediaHint": "内容/社媒在「发布」工作间(Post editor)。不建图库。",
260
+ "board.ecommerce": "电商平台",
261
+ "board.ecommerceHint": "Listing 在「电商」工作间。一期只有阿里巴巴国际站。渠道商品 ID 写回 Odoo,库存从 Odoo 推到阿里。Amazon 没有号,标后续。",
262
+ "board.rag": "RAG",
263
+ "board.ragHint": "基于已有 Dify,知识库对接 Nextcloud 锁死路径(Standards + Marketing/Publish)。Harness 不做推理。",
264
+ "board.inbox": "Message inbox",
265
+ "board.inboxHint": "一期只做 WhatsApp Business,会话落到 Odoo(浙江雷泽,Business 号已有)。不用官方收费模块,走社区 add-on(OCA mail_gateway_whatsapp)。禁止自写 Meta 客户端。生产安装另开窗口。",
266
+ "board.col.source": "来源",
267
+ "board.col.state": "状态",
268
+ "board.col.channel": "渠道",
269
+ "board.col.room": "房间",
270
+ "board.col.phase": "阶段",
271
+ "board.bound": "已绑 bot",
272
+ "board.unbound": "未绑定",
273
+ "board.phase1": "一期",
274
+ "board.phaseLater": "后续",
247
275
  "common.close": "关闭",
248
276
  "common.loading": "加载中…",
249
277
  "common.error": "出错:{error}",
@@ -277,12 +305,13 @@ const en = {
277
305
  "settings.description": "Company MCP (Odoo / Nextcloud / HA / TAPD / GSC) and WeCom AI bots. Personal WeChat is the WeChat tab.",
278
306
  "panel.title": "Rez Suite",
279
307
  "tab.config": "Config",
308
+ "tab.board": "Board",
280
309
  "tab.weixin": "WeChat",
281
310
  "tab.status": "Status",
282
311
  "tab.audit": "Usage",
283
312
  "tab.changelog": "Changelog",
284
313
  "config.role": "Role",
285
- "config.roleHint": "Identity registers workspaces in the sidebar. Staff assistants for every role; 设计 for Operations only; 实验室 for Engineer only; 搞钱 / 产品 / 运营 for Boss only.",
314
+ "config.roleHint": "Identity registers workspaces in the sidebar. Staff assistants for every role; 设计 / 发布 / 电商 for Operations only; 实验室 for Engineer only; 搞钱 / 产品 / 运营 for Boss only.",
286
315
  "role.all": "All",
287
316
  "role.boss": "Boss",
288
317
  "role.engineer": "Engineer",
@@ -310,7 +339,7 @@ const en = {
310
339
  "config.wecom.botId": "Bot ID",
311
340
  "config.wecom.secret": "Secret",
312
341
  "config.wecom.webhook": "Group bot webhook",
313
- "config.wecom.hint": "Accio-style: one WeCom AI bot per Harness room. Whoever talks to that bot lands in that sidebar folder. Secrets stay in ~/.dsh/wecom-channels.json, not compose. BotID / Secret come from WeCom admin → AI bot.",
342
+ "config.wecom.hint": "Accio-style: one WeCom AI bot per Harness room. Whoever talks to that bot lands in the same sidebar session. Secrets stay in ~/.dsh/wecom-channels.json, not compose. BotID / Secret come from WeCom admin → AI bot.",
314
343
  "config.wecom.room": "Room",
315
344
  "config.wecom.add": "Add binding",
316
345
  "config.wecom.remove": "Remove",
@@ -350,7 +379,7 @@ const en = {
350
379
  "config.testResult": "{server}: {status}",
351
380
  "config.testOk": "OK ({tools} tools, {latency}ms)",
352
381
  "config.testFail": "Failed: {error}",
353
- "status.hint": "Green means this host registered mcp__<system>__* tools. A live remote MCP with a red row means dsh-mcp-client has not attached yet. Qichacha is only for the Legal assistant room; other rooms hide the row or show “room not enabled”.",
382
+ "status.hint": "Green means this host registered mcp__<system>__* tools. A live remote MCP with a red row means dsh-mcp-client has not attached yet. WeCom office APIs are the wecom-cli row below, not the MCP table. Qichacha is only for the Legal assistant room; other rooms hide the row or show “room not enabled”.",
354
383
  "status.total": "Role {role}, {count} MCP tools registered",
355
384
  "status.col.server": "Server",
356
385
  "status.col.state": "State",
@@ -358,6 +387,12 @@ const en = {
358
387
  "status.col.registered": "Registered",
359
388
  "status.col.error": "Error",
360
389
  "status.none": "No status yet",
390
+ "status.wecomCli": "WeCom office APIs (official wecom-cli, not MCP)",
391
+ "status.wecomCli.installed": "CLI",
392
+ "status.wecomCli.authorized": "Auth",
393
+ "status.wecomCli.yes": "Ready",
394
+ "status.wecomCli.no": "Not ready",
395
+ "status.wecomCli.modules": "Modules",
361
396
  "audit.totalCalls": "Calls",
362
397
  "audit.inputTokens": "Input tokens",
363
398
  "audit.outputTokens": "Output tokens",
@@ -379,6 +414,27 @@ const en = {
379
414
  "audit.empty": "No records",
380
415
  "changelog.current": "Now {version}",
381
416
  "changelog.upgrade": "Upgrade:",
417
+ "board.hint": "Account connections split into two rooms: media in 发布, ecommerce in 电商 (phase 1: Alibaba.com only; Amazon waits for an account). Not a separate admin site. Secrets stay off this board.",
418
+ "board.people": "People / permissions",
419
+ "board.peopleHint": "Keep Odoo employee accounts (company / record rules) plus one WeCom AI bot per room. No new ACL database. Do not change Odoo groups.",
420
+ "board.role": "Current Harness identity: {role} (sidebar rooms only)",
421
+ "board.media": "Media connections",
422
+ "board.mediaHint": "Content / social lives in the 发布 room (Post editor). No media library.",
423
+ "board.ecommerce": "Ecommerce platforms",
424
+ "board.ecommerceHint": "Listings live in the 电商 room. Phase 1 is Alibaba.com. Write channel product IDs back to Odoo and push stock Odoo → Alibaba. Amazon is later until we have an account.",
425
+ "board.rag": "RAG",
426
+ "board.ragHint": "Reuse Dify. Index Nextcloud locked paths (Standards + Marketing/Publish). Harness does not run embeddings.",
427
+ "board.inbox": "Message inbox",
428
+ "board.inboxHint": "Phase 1 is WhatsApp Business into Odoo (Zhejiang ReZ-TI; WABA already exists). Skip the paid official module; reuse OCA mail_gateway_whatsapp. No homemade Meta client. Production install needs a separate window.",
429
+ "board.col.source": "Source",
430
+ "board.col.state": "State",
431
+ "board.col.channel": "Channel",
432
+ "board.col.room": "Room",
433
+ "board.col.phase": "Phase",
434
+ "board.bound": "Bot bound",
435
+ "board.unbound": "Unbound",
436
+ "board.phase1": "Phase 1",
437
+ "board.phaseLater": "Later",
382
438
  "common.close": "Close",
383
439
  "common.loading": "Loading…",
384
440
  "common.error": "Error: {error}",
@@ -530,6 +586,7 @@ var panel_module_default = {
530
586
  "badge": "LOjPTW_badge",
531
587
  "badgeFail": "LOjPTW_badgeFail",
532
588
  "badgeOk": "LOjPTW_badgeOk",
589
+ "boardTitle": "LOjPTW_boardTitle",
533
590
  "body": "LOjPTW_body",
534
591
  "button": "LOjPTW_button",
535
592
  "card": "LOjPTW_card",
@@ -741,8 +798,238 @@ function AuditTab({ api }) {
741
798
  });
742
799
  }
743
800
  //#endregion
801
+ //#region src/channel-board.ts
802
+ const MEDIA_ROOM = "发布";
803
+ const ECOMMERCE_ROOM = "电商";
804
+ const CHANNEL_BOARD = [
805
+ {
806
+ id: "media_via_publish",
807
+ nameZh: "内容 / 社媒分发",
808
+ nameEn: "Content / social",
809
+ kind: "media",
810
+ room: MEDIA_ROOM,
811
+ phase: "1"
812
+ },
813
+ {
814
+ id: "alibaba_icbu",
815
+ nameZh: "阿里巴巴国际站",
816
+ nameEn: "Alibaba.com",
817
+ kind: "ecommerce",
818
+ room: ECOMMERCE_ROOM,
819
+ phase: "1"
820
+ },
821
+ {
822
+ id: "amazon",
823
+ nameZh: "Amazon",
824
+ nameEn: "Amazon",
825
+ kind: "ecommerce",
826
+ room: ECOMMERCE_ROOM,
827
+ phase: "later"
828
+ }
829
+ ];
830
+ function channelsFor(kind) {
831
+ return CHANNEL_BOARD.filter((row) => row.kind === kind);
832
+ }
833
+ function wecomBound(room, bots) {
834
+ return bots.some((bot) => bot.room === room);
835
+ }
836
+ //#endregion
837
+ //#region src/client/panel/BoardTab.tsx
838
+ /**
839
+ * Account board: media (发布) vs ecommerce (电商; phase 1 Alibaba, Amazon later).
840
+ * People = Odoo user + WeCom room bots. No new ACL store.
841
+ */
842
+ function BoardTab({ api }) {
843
+ const t = useT();
844
+ const [config, setConfig] = (0, react.useState)(null);
845
+ const [bots, setBots] = (0, react.useState)([]);
846
+ const [error, setError] = (0, react.useState)("");
847
+ const [loading, setLoading] = (0, react.useState)(true);
848
+ const load = async () => {
849
+ setLoading(true);
850
+ setError("");
851
+ try {
852
+ const next = await api.getConfig();
853
+ setConfig(next);
854
+ try {
855
+ const wecom = await api.wecomChannels();
856
+ setBots(wecom.bots);
857
+ } catch {
858
+ setBots([]);
859
+ }
860
+ } catch (err) {
861
+ setError(errorMessage(err));
862
+ } finally {
863
+ setLoading(false);
864
+ }
865
+ };
866
+ (0, react.useEffect)(() => {
867
+ load();
868
+ }, []);
869
+ if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
870
+ className: panel_module_default.message,
871
+ children: t("common.loading")
872
+ });
873
+ if (config === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
874
+ className: panel_module_default.error,
875
+ children: error
876
+ });
877
+ const odooOk = config.connections.odoo.secretConfigured;
878
+ const lang = t("tab.config") === "配置" ? "zh" : "en";
879
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
880
+ className: panel_module_default.tabBody,
881
+ children: [
882
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
883
+ className: panel_module_default.toolbar,
884
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
885
+ className: panel_module_default.message,
886
+ children: t("board.hint")
887
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
888
+ type: "button",
889
+ className: panel_module_default.button,
890
+ onClick: () => {
891
+ load();
892
+ },
893
+ children: t("common.refresh")
894
+ })]
895
+ }),
896
+ error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
897
+ className: panel_module_default.error,
898
+ children: error
899
+ }),
900
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
901
+ className: panel_module_default.boardTitle,
902
+ children: t("board.people")
903
+ }),
904
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
905
+ className: panel_module_default.message,
906
+ children: t("board.peopleHint")
907
+ }),
908
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
909
+ className: panel_module_default.tableWrap,
910
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
911
+ className: panel_module_default.table,
912
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("board.col.source") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("board.col.state") })] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tbody", { children: [
913
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: "Odoo" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
914
+ className: panel_module_default.badge + " " + (odooOk ? panel_module_default.badgeOk : panel_module_default.badgeFail),
915
+ children: odooOk ? t("config.secretConfigured") : t("config.secretMissing")
916
+ }) })] }),
917
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("td", { children: ["WeCom · ", MEDIA_ROOM] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
918
+ className: panel_module_default.badge + " " + (wecomBound("发布", bots) ? panel_module_default.badgeOk : panel_module_default.badgeFail),
919
+ children: wecomBound("发布", bots) ? t("board.bound") : t("board.unbound")
920
+ }) })] }),
921
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("td", { children: ["WeCom · ", ECOMMERCE_ROOM] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
922
+ className: panel_module_default.badge + " " + (wecomBound("电商", bots) ? panel_module_default.badgeOk : panel_module_default.badgeFail),
923
+ children: wecomBound("电商", bots) ? t("board.bound") : t("board.unbound")
924
+ }) })] })
925
+ ] })]
926
+ })
927
+ }),
928
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
929
+ className: panel_module_default.message,
930
+ children: t("board.role", { role: config.role })
931
+ }),
932
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
933
+ className: panel_module_default.boardTitle,
934
+ children: t("board.media")
935
+ }),
936
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
937
+ className: panel_module_default.message,
938
+ children: t("board.mediaHint")
939
+ }),
940
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChannelTable, {
941
+ kind: "media",
942
+ lang
943
+ }),
944
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
945
+ className: panel_module_default.boardTitle,
946
+ children: t("board.ecommerce")
947
+ }),
948
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
949
+ className: panel_module_default.message,
950
+ children: t("board.ecommerceHint")
951
+ }),
952
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChannelTable, {
953
+ kind: "ecommerce",
954
+ lang
955
+ }),
956
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
957
+ className: panel_module_default.boardTitle,
958
+ children: t("board.rag")
959
+ }),
960
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
961
+ className: panel_module_default.message,
962
+ children: t("board.ragHint")
963
+ }),
964
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
965
+ className: panel_module_default.boardTitle,
966
+ children: t("board.inbox")
967
+ }),
968
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
969
+ className: panel_module_default.message,
970
+ children: t("board.inboxHint")
971
+ })
972
+ ]
973
+ });
974
+ }
975
+ function ChannelTable({ kind, lang }) {
976
+ const t = useT();
977
+ const rows = channelsFor(kind);
978
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
979
+ className: panel_module_default.tableWrap,
980
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
981
+ className: panel_module_default.table,
982
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
983
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("board.col.channel") }),
984
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("board.col.room") }),
985
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("board.col.phase") })
986
+ ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: rows.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
987
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: lang === "zh" ? row.nameZh : row.nameEn }),
988
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: row.room }),
989
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: row.phase === "1" ? t("board.phase1") : t("board.phaseLater") })
990
+ ] }, row.id)) })]
991
+ })
992
+ });
993
+ }
994
+ //#endregion
744
995
  //#region src/changelog.ts
745
996
  const SUITE_CHANGELOG = [
997
+ {
998
+ version: "0.1.50",
999
+ date: "2026-08-20",
1000
+ sections: [
1001
+ {
1002
+ title: {
1003
+ zh: "运营发布工作间",
1004
+ en: "Operations publish room"
1005
+ },
1006
+ items: [{
1007
+ zh: "运营身份侧栏多了「发布」房间(合同 Post editor / 媒体连接)和「电商」房间(一期只阿里巴巴国际站;Amazon 等有号)。设置页「看板」看两室状态与 Odoo/企微权限。不建图库,排期写企微共享日历。员工机安装包仍钉已发布版本,不要改审批镜像。",
1008
+ en: "Operations now gets 发布 (media / Post editor) and 电商 (phase 1: Alibaba.com; Amazon waits for an account). The settings Board tab shows channel status plus Odoo/WeCom identity. No media library; schedule goes to one shared WeCom calendar. Do not bump the installer SUITE_VERSION."
1009
+ }]
1010
+ },
1011
+ {
1012
+ title: {
1013
+ zh: "企微固定对话框",
1014
+ en: "Sticky WeCom sessions"
1015
+ },
1016
+ items: [{
1017
+ zh: "同一房间连续说话复用网页左侧同一条会话。只有「重启对话」才新开。",
1018
+ en: "WeCom turns in one room reuse the same sidebar session. Only “重启对话” opens a new one."
1019
+ }]
1020
+ },
1021
+ {
1022
+ title: {
1023
+ zh: "企微办公能力",
1024
+ en: "WeCom office APIs"
1025
+ },
1026
+ items: [{
1027
+ zh: "rez_status / 状态页报官方 wecom-cli >=1.1 品类(通讯录/在线文档/表格/待办/日程/会议/邮件/微盘等)。房间种入官方 wecomcli-* 技能。不要把「没有 wechat MCP」或旧的 10 人限制当成没有企微能力。BotID 只是房间消息通道。不改员工机安装包。",
1028
+ en: "rez_status lists official wecom-cli >=1.1 modules (contacts/docs/sheets/todos/calendar/meetings/mail/disk). Rooms get upstream wecomcli-* skills. A missing wechat MCP row is not “no WeCom”. BotID is only the room chat channel. Do not bump the installer."
1029
+ }]
1030
+ }
1031
+ ]
1032
+ },
746
1033
  {
747
1034
  version: "0.1.49",
748
1035
  date: "2026-08-19",
@@ -1179,6 +1466,8 @@ function ConfigTab({ api }) {
1179
1466
  "财务助理",
1180
1467
  "法务助理",
1181
1468
  "设计",
1469
+ "发布",
1470
+ "电商",
1182
1471
  "实验室"
1183
1472
  ]);
1184
1473
  setWecomDrafts(toWecomDrafts(wecom.bots));
@@ -1192,6 +1481,8 @@ function ConfigTab({ api }) {
1192
1481
  "财务助理",
1193
1482
  "法务助理",
1194
1483
  "设计",
1484
+ "发布",
1485
+ "电商",
1195
1486
  "实验室"
1196
1487
  ]);
1197
1488
  }
@@ -1721,6 +2012,32 @@ function StatusTab({ api }) {
1721
2012
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: server.lastError ?? "" })
1722
2013
  ] }, server.server)) })]
1723
2014
  })
2015
+ }),
2016
+ status.wecomCli !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2017
+ className: panel_module_default.tableWrap,
2018
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2019
+ className: panel_module_default.message,
2020
+ children: t("status.wecomCli")
2021
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
2022
+ className: panel_module_default.table,
2023
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
2024
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("status.wecomCli.installed") }),
2025
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("status.wecomCli.authorized") }),
2026
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("status.wecomCli.modules") }),
2027
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("status.col.error") })
2028
+ ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
2029
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2030
+ className: panel_module_default.badge + " " + (status.wecomCli.installed ? panel_module_default.badgeOk : panel_module_default.badgeFail),
2031
+ children: status.wecomCli.installed ? t("status.wecomCli.yes") : t("status.wecomCli.no")
2032
+ }) }),
2033
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2034
+ className: panel_module_default.badge + " " + (status.wecomCli.authorized ? panel_module_default.badgeOk : panel_module_default.badgeFail),
2035
+ children: status.wecomCli.authorized ? t("status.wecomCli.yes") : t("status.wecomCli.no")
2036
+ }) }),
2037
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: (status.wecomCli.modules ?? []).map((row) => row.label).join("、") }),
2038
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: status.wecomCli.hint })
2039
+ ] }) })]
2040
+ })]
1724
2041
  })
1725
2042
  ]
1726
2043
  });
@@ -1878,6 +2195,10 @@ function RezSettingsPage({ t }) {
1878
2195
  id: "config",
1879
2196
  label: t("tab.config")
1880
2197
  },
2198
+ {
2199
+ id: "board",
2200
+ label: t("tab.board")
2201
+ },
1881
2202
  {
1882
2203
  id: "weixin",
1883
2204
  label: t("tab.weixin")
@@ -1916,6 +2237,7 @@ function RezSettingsPage({ t }) {
1916
2237
  }, tab.id))
1917
2238
  }),
1918
2239
  activeTab === "config" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConfigTab, { api }),
2240
+ activeTab === "board" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BoardTab, { api }),
1919
2241
  activeTab === "weixin" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WeixinTab, { api }),
1920
2242
  activeTab === "status" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusTab, { api }),
1921
2243
  activeTab === "audit" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AuditTab, { api }),