@rezti/dsh-rez-suite 0.1.21 → 0.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @rezti/dsh-rez-suite
2
2
 
3
- 雷泽插件的**唯一安装入口**。Odoo / 企微 / HA / 老板三室等都由这一包拉齐,不要再逐个 `plugin add`。
3
+ 雷泽插件的**唯一安装入口**。Odoo / 企微 / HA / TAPD / GSC / 老板三室等都由这一包拉齐,不要再逐个 `plugin add`。
4
4
 
5
5
  ```bash
6
6
  # 第一次
package/README.zh.md CHANGED
@@ -46,6 +46,17 @@ DSH Web GUI 的「Rez Suite」插件包:在插件内部启动一个 MCP Host
46
46
  "TAPD_NICK_NAME": "凯文智能家居"
47
47
  }
48
48
  },
49
+ "gsc": {
50
+ "enabled": false,
51
+ "transport": "stdio",
52
+ "command": "npx",
53
+ "args": ["-y", "mcp-server-gsc"],
54
+ "env": {
55
+ "GOOGLE_APPLICATION_CREDENTIALS": "~/.dsh/gsc-service-account.json",
56
+ "GSC_KEY_FILE": "~/.dsh/gsc-service-account.json",
57
+ "GSC_SITE_URL": "sc-domain:rez-ti.com"
58
+ }
59
+ },
49
60
  "dify": {
50
61
  "enabled": false,
51
62
  "transport": "stdio",
@@ -93,9 +104,9 @@ dsh plugin --profile web add link:$(pwd)
93
104
 
94
105
  MCP 工具按 \`mcp__<server>__<rawName>\` 注册,Preset 加载器用通配符匹配 \`server + 工具名\`。规则位于 \`src/presets.ts\`,可按团队实际工具名调整;\`role: all\` 注册全部工具。
95
106
 
96
- - \`engineer\`:odoo 检索/读取、homeassistant 状态读取、tapd/dify 查询、fs/sqlite 读取
107
+ - \`engineer\`:odoo 检索/读取、homeassistant 状态读取、tapd/gsc 查询、fs/sqlite 读取
97
108
  - \`sales\`:odoo CRM/销售、nextcloud 上传、wecom 发送
98
- - \`operations\`:odoo 报表/库存/采购、homeassistant 控制、tapd 增删改、dify workflow、nextcloud 管理、wecom 群发
109
+ - \`operations\`:odoo 报表/库存/采购、homeassistant 控制、tapd 增删改、gsc 查询、nextcloud 管理、wecom 群发
99
110
 
100
111
  ## Token / 审计
101
112
 
package/cordis.patch.yml CHANGED
@@ -20,5 +20,9 @@
20
20
  name: '@rezti/dsh-rez-wechat'
21
21
  - id: rez-ha-bridge
22
22
  name: '@rezti/dsh-rez-ha-bridge'
23
+ - id: rez-tapd
24
+ name: '@rezti/dsh-rez-tapd'
25
+ - id: rez-gsc
26
+ name: '@rezti/dsh-rez-gsc'
23
27
  - id: rez-suite
24
28
  name: '@rezti/dsh-rez-suite'
package/lib/client.d.ts CHANGED
@@ -7255,7 +7255,7 @@ declare const zh: {
7255
7255
  readonly 'entry.label': "Rez";
7256
7256
  readonly 'entry.tooltip': "Rez Suite 配置与审计面板";
7257
7257
  readonly 'settings.title': "ReZ-TI";
7258
- readonly 'settings.description': "公司 MCP(Odoo / Nextcloud / 企微 / HA)与个人微信扫码通道。";
7258
+ readonly 'settings.description': "公司 MCP(Odoo / Nextcloud / 企微 / HA / TAPD / GSC)与个人微信扫码通道。";
7259
7259
  readonly 'panel.title': "Rez Suite";
7260
7260
  readonly 'tab.config': "配置";
7261
7261
  readonly 'tab.weixin': "微信";
@@ -7276,7 +7276,7 @@ declare const zh: {
7276
7276
  readonly 'config.env': "环境变量 (JSON)";
7277
7277
  readonly 'config.headers': "Headers (JSON)";
7278
7278
  readonly 'config.jsonInvalid': "JSON 格式错误:{error}";
7279
- readonly 'config.mcpHint': "四个公司 MCP 在这里配。密钥写入 ~/.dsh/.credentials.yaml(REZ_*)。新填的密钥会立刻拉起连接;改 URL 后如果已经连上,需要重启 dsh web。";
7279
+ readonly 'config.mcpHint': "公司 MCP 在这里配。密钥写入 ~/.dsh/.credentials.yaml(REZ_*)。新填的密钥会立刻拉起连接;改 URL / 项目 / 站点后如果已经连上,需要重启 dsh web。";
7280
7280
  readonly 'config.secretConfigured': "已配置(留空则保持)";
7281
7281
  readonly 'config.secretMissing': "未配置";
7282
7282
  readonly 'config.odoo': "Odoo";
@@ -7293,6 +7293,13 @@ declare const zh: {
7293
7293
  readonly 'config.ha': "Home Assistant";
7294
7294
  readonly 'config.ha.url': "HA MCP URL";
7295
7295
  readonly 'config.ha.token': "长期访问令牌";
7296
+ readonly 'config.tapd': "TAPD";
7297
+ readonly 'config.tapd.workspaceId': "项目 ID";
7298
+ readonly 'config.tapd.nickName': "昵称";
7299
+ readonly 'config.tapd.token': "Access Token";
7300
+ readonly 'config.gsc': "Google Search Console";
7301
+ readonly 'config.gsc.siteUrl': "站点 URL";
7302
+ readonly 'config.gsc.key': "服务账号 JSON 或密钥文件路径";
7296
7303
  readonly 'config.fs': "本地文件 (fs-mcp-server)";
7297
7304
  readonly 'config.fs.root': "根目录";
7298
7305
  readonly 'config.sqlite': "SQLite (sqlite-mcp-server)";
package/lib/client.js CHANGED
@@ -16,7 +16,7 @@ const zh = {
16
16
  "entry.label": "Rez",
17
17
  "entry.tooltip": "Rez Suite 配置与审计面板",
18
18
  "settings.title": "ReZ-TI",
19
- "settings.description": "公司 MCP(Odoo / Nextcloud / 企微 / HA)与个人微信扫码通道。",
19
+ "settings.description": "公司 MCP(Odoo / Nextcloud / 企微 / HA / TAPD / GSC)与个人微信扫码通道。",
20
20
  "panel.title": "Rez Suite",
21
21
  "tab.config": "配置",
22
22
  "tab.weixin": "微信",
@@ -37,7 +37,7 @@ const zh = {
37
37
  "config.env": "环境变量 (JSON)",
38
38
  "config.headers": "Headers (JSON)",
39
39
  "config.jsonInvalid": "JSON 格式错误:{error}",
40
- "config.mcpHint": "四个公司 MCP 在这里配。密钥写入 ~/.dsh/.credentials.yaml(REZ_*)。新填的密钥会立刻拉起连接;改 URL 后如果已经连上,需要重启 dsh web。",
40
+ "config.mcpHint": "公司 MCP 在这里配。密钥写入 ~/.dsh/.credentials.yaml(REZ_*)。新填的密钥会立刻拉起连接;改 URL / 项目 / 站点后如果已经连上,需要重启 dsh web。",
41
41
  "config.secretConfigured": "已配置(留空则保持)",
42
42
  "config.secretMissing": "未配置",
43
43
  "config.odoo": "Odoo",
@@ -54,6 +54,13 @@ const zh = {
54
54
  "config.ha": "Home Assistant",
55
55
  "config.ha.url": "HA MCP URL",
56
56
  "config.ha.token": "长期访问令牌",
57
+ "config.tapd": "TAPD",
58
+ "config.tapd.workspaceId": "项目 ID",
59
+ "config.tapd.nickName": "昵称",
60
+ "config.tapd.token": "Access Token",
61
+ "config.gsc": "Google Search Console",
62
+ "config.gsc.siteUrl": "站点 URL",
63
+ "config.gsc.key": "服务账号 JSON 或密钥文件路径",
57
64
  "config.fs": "本地文件 (fs-mcp-server)",
58
65
  "config.fs.root": "根目录",
59
66
  "config.sqlite": "SQLite (sqlite-mcp-server)",
@@ -122,7 +129,7 @@ const en = {
122
129
  "entry.label": "Rez",
123
130
  "entry.tooltip": "Rez Suite configuration and audit panel",
124
131
  "settings.title": "ReZ-TI",
125
- "settings.description": "Company MCP (Odoo / Nextcloud / WeCom / HA) and personal WeChat scan-and-chat.",
132
+ "settings.description": "Company MCP (Odoo / Nextcloud / WeCom / HA / TAPD / GSC) and personal WeChat scan-and-chat.",
126
133
  "panel.title": "Rez Suite",
127
134
  "tab.config": "Config",
128
135
  "tab.weixin": "WeChat",
@@ -143,7 +150,7 @@ const en = {
143
150
  "config.env": "Env vars (JSON)",
144
151
  "config.headers": "Headers (JSON)",
145
152
  "config.jsonInvalid": "Invalid JSON: {error}",
146
- "config.mcpHint": "Company MCP lives here. Secrets go to ~/.dsh/.credentials.yaml (REZ_*). A newly saved secret starts the connection immediately; URL changes after a live connection need a dsh web restart.",
153
+ "config.mcpHint": "Company MCP lives here. Secrets go to ~/.dsh/.credentials.yaml (REZ_*). A newly saved secret starts the connection immediately; URL / workspace / site changes after a live connection need a dsh web restart.",
147
154
  "config.secretConfigured": "Configured (leave blank to keep)",
148
155
  "config.secretMissing": "Not configured",
149
156
  "config.odoo": "Odoo",
@@ -160,6 +167,13 @@ const en = {
160
167
  "config.ha": "Home Assistant",
161
168
  "config.ha.url": "HA MCP URL",
162
169
  "config.ha.token": "Long-lived access token",
170
+ "config.tapd": "TAPD",
171
+ "config.tapd.workspaceId": "Workspace ID",
172
+ "config.tapd.nickName": "Nickname",
173
+ "config.tapd.token": "Access token",
174
+ "config.gsc": "Google Search Console",
175
+ "config.gsc.siteUrl": "Site URL",
176
+ "config.gsc.key": "Service-account JSON or key file path",
163
177
  "config.fs": "Local files (fs-mcp-server)",
164
178
  "config.fs.root": "Root directory",
165
179
  "config.sqlite": "SQLite (sqlite-mcp-server)",
@@ -536,7 +550,7 @@ function AuditTab({ api }) {
536
550
  //#endregion
537
551
  //#region src/client/panel/ConfigTab.tsx
538
552
  /**
539
- * Config tab: company MCP connections (Odoo / Nextcloud / WeCom / HA),
553
+ * Config tab: company MCP connections (Odoo / Nextcloud / WeCom / HA / TAPD / GSC),
540
554
  * role, and billing. Secrets are write-only and land in credentials.yaml.
541
555
  */
542
556
  const ROLES = [
@@ -565,7 +579,9 @@ const EMPTY_SECRETS = {
565
579
  odoo: "",
566
580
  nextcloud: "",
567
581
  wechat: "",
568
- homeassistant: ""
582
+ homeassistant: "",
583
+ tapd: "",
584
+ gsc: ""
569
585
  };
570
586
  function Field({ label, children }) {
571
587
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -600,7 +616,7 @@ function SecretField({ label, configured, value, onChange }) {
600
616
  })
601
617
  });
602
618
  }
603
- function McpSection({ title, row, secret, onEnabled, onUrl, onUsername, onSecret, urlLabel, secretLabel, usernameLabel }) {
619
+ function McpSection({ title, row, secret, onEnabled, onUrl, onUsername, onSecret, extra, urlLabel, secretLabel, usernameLabel }) {
604
620
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Section, {
605
621
  title,
606
622
  children: [
@@ -635,6 +651,7 @@ function McpSection({ title, row, secret, onEnabled, onUrl, onUsername, onSecret
635
651
  }
636
652
  })
637
653
  }),
654
+ extra,
638
655
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SecretField, {
639
656
  label: secretLabel,
640
657
  configured: row.secretConfigured,
@@ -720,6 +737,14 @@ function ConfigTab({ api }) {
720
737
  homeassistant: {
721
738
  ...config.connections.homeassistant,
722
739
  secret: secrets.homeassistant || void 0
740
+ },
741
+ tapd: {
742
+ ...config.connections.tapd,
743
+ secret: secrets.tapd || void 0
744
+ },
745
+ gsc: {
746
+ ...config.connections.gsc,
747
+ secret: secrets.gsc || void 0
723
748
  }
724
749
  }
725
750
  };
@@ -866,6 +891,65 @@ function ConfigTab({ api }) {
866
891
  urlLabel: tt("config.ha.url"),
867
892
  secretLabel: tt("config.ha.token")
868
893
  }),
894
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(McpSection, {
895
+ title: tt("config.tapd"),
896
+ row: config.connections.tapd,
897
+ secret: secrets.tapd,
898
+ onEnabled: (enabled) => {
899
+ patchConnection("tapd", { enabled });
900
+ },
901
+ 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"),
903
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
904
+ className: panel_module_default.input,
905
+ value: config.connections.tapd.workspaceId ?? "",
906
+ onChange: (event) => {
907
+ patchConnection("tapd", { workspaceId: event.target.value });
908
+ }
909
+ })
910
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
911
+ label: tt("config.tapd.nickName"),
912
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
913
+ className: panel_module_default.input,
914
+ value: config.connections.tapd.nickName ?? "",
915
+ onChange: (event) => {
916
+ patchConnection("tapd", { nickName: event.target.value });
917
+ }
918
+ })
919
+ })] }),
920
+ onSecret: (value) => {
921
+ setSecrets((prev) => ({
922
+ ...prev,
923
+ tapd: value
924
+ }));
925
+ },
926
+ secretLabel: tt("config.tapd.token")
927
+ }),
928
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(McpSection, {
929
+ title: tt("config.gsc"),
930
+ row: config.connections.gsc,
931
+ secret: secrets.gsc,
932
+ onEnabled: (enabled) => {
933
+ patchConnection("gsc", { enabled });
934
+ },
935
+ extra: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
936
+ label: tt("config.gsc.siteUrl"),
937
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
938
+ className: panel_module_default.input,
939
+ value: config.connections.gsc.siteUrl ?? "",
940
+ onChange: (event) => {
941
+ patchConnection("gsc", { siteUrl: event.target.value });
942
+ }
943
+ })
944
+ }),
945
+ onSecret: (value) => {
946
+ setSecrets((prev) => ({
947
+ ...prev,
948
+ gsc: value
949
+ }));
950
+ },
951
+ secretLabel: tt("config.gsc.key")
952
+ }),
869
953
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Section, {
870
954
  title: tt("config.billing"),
871
955
  children: [
package/lib/index.d.ts CHANGED
@@ -1721,6 +1721,15 @@ interface RezConnections {
1721
1721
  enabled: boolean;
1722
1722
  url: string;
1723
1723
  };
1724
+ tapd: {
1725
+ enabled: boolean;
1726
+ workspaceId: string;
1727
+ nickName: string;
1728
+ };
1729
+ gsc: {
1730
+ enabled: boolean;
1731
+ siteUrl: string;
1732
+ };
1724
1733
  }
1725
1734
  /** Full plugin configuration persisted under ~/.dsh/dsh-rez-suite.json. */
1726
1735
  interface RezConfig {
package/lib/index.js CHANGED
@@ -2856,7 +2856,9 @@ const COMPOSED_SERVERS = [
2856
2856
  "odoo",
2857
2857
  "nextcloud",
2858
2858
  "wechat",
2859
- "homeassistant"
2859
+ "homeassistant",
2860
+ "tapd",
2861
+ "gsc"
2860
2862
  ];
2861
2863
  function mcpToolPrefix(server) {
2862
2864
  return "mcp__" + server + "__";
@@ -3034,6 +3036,19 @@ function publicConfig(config) {
3034
3036
  url: connections.homeassistant.url,
3035
3037
  secretConfigured: secretConfigured("homeassistant"),
3036
3038
  secretRef: REZ_CREDENTIAL_REFS.homeassistant
3039
+ },
3040
+ tapd: {
3041
+ enabled: connections.tapd.enabled,
3042
+ workspaceId: connections.tapd.workspaceId,
3043
+ nickName: connections.tapd.nickName,
3044
+ secretConfigured: secretConfigured("tapd"),
3045
+ secretRef: REZ_CREDENTIAL_REFS.tapd
3046
+ },
3047
+ gsc: {
3048
+ enabled: connections.gsc.enabled,
3049
+ siteUrl: connections.gsc.siteUrl,
3050
+ secretConfigured: secretConfigured("gsc"),
3051
+ secretRef: REZ_CREDENTIAL_REFS.gsc
3037
3052
  }
3038
3053
  },
3039
3054
  billing: { ...config.billing }
@@ -8050,7 +8065,16 @@ const Config = Schema.object({
8050
8065
  homeassistant: Schema.object({
8051
8066
  enabled: Schema.boolean().default(true),
8052
8067
  url: Schema.string().default(REZ_DEFAULT_CONNECTIONS.homeassistant.url)
8053
- }).default(REZ_DEFAULT_CONNECTIONS.homeassistant)
8068
+ }).default(REZ_DEFAULT_CONNECTIONS.homeassistant),
8069
+ tapd: Schema.object({
8070
+ enabled: Schema.boolean().default(true),
8071
+ workspaceId: Schema.string().default(REZ_DEFAULT_CONNECTIONS.tapd.workspaceId),
8072
+ nickName: Schema.string().default(REZ_DEFAULT_CONNECTIONS.tapd.nickName)
8073
+ }).default(REZ_DEFAULT_CONNECTIONS.tapd),
8074
+ gsc: Schema.object({
8075
+ enabled: Schema.boolean().default(true),
8076
+ siteUrl: Schema.string().default(REZ_DEFAULT_CONNECTIONS.gsc.siteUrl)
8077
+ }).default(REZ_DEFAULT_CONNECTIONS.gsc)
8054
8078
  }).default(REZ_DEFAULT_CONNECTIONS),
8055
8079
  billing: Schema.object({
8056
8080
  inputCostPer1k: Schema.number().default(.001),
@@ -8064,9 +8088,9 @@ const Config = Schema.object({
8064
8088
  });
8065
8089
  const SECTION_ORDER = 150;
8066
8090
  const REZ_GUIDANCE_CORE = [
8067
- "本机已安装 ReZ-TI 拆分包:工作身份由 dsh-rez-sso 提供,MCP 由官方 dsh-mcp-client 接入 Odoo / Nextcloud / 企业微信 / Home Assistant。",
8068
- "工具名 mcp__odoo__*、mcp__nextcloud__*、mcp__wechat__*、mcp__homeassistant__*。",
8069
- "密钥:REZ_ODOO_TOKEN、REZ_NEXTCLOUD_PASSWORD、REZ_WECHAT_WEBHOOK、REZ_HA_TOKEN。",
8091
+ "本机已安装 ReZ-TI 拆分包:工作身份由 dsh-rez-sso 提供,MCP 由官方 dsh-mcp-client 接入 Odoo / Nextcloud / 企业微信 / Home Assistant / TAPD / GSC。",
8092
+ "工具名 mcp__odoo__*、mcp__nextcloud__*、mcp__wechat__*、mcp__homeassistant__*、mcp__tapd__*、mcp__gsc__*。",
8093
+ "密钥:REZ_ODOO_TOKEN、REZ_NEXTCLOUD_PASSWORD、REZ_WECHAT_WEBHOOK、REZ_HA_TOKEN、REZ_TAPD_TOKEN、REZ_GSC_KEY。",
8070
8094
  "个人微信(QClaw/ClawBot):打开 设置 → 插件 → ReZ-TI → 微信 扫码,然后直接在微信里说话。消息进入网页左侧「微信」文件夹并延续同一会话,模型跟网页默认。网页归档了再从微信说话会自动恢复到侧栏。发「重启对话」会新开一条可见会话并把旧会话归档。网页端必须开着。不必再跑命令、也不要调用微信 MCP 工具。",
8071
8095
  "意图用 rez_set_intent(erp/files/chat/home/auto)。审计用 rez_audit。",
8072
8096
  "涉及资金、对外发送、设备控制、生产写入时先征得用户批准。"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rezti/dsh-rez-suite",
3
3
  "description": "ReZ-TI one-package install for DeepSeek Harness. Update with: dsh plugin --profile web update @rezti/dsh-rez-suite",
4
- "version": "0.1.21",
4
+ "version": "0.1.22",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": "^22.19.0 || >=24.0.0"
@@ -39,13 +39,15 @@
39
39
  "dependencies": {
40
40
  "@modelcontextprotocol/sdk": "^1.30.0",
41
41
  "zod": "^4.4.3",
42
- "@rezti/dsh-rez-ha-bridge": "0.1.7",
43
- "@rezti/dsh-rez-sso": "0.1.7",
44
42
  "@rezti/dsh-rez-nextcloud": "0.1.7",
45
- "@rezti/dsh-rez-intent": "0.1.4",
43
+ "@rezti/dsh-rez-ha-bridge": "0.1.7",
44
+ "@rezti/dsh-rez-tapd": "0.1.0",
46
45
  "@rezti/dsh-rez-token-manager": "0.1.4",
46
+ "@rezti/dsh-rez-gsc": "0.1.0",
47
47
  "@rezti/dsh-rez-odoo": "0.1.7",
48
- "@rezti/dsh-rez-wechat": "0.1.12"
48
+ "@rezti/dsh-rez-intent": "0.1.5",
49
+ "@rezti/dsh-rez-wechat": "0.1.12",
50
+ "@rezti/dsh-rez-sso": "0.1.8"
49
51
  },
50
52
  "peerDependencies": {
51
53
  "react": "^18.2.0",
@@ -6,7 +6,7 @@ export const zh = {
6
6
  'entry.label': 'Rez',
7
7
  'entry.tooltip': 'Rez Suite 配置与审计面板',
8
8
  'settings.title': 'ReZ-TI',
9
- 'settings.description': '公司 MCP(Odoo / Nextcloud / 企微 / HA)与个人微信扫码通道。',
9
+ 'settings.description': '公司 MCP(Odoo / Nextcloud / 企微 / HA / TAPD / GSC)与个人微信扫码通道。',
10
10
  'panel.title': 'Rez Suite',
11
11
  'tab.config': '配置',
12
12
  'tab.weixin': '微信',
@@ -28,7 +28,7 @@ export const zh = {
28
28
  'config.env': '环境变量 (JSON)',
29
29
  'config.headers': 'Headers (JSON)',
30
30
  'config.jsonInvalid': 'JSON 格式错误:{error}',
31
- 'config.mcpHint': '四个公司 MCP 在这里配。密钥写入 ~/.dsh/.credentials.yaml(REZ_*)。新填的密钥会立刻拉起连接;改 URL 后如果已经连上,需要重启 dsh web。',
31
+ 'config.mcpHint': '公司 MCP 在这里配。密钥写入 ~/.dsh/.credentials.yaml(REZ_*)。新填的密钥会立刻拉起连接;改 URL / 项目 / 站点后如果已经连上,需要重启 dsh web。',
32
32
  'config.secretConfigured': '已配置(留空则保持)',
33
33
  'config.secretMissing': '未配置',
34
34
  'config.odoo': 'Odoo',
@@ -45,6 +45,13 @@ export const zh = {
45
45
  'config.ha': 'Home Assistant',
46
46
  'config.ha.url': 'HA MCP URL',
47
47
  'config.ha.token': '长期访问令牌',
48
+ 'config.tapd': 'TAPD',
49
+ 'config.tapd.workspaceId': '项目 ID',
50
+ 'config.tapd.nickName': '昵称',
51
+ 'config.tapd.token': 'Access Token',
52
+ 'config.gsc': 'Google Search Console',
53
+ 'config.gsc.siteUrl': '站点 URL',
54
+ 'config.gsc.key': '服务账号 JSON 或密钥文件路径',
48
55
  'config.fs': '本地文件 (fs-mcp-server)',
49
56
  'config.fs.root': '根目录',
50
57
  'config.sqlite': 'SQLite (sqlite-mcp-server)',
@@ -119,7 +126,7 @@ export const en: Record<RezKey, string> = {
119
126
  'entry.label': 'Rez',
120
127
  'entry.tooltip': 'Rez Suite configuration and audit panel',
121
128
  'settings.title': 'ReZ-TI',
122
- 'settings.description': 'Company MCP (Odoo / Nextcloud / WeCom / HA) and personal WeChat scan-and-chat.',
129
+ 'settings.description': 'Company MCP (Odoo / Nextcloud / WeCom / HA / TAPD / GSC) and personal WeChat scan-and-chat.',
123
130
  'panel.title': 'Rez Suite',
124
131
  'tab.config': 'Config',
125
132
  'tab.weixin': 'WeChat',
@@ -140,7 +147,7 @@ export const en: Record<RezKey, string> = {
140
147
  'config.env': 'Env vars (JSON)',
141
148
  'config.headers': 'Headers (JSON)',
142
149
  'config.jsonInvalid': 'Invalid JSON: {error}',
143
- 'config.mcpHint': 'Company MCP lives here. Secrets go to ~/.dsh/.credentials.yaml (REZ_*). A newly saved secret starts the connection immediately; URL changes after a live connection need a dsh web restart.',
150
+ 'config.mcpHint': 'Company MCP lives here. Secrets go to ~/.dsh/.credentials.yaml (REZ_*). A newly saved secret starts the connection immediately; URL / workspace / site changes after a live connection need a dsh web restart.',
144
151
  'config.secretConfigured': 'Configured (leave blank to keep)',
145
152
  'config.secretMissing': 'Not configured',
146
153
  'config.odoo': 'Odoo',
@@ -157,6 +164,13 @@ export const en: Record<RezKey, string> = {
157
164
  'config.ha': 'Home Assistant',
158
165
  'config.ha.url': 'HA MCP URL',
159
166
  'config.ha.token': 'Long-lived access token',
167
+ 'config.tapd': 'TAPD',
168
+ 'config.tapd.workspaceId': 'Workspace ID',
169
+ 'config.tapd.nickName': 'Nickname',
170
+ 'config.tapd.token': 'Access token',
171
+ 'config.gsc': 'Google Search Console',
172
+ 'config.gsc.siteUrl': 'Site URL',
173
+ 'config.gsc.key': 'Service-account JSON or key file path',
160
174
  'config.fs': 'Local files (fs-mcp-server)',
161
175
  'config.fs.root': 'Root directory',
162
176
  'config.sqlite': 'SQLite (sqlite-mcp-server)',
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Config tab: company MCP connections (Odoo / Nextcloud / WeCom / HA),
2
+ * Config tab: company MCP connections (Odoo / Nextcloud / WeCom / HA / TAPD / GSC),
3
3
  * role, and billing. Secrets are write-only and land in credentials.yaml.
4
4
  */
5
5
 
@@ -22,9 +22,11 @@ type SecretDrafts = {
22
22
  nextcloud: string
23
23
  wechat: string
24
24
  homeassistant: string
25
+ tapd: string
26
+ gsc: string
25
27
  }
26
28
 
27
- const EMPTY_SECRETS: SecretDrafts = { odoo: '', nextcloud: '', wechat: '', homeassistant: '' }
29
+ const EMPTY_SECRETS: SecretDrafts = { odoo: '', nextcloud: '', wechat: '', homeassistant: '', tapd: '', gsc: '' }
28
30
 
29
31
  function Field({ label, children }: { label: string; children: ReactNode }) {
30
32
  return (
@@ -77,6 +79,7 @@ function McpSection({
77
79
  onUrl,
78
80
  onUsername,
79
81
  onSecret,
82
+ extra,
80
83
  urlLabel,
81
84
  secretLabel,
82
85
  usernameLabel,
@@ -88,6 +91,7 @@ function McpSection({
88
91
  onUrl?: (url: string) => void
89
92
  onUsername?: (username: string) => void
90
93
  onSecret: (secret: string) => void
94
+ extra?: ReactNode
91
95
  urlLabel?: string
92
96
  secretLabel: string
93
97
  usernameLabel?: string
@@ -107,6 +111,7 @@ function McpSection({
107
111
  <input className={css.input} value={row.username ?? ''} onChange={event => { onUsername(event.target.value) }} />
108
112
  </Field>
109
113
  )}
114
+ {extra}
110
115
  <SecretField label={secretLabel} configured={row.secretConfigured} value={secret} onChange={onSecret} />
111
116
  <p className={css.message}>{row.secretRef}</p>
112
117
  </Section>
@@ -163,6 +168,8 @@ export function ConfigTab({ api }: { api: RezApi }) {
163
168
  nextcloud: { ...config.connections.nextcloud, secret: secrets.nextcloud || undefined },
164
169
  wechat: { ...config.connections.wechat, secret: secrets.wechat || undefined },
165
170
  homeassistant: { ...config.connections.homeassistant, secret: secrets.homeassistant || undefined },
171
+ tapd: { ...config.connections.tapd, secret: secrets.tapd || undefined },
172
+ gsc: { ...config.connections.gsc, secret: secrets.gsc || undefined },
166
173
  },
167
174
  }
168
175
  const saved = await api.saveConfig(payload)
@@ -252,6 +259,37 @@ export function ConfigTab({ api }: { api: RezApi }) {
252
259
  urlLabel={tt('config.ha.url')}
253
260
  secretLabel={tt('config.ha.token')}
254
261
  />
262
+ <McpSection
263
+ title={tt('config.tapd')}
264
+ row={config.connections.tapd}
265
+ secret={secrets.tapd}
266
+ onEnabled={enabled => { patchConnection('tapd', { enabled }) }}
267
+ extra={(
268
+ <>
269
+ <Field label={tt('config.tapd.workspaceId')}>
270
+ <input className={css.input} value={config.connections.tapd.workspaceId ?? ''} onChange={event => { patchConnection('tapd', { workspaceId: event.target.value }) }} />
271
+ </Field>
272
+ <Field label={tt('config.tapd.nickName')}>
273
+ <input className={css.input} value={config.connections.tapd.nickName ?? ''} onChange={event => { patchConnection('tapd', { nickName: event.target.value }) }} />
274
+ </Field>
275
+ </>
276
+ )}
277
+ onSecret={value => { setSecrets(prev => ({ ...prev, tapd: value })) }}
278
+ secretLabel={tt('config.tapd.token')}
279
+ />
280
+ <McpSection
281
+ title={tt('config.gsc')}
282
+ row={config.connections.gsc}
283
+ secret={secrets.gsc}
284
+ onEnabled={enabled => { patchConnection('gsc', { enabled }) }}
285
+ extra={(
286
+ <Field label={tt('config.gsc.siteUrl')}>
287
+ <input className={css.input} value={config.connections.gsc.siteUrl ?? ''} onChange={event => { patchConnection('gsc', { siteUrl: event.target.value }) }} />
288
+ </Field>
289
+ )}
290
+ onSecret={value => { setSecrets(prev => ({ ...prev, gsc: value })) }}
291
+ secretLabel={tt('config.gsc.key')}
292
+ />
255
293
 
256
294
  <Section title={tt('config.billing')}>
257
295
  <Field label={tt('config.billing.input')}>
package/src/index.ts CHANGED
@@ -70,6 +70,15 @@ export const Config: z<RezConfig> = z.object({
70
70
  enabled: z.boolean().default(true),
71
71
  url: z.string().default(REZ_DEFAULT_CONNECTIONS.homeassistant.url),
72
72
  }).default(REZ_DEFAULT_CONNECTIONS.homeassistant),
73
+ tapd: z.object({
74
+ enabled: z.boolean().default(true),
75
+ workspaceId: z.string().default(REZ_DEFAULT_CONNECTIONS.tapd.workspaceId),
76
+ nickName: z.string().default(REZ_DEFAULT_CONNECTIONS.tapd.nickName),
77
+ }).default(REZ_DEFAULT_CONNECTIONS.tapd),
78
+ gsc: z.object({
79
+ enabled: z.boolean().default(true),
80
+ siteUrl: z.string().default(REZ_DEFAULT_CONNECTIONS.gsc.siteUrl),
81
+ }).default(REZ_DEFAULT_CONNECTIONS.gsc),
73
82
  }).default(REZ_DEFAULT_CONNECTIONS),
74
83
  billing: z.object({
75
84
  inputCostPer1k: z.number().default(0.001),
@@ -81,9 +90,9 @@ export const Config: z<RezConfig> = z.object({
81
90
  const SECTION_ORDER = 150
82
91
 
83
92
  export const REZ_GUIDANCE_CORE = [
84
- '本机已安装 ReZ-TI 拆分包:工作身份由 dsh-rez-sso 提供,MCP 由官方 dsh-mcp-client 接入 Odoo / Nextcloud / 企业微信 / Home Assistant。',
85
- '工具名 mcp__odoo__*、mcp__nextcloud__*、mcp__wechat__*、mcp__homeassistant__*。',
86
- '密钥:REZ_ODOO_TOKEN、REZ_NEXTCLOUD_PASSWORD、REZ_WECHAT_WEBHOOK、REZ_HA_TOKEN。',
93
+ '本机已安装 ReZ-TI 拆分包:工作身份由 dsh-rez-sso 提供,MCP 由官方 dsh-mcp-client 接入 Odoo / Nextcloud / 企业微信 / Home Assistant / TAPD / GSC。',
94
+ '工具名 mcp__odoo__*、mcp__nextcloud__*、mcp__wechat__*、mcp__homeassistant__*、mcp__tapd__*、mcp__gsc__*。',
95
+ '密钥:REZ_ODOO_TOKEN、REZ_NEXTCLOUD_PASSWORD、REZ_WECHAT_WEBHOOK、REZ_HA_TOKEN、REZ_TAPD_TOKEN、REZ_GSC_KEY。',
87
96
  '个人微信(QClaw/ClawBot):打开 设置 → 插件 → ReZ-TI → 微信 扫码,然后直接在微信里说话。消息进入网页左侧「微信」文件夹并延续同一会话,模型跟网页默认。网页归档了再从微信说话会自动恢复到侧栏。发「重启对话」会新开一条可见会话并把旧会话归档。网页端必须开着。不必再跑命令、也不要调用微信 MCP 工具。',
88
97
  '意图用 rez_set_intent(erp/files/chat/home/auto)。审计用 rez_audit。',
89
98
  '涉及资金、对外发送、设备控制、生产写入时先征得用户批准。',
@@ -9,7 +9,7 @@
9
9
  import { lastMcpStartError, REZ_CREDENTIAL_REFS, secretConfigured, type RezSystem } from '@rezti/dsh-rez-sso'
10
10
  import type { RezConfig, RezServerStatus, RezTestResult } from './protocol.ts'
11
11
 
12
- export const COMPOSED_SERVERS = ['odoo', 'nextcloud', 'wechat', 'homeassistant'] as const
12
+ export const COMPOSED_SERVERS = ['odoo', 'nextcloud', 'wechat', 'homeassistant', 'tapd', 'gsc'] as const
13
13
 
14
14
  export type ComposedServer = (typeof COMPOSED_SERVERS)[number]
15
15
 
package/src/presets.ts CHANGED
@@ -28,6 +28,10 @@ const RULES: Record<Exclude<RezRoleId, 'all' | 'boss'>, RoleRule[]> = {
28
28
  { server: 'tapd', pattern: '*query*' },
29
29
  { server: 'tapd', pattern: '*get*' },
30
30
  { server: 'tapd', pattern: '*list*' },
31
+ { server: 'gsc', pattern: '*query*' },
32
+ { server: 'gsc', pattern: '*get*' },
33
+ { server: 'gsc', pattern: '*list*' },
34
+ { server: 'gsc', pattern: '*search*' },
31
35
  // Dify read/query.
32
36
  { server: 'dify', pattern: '*query*' },
33
37
  { server: 'dify', pattern: '*get*' },
@@ -76,6 +80,10 @@ const RULES: Record<Exclude<RezRoleId, 'all' | 'boss'>, RoleRule[]> = {
76
80
  { server: 'tapd', pattern: '*create*' },
77
81
  { server: 'tapd', pattern: '*update*' },
78
82
  { server: 'tapd', pattern: '*delete*' },
83
+ { server: 'gsc', pattern: '*query*' },
84
+ { server: 'gsc', pattern: '*get*' },
85
+ { server: 'gsc', pattern: '*list*' },
86
+ { server: 'gsc', pattern: '*search*' },
79
87
  // Dify workflow execution.
80
88
  { server: 'dify', pattern: '*run*' },
81
89
  { server: 'dify', pattern: '*workflow*' },
package/src/protocol.ts CHANGED
@@ -46,12 +46,17 @@ export interface RezConnections {
46
46
  nextcloud: { enabled: boolean; url: string; username: string }
47
47
  wechat: { enabled: boolean }
48
48
  homeassistant: { enabled: boolean; url: string }
49
+ tapd: { enabled: boolean; workspaceId: string; nickName: string }
50
+ gsc: { enabled: boolean; siteUrl: string }
49
51
  }
50
52
 
51
53
  export interface RezPublicConnection {
52
54
  enabled: boolean
53
55
  url?: string
54
56
  username?: string
57
+ workspaceId?: string
58
+ nickName?: string
59
+ siteUrl?: string
55
60
  secretConfigured: boolean
56
61
  secretRef: string
57
62
  }
@@ -83,6 +88,8 @@ export interface RezPublicConfig {
83
88
  nextcloud: RezPublicConnection
84
89
  wechat: RezPublicConnection
85
90
  homeassistant: RezPublicConnection
91
+ tapd: RezPublicConnection
92
+ gsc: RezPublicConnection
86
93
  }
87
94
  billing: { inputCostPer1k: number; outputCostPer1k: number; monthlyBudget: number }
88
95
  }
package/src/store.ts CHANGED
@@ -112,6 +112,19 @@ export function publicConfig(config: RezConfig): RezPublicConfig {
112
112
  secretConfigured: secretConfigured('homeassistant'),
113
113
  secretRef: REZ_CREDENTIAL_REFS.homeassistant,
114
114
  },
115
+ tapd: {
116
+ enabled: connections.tapd.enabled,
117
+ workspaceId: connections.tapd.workspaceId,
118
+ nickName: connections.tapd.nickName,
119
+ secretConfigured: secretConfigured('tapd'),
120
+ secretRef: REZ_CREDENTIAL_REFS.tapd,
121
+ },
122
+ gsc: {
123
+ enabled: connections.gsc.enabled,
124
+ siteUrl: connections.gsc.siteUrl,
125
+ secretConfigured: secretConfigured('gsc'),
126
+ secretRef: REZ_CREDENTIAL_REFS.gsc,
127
+ },
115
128
  },
116
129
  billing: { ...config.billing },
117
130
  }