@rezti/dsh-rez-suite 0.1.5 → 0.1.6
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 +1 -1
- package/README.zh.md +1 -1
- package/lib/client.d.ts +10 -3
- package/lib/client.js +209 -161
- package/lib/index.d.ts +20 -0
- package/lib/index.js +91 -12
- package/package.json +7 -7
- package/src/client/locales.ts +21 -7
- package/src/client/panel/ConfigTab.tsx +141 -86
- package/src/index.ts +33 -7
- package/src/protocol.ts +23 -0
- package/src/routes.ts +32 -4
- package/src/store.ts +37 -1
package/README.md
CHANGED
|
@@ -8,4 +8,4 @@ dsh plugin --profile web add @rezti/dsh-rez-suite
|
|
|
8
8
|
|
|
9
9
|
组成见仓库根 README。子包不要单独 `dsh plugin add`。
|
|
10
10
|
|
|
11
|
-
配置在 **设置 → 插件 → 插件配置** 展开 **ReZ-TI**(同页还有独立的 ReZ-TI
|
|
11
|
+
配置在 **设置 → 插件 → 插件配置** 展开 **ReZ-TI**(同页还有独立的 ReZ-TI 标签)。Odoo / Nextcloud / WeCom / HA 的地址和密钥都在「配置」页。个人微信在卡片的「微信」页扫码,然后直接在微信里说话。
|
package/README.zh.md
CHANGED
|
@@ -8,6 +8,6 @@ dsh plugin --profile web add @rezti/dsh-rez-suite
|
|
|
8
8
|
|
|
9
9
|
密钥用环境变量或 dsh-credentials:`REZ_ODOO_TOKEN`、`REZ_NEXTCLOUD_PASSWORD`、`REZ_WECHAT_WEBHOOK`、`REZ_HA_TOKEN`。未配置时不拉起对应 MCP。
|
|
10
10
|
|
|
11
|
-
配置在 **设置 → 插件 → 插件配置** 展开 **ReZ-TI**(同页还有独立的 ReZ-TI
|
|
11
|
+
配置在 **设置 → 插件 → 插件配置** 展开 **ReZ-TI**(同页还有独立的 ReZ-TI 标签)。Odoo / Nextcloud / 企微 / HA 的地址和密钥都在「配置」页。个人微信在卡片的「微信」页扫码,然后直接在微信里说话。
|
|
12
12
|
|
|
13
13
|
子包不要再单独 `dsh plugin add`,否则会重复注册 MCP。
|
package/lib/client.d.ts
CHANGED
|
@@ -7275,16 +7275,23 @@ declare const zh: {
|
|
|
7275
7275
|
readonly 'config.env': "环境变量 (JSON)";
|
|
7276
7276
|
readonly 'config.headers': "Headers (JSON)";
|
|
7277
7277
|
readonly 'config.jsonInvalid': "JSON 格式错误:{error}";
|
|
7278
|
+
readonly 'config.mcpHint': "四个公司 MCP 在这里配。密钥写入 ~/.dsh/.credentials.yaml(REZ_*)。新填的密钥会立刻拉起连接;改 URL 后如果已经连上,需要重启 dsh web。";
|
|
7279
|
+
readonly 'config.secretConfigured': "已配置(留空则保持)";
|
|
7280
|
+
readonly 'config.secretMissing': "未配置";
|
|
7278
7281
|
readonly 'config.odoo': "Odoo";
|
|
7279
|
-
readonly 'config.odoo.url': "Odoo URL";
|
|
7280
|
-
readonly 'config.odoo.apiKey': "API
|
|
7282
|
+
readonly 'config.odoo.url': "Odoo MCP URL";
|
|
7283
|
+
readonly 'config.odoo.apiKey': "API Token";
|
|
7281
7284
|
readonly 'config.nextcloud': "Nextcloud";
|
|
7282
|
-
readonly 'config.nextcloud.url': "Nextcloud
|
|
7285
|
+
readonly 'config.nextcloud.url': "Nextcloud 主机";
|
|
7283
7286
|
readonly 'config.nextcloud.username': "用户名";
|
|
7284
7287
|
readonly 'config.nextcloud.appPassword': "App Password";
|
|
7285
7288
|
readonly 'config.wecom': "企业微信";
|
|
7286
7289
|
readonly 'config.wecom.botId': "Bot ID";
|
|
7287
7290
|
readonly 'config.wecom.secret': "Secret";
|
|
7291
|
+
readonly 'config.wecom.webhook': "群机器人 Webhook";
|
|
7292
|
+
readonly 'config.ha': "Home Assistant";
|
|
7293
|
+
readonly 'config.ha.url': "HA MCP URL";
|
|
7294
|
+
readonly 'config.ha.token': "长期访问令牌";
|
|
7288
7295
|
readonly 'config.fs': "本地文件 (fs-mcp-server)";
|
|
7289
7296
|
readonly 'config.fs.root': "根目录";
|
|
7290
7297
|
readonly 'config.sqlite': "SQLite (sqlite-mcp-server)";
|
package/lib/client.js
CHANGED
|
@@ -36,16 +36,23 @@ const zh = {
|
|
|
36
36
|
"config.env": "环境变量 (JSON)",
|
|
37
37
|
"config.headers": "Headers (JSON)",
|
|
38
38
|
"config.jsonInvalid": "JSON 格式错误:{error}",
|
|
39
|
+
"config.mcpHint": "四个公司 MCP 在这里配。密钥写入 ~/.dsh/.credentials.yaml(REZ_*)。新填的密钥会立刻拉起连接;改 URL 后如果已经连上,需要重启 dsh web。",
|
|
40
|
+
"config.secretConfigured": "已配置(留空则保持)",
|
|
41
|
+
"config.secretMissing": "未配置",
|
|
39
42
|
"config.odoo": "Odoo",
|
|
40
|
-
"config.odoo.url": "Odoo URL",
|
|
41
|
-
"config.odoo.apiKey": "API
|
|
43
|
+
"config.odoo.url": "Odoo MCP URL",
|
|
44
|
+
"config.odoo.apiKey": "API Token",
|
|
42
45
|
"config.nextcloud": "Nextcloud",
|
|
43
|
-
"config.nextcloud.url": "Nextcloud
|
|
46
|
+
"config.nextcloud.url": "Nextcloud 主机",
|
|
44
47
|
"config.nextcloud.username": "用户名",
|
|
45
48
|
"config.nextcloud.appPassword": "App Password",
|
|
46
49
|
"config.wecom": "企业微信",
|
|
47
50
|
"config.wecom.botId": "Bot ID",
|
|
48
51
|
"config.wecom.secret": "Secret",
|
|
52
|
+
"config.wecom.webhook": "群机器人 Webhook",
|
|
53
|
+
"config.ha": "Home Assistant",
|
|
54
|
+
"config.ha.url": "HA MCP URL",
|
|
55
|
+
"config.ha.token": "长期访问令牌",
|
|
49
56
|
"config.fs": "本地文件 (fs-mcp-server)",
|
|
50
57
|
"config.fs.root": "根目录",
|
|
51
58
|
"config.sqlite": "SQLite (sqlite-mcp-server)",
|
|
@@ -125,16 +132,23 @@ const en = {
|
|
|
125
132
|
"config.env": "Env vars (JSON)",
|
|
126
133
|
"config.headers": "Headers (JSON)",
|
|
127
134
|
"config.jsonInvalid": "Invalid JSON: {error}",
|
|
135
|
+
"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.",
|
|
136
|
+
"config.secretConfigured": "Configured (leave blank to keep)",
|
|
137
|
+
"config.secretMissing": "Not configured",
|
|
128
138
|
"config.odoo": "Odoo",
|
|
129
|
-
"config.odoo.url": "Odoo URL",
|
|
130
|
-
"config.odoo.apiKey": "API
|
|
139
|
+
"config.odoo.url": "Odoo MCP URL",
|
|
140
|
+
"config.odoo.apiKey": "API token",
|
|
131
141
|
"config.nextcloud": "Nextcloud",
|
|
132
|
-
"config.nextcloud.url": "Nextcloud
|
|
142
|
+
"config.nextcloud.url": "Nextcloud host",
|
|
133
143
|
"config.nextcloud.username": "Username",
|
|
134
|
-
"config.nextcloud.appPassword": "App
|
|
144
|
+
"config.nextcloud.appPassword": "App password",
|
|
135
145
|
"config.wecom": "WeCom",
|
|
136
146
|
"config.wecom.botId": "Bot ID",
|
|
137
147
|
"config.wecom.secret": "Secret",
|
|
148
|
+
"config.wecom.webhook": "Group bot webhook",
|
|
149
|
+
"config.ha": "Home Assistant",
|
|
150
|
+
"config.ha.url": "HA MCP URL",
|
|
151
|
+
"config.ha.token": "Long-lived access token",
|
|
138
152
|
"config.fs": "Local files (fs-mcp-server)",
|
|
139
153
|
"config.fs.root": "Root directory",
|
|
140
154
|
"config.sqlite": "SQLite (sqlite-mcp-server)",
|
|
@@ -489,8 +503,8 @@ function AuditTab({ api }) {
|
|
|
489
503
|
//#endregion
|
|
490
504
|
//#region src/client/panel/ConfigTab.tsx
|
|
491
505
|
/**
|
|
492
|
-
* Config tab:
|
|
493
|
-
*
|
|
506
|
+
* Config tab: company MCP connections (Odoo / Nextcloud / WeCom / HA),
|
|
507
|
+
* role, and billing. Secrets are write-only and land in credentials.yaml.
|
|
494
508
|
*/
|
|
495
509
|
const ROLES = [
|
|
496
510
|
{
|
|
@@ -510,6 +524,12 @@ const ROLES = [
|
|
|
510
524
|
label: "role.operations"
|
|
511
525
|
}
|
|
512
526
|
];
|
|
527
|
+
const EMPTY_SECRETS = {
|
|
528
|
+
odoo: "",
|
|
529
|
+
nextcloud: "",
|
|
530
|
+
wechat: "",
|
|
531
|
+
homeassistant: ""
|
|
532
|
+
};
|
|
513
533
|
function Field({ label, children }) {
|
|
514
534
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
515
535
|
className: panel_module_default.field,
|
|
@@ -528,42 +548,81 @@ function Section({ title, children }) {
|
|
|
528
548
|
}), children]
|
|
529
549
|
});
|
|
530
550
|
}
|
|
531
|
-
function
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
551
|
+
function SecretField({ label, configured, value, onChange }) {
|
|
552
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
553
|
+
label,
|
|
554
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
555
|
+
className: panel_module_default.input,
|
|
556
|
+
type: "password",
|
|
557
|
+
autoComplete: "off",
|
|
558
|
+
value,
|
|
559
|
+
placeholder: configured ? tt("config.secretConfigured") : tt("config.secretMissing"),
|
|
560
|
+
onChange: (event) => {
|
|
561
|
+
onChange(event.target.value);
|
|
562
|
+
}
|
|
563
|
+
})
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
function McpSection({ title, row, secret, onEnabled, onUrl, onUsername, onSecret, urlLabel, secretLabel, usernameLabel }) {
|
|
567
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Section, {
|
|
568
|
+
title,
|
|
569
|
+
children: [
|
|
570
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
571
|
+
label: tt("config.enabled"),
|
|
572
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
573
|
+
className: panel_module_default.checkbox,
|
|
574
|
+
type: "checkbox",
|
|
575
|
+
checked: row.enabled,
|
|
576
|
+
onChange: (event) => {
|
|
577
|
+
onEnabled(event.target.checked);
|
|
578
|
+
}
|
|
579
|
+
})
|
|
580
|
+
}),
|
|
581
|
+
onUrl !== void 0 && urlLabel !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
582
|
+
label: urlLabel,
|
|
583
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
584
|
+
className: panel_module_default.input,
|
|
585
|
+
value: row.url ?? "",
|
|
586
|
+
onChange: (event) => {
|
|
587
|
+
onUrl(event.target.value);
|
|
588
|
+
}
|
|
589
|
+
})
|
|
590
|
+
}),
|
|
591
|
+
onUsername !== void 0 && usernameLabel !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
592
|
+
label: usernameLabel,
|
|
593
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
594
|
+
className: panel_module_default.input,
|
|
595
|
+
value: row.username ?? "",
|
|
596
|
+
onChange: (event) => {
|
|
597
|
+
onUsername(event.target.value);
|
|
598
|
+
}
|
|
599
|
+
})
|
|
600
|
+
}),
|
|
601
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SecretField, {
|
|
602
|
+
label: secretLabel,
|
|
603
|
+
configured: row.secretConfigured,
|
|
604
|
+
value: secret,
|
|
605
|
+
onChange: onSecret
|
|
606
|
+
}),
|
|
607
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
608
|
+
className: panel_module_default.message,
|
|
609
|
+
children: row.secretRef
|
|
610
|
+
})
|
|
611
|
+
]
|
|
612
|
+
});
|
|
537
613
|
}
|
|
538
614
|
function ConfigTab({ api }) {
|
|
539
615
|
const [config, setConfig] = (0, react.useState)(null);
|
|
616
|
+
const [secrets, setSecrets] = (0, react.useState)(EMPTY_SECRETS);
|
|
540
617
|
const [loading, setLoading] = (0, react.useState)(true);
|
|
541
618
|
const [saving, setSaving] = (0, react.useState)(false);
|
|
542
619
|
const [testing, setTesting] = (0, react.useState)(false);
|
|
543
620
|
const [message, setMessage] = (0, react.useState)("");
|
|
544
621
|
const [error, setError] = (0, react.useState)("");
|
|
545
622
|
const [results, setResults] = (0, react.useState)([]);
|
|
546
|
-
const [argsText, setArgsText] = (0, react.useState)({});
|
|
547
|
-
const [envText, setEnvText] = (0, react.useState)({});
|
|
548
|
-
const [headerText, setHeaderText] = (0, react.useState)({});
|
|
549
|
-
const initTexts = (next) => {
|
|
550
|
-
const args = {};
|
|
551
|
-
const envs = {};
|
|
552
|
-
const headers = {};
|
|
553
|
-
for (const [id, server] of Object.entries(next.servers)) {
|
|
554
|
-
args[id] = (server.args ?? []).join("\n");
|
|
555
|
-
envs[id] = JSON.stringify(server.env ?? {}, null, 2);
|
|
556
|
-
headers[id] = JSON.stringify(server.headers ?? {}, null, 2);
|
|
557
|
-
}
|
|
558
|
-
setArgsText(args);
|
|
559
|
-
setEnvText(envs);
|
|
560
|
-
setHeaderText(headers);
|
|
561
|
-
};
|
|
562
623
|
const load = async () => {
|
|
563
624
|
try {
|
|
564
|
-
|
|
565
|
-
setConfig(next);
|
|
566
|
-
initTexts(next);
|
|
625
|
+
setConfig(await api.getConfig());
|
|
567
626
|
} catch (err) {
|
|
568
627
|
setError(errorMessage(err));
|
|
569
628
|
} finally {
|
|
@@ -587,13 +646,13 @@ function ConfigTab({ api }) {
|
|
|
587
646
|
[key]: value
|
|
588
647
|
});
|
|
589
648
|
};
|
|
590
|
-
const
|
|
649
|
+
const patchConnection = (id, patch) => {
|
|
591
650
|
setConfig((prev) => prev === null ? prev : {
|
|
592
651
|
...prev,
|
|
593
|
-
|
|
594
|
-
...prev.
|
|
652
|
+
connections: {
|
|
653
|
+
...prev.connections,
|
|
595
654
|
[id]: {
|
|
596
|
-
...prev.
|
|
655
|
+
...prev.connections[id],
|
|
597
656
|
...patch
|
|
598
657
|
}
|
|
599
658
|
}
|
|
@@ -604,9 +663,32 @@ function ConfigTab({ api }) {
|
|
|
604
663
|
setMessage("");
|
|
605
664
|
setError("");
|
|
606
665
|
try {
|
|
607
|
-
const
|
|
666
|
+
const payload = {
|
|
667
|
+
enabled: config.enabled,
|
|
668
|
+
role: config.role,
|
|
669
|
+
billing: config.billing,
|
|
670
|
+
connections: {
|
|
671
|
+
odoo: {
|
|
672
|
+
...config.connections.odoo,
|
|
673
|
+
secret: secrets.odoo || void 0
|
|
674
|
+
},
|
|
675
|
+
nextcloud: {
|
|
676
|
+
...config.connections.nextcloud,
|
|
677
|
+
secret: secrets.nextcloud || void 0
|
|
678
|
+
},
|
|
679
|
+
wechat: {
|
|
680
|
+
...config.connections.wechat,
|
|
681
|
+
secret: secrets.wechat || void 0
|
|
682
|
+
},
|
|
683
|
+
homeassistant: {
|
|
684
|
+
...config.connections.homeassistant,
|
|
685
|
+
secret: secrets.homeassistant || void 0
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
const saved = await api.saveConfig(payload);
|
|
608
690
|
setConfig(saved);
|
|
609
|
-
|
|
691
|
+
setSecrets(EMPTY_SECRETS);
|
|
610
692
|
setMessage(tt("config.saved"));
|
|
611
693
|
} catch (err) {
|
|
612
694
|
setError(errorMessage(err));
|
|
@@ -628,28 +710,22 @@ function ConfigTab({ api }) {
|
|
|
628
710
|
}
|
|
629
711
|
};
|
|
630
712
|
const renderResult = (result) => {
|
|
631
|
-
if (result.ok)
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
const commitArgs = (id) => {
|
|
638
|
-
updateServer(id, { args: argsText[id] === "" ? [] : argsText[id].split("\n").map((line) => line.trim()).filter(Boolean) });
|
|
639
|
-
};
|
|
640
|
-
const commitRecord = (id, kind) => {
|
|
641
|
-
const text = kind === "env" ? envText[id] : headerText[id];
|
|
642
|
-
try {
|
|
643
|
-
const record = parseRecord(text ?? "{}");
|
|
644
|
-
updateServer(id, kind === "env" ? { env: record } : { headers: record });
|
|
645
|
-
setError("");
|
|
646
|
-
} catch (err) {
|
|
647
|
-
setError(tt("config.jsonInvalid", { error: errorMessage(err) }));
|
|
713
|
+
if (result.ok) {
|
|
714
|
+
if (result.serverInfo !== void 0) return result.serverInfo;
|
|
715
|
+
return tt("config.testOk", {
|
|
716
|
+
tools: result.toolCount ?? 0,
|
|
717
|
+
latency: result.latencyMs ?? 0
|
|
718
|
+
});
|
|
648
719
|
}
|
|
720
|
+
return tt("config.testFail", { error: result.error ?? "" });
|
|
649
721
|
};
|
|
650
722
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
651
723
|
className: panel_module_default.tabBody,
|
|
652
724
|
children: [
|
|
725
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
726
|
+
className: panel_module_default.message,
|
|
727
|
+
children: tt("config.mcpHint")
|
|
728
|
+
}),
|
|
653
729
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Section, {
|
|
654
730
|
title: tt("config.role"),
|
|
655
731
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
@@ -677,110 +753,82 @@ function ConfigTab({ api }) {
|
|
|
677
753
|
})
|
|
678
754
|
})]
|
|
679
755
|
}),
|
|
680
|
-
|
|
681
|
-
title:
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
})
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
757
|
-
label: tt("config.url"),
|
|
758
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
759
|
-
className: panel_module_default.input,
|
|
760
|
-
value: server.url ?? "",
|
|
761
|
-
onChange: (event) => {
|
|
762
|
-
updateServer(id, { url: event.target.value });
|
|
763
|
-
}
|
|
764
|
-
})
|
|
765
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
766
|
-
label: tt("config.headers"),
|
|
767
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
768
|
-
className: panel_module_default.input,
|
|
769
|
-
rows: 4,
|
|
770
|
-
value: headerText[id] ?? "{}",
|
|
771
|
-
onChange: (event) => {
|
|
772
|
-
setHeaderText((prev) => ({
|
|
773
|
-
...prev,
|
|
774
|
-
[id]: event.target.value
|
|
775
|
-
}));
|
|
776
|
-
},
|
|
777
|
-
onBlur: () => {
|
|
778
|
-
commitRecord(id, "headers");
|
|
779
|
-
}
|
|
780
|
-
})
|
|
781
|
-
})] })
|
|
782
|
-
]
|
|
783
|
-
}, id)),
|
|
756
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(McpSection, {
|
|
757
|
+
title: tt("config.odoo"),
|
|
758
|
+
row: config.connections.odoo,
|
|
759
|
+
secret: secrets.odoo,
|
|
760
|
+
onEnabled: (enabled) => {
|
|
761
|
+
patchConnection("odoo", { enabled });
|
|
762
|
+
},
|
|
763
|
+
onUrl: (url) => {
|
|
764
|
+
patchConnection("odoo", { url });
|
|
765
|
+
},
|
|
766
|
+
onSecret: (value) => {
|
|
767
|
+
setSecrets((prev) => ({
|
|
768
|
+
...prev,
|
|
769
|
+
odoo: value
|
|
770
|
+
}));
|
|
771
|
+
},
|
|
772
|
+
urlLabel: tt("config.odoo.url"),
|
|
773
|
+
secretLabel: tt("config.odoo.apiKey")
|
|
774
|
+
}),
|
|
775
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(McpSection, {
|
|
776
|
+
title: tt("config.nextcloud"),
|
|
777
|
+
row: config.connections.nextcloud,
|
|
778
|
+
secret: secrets.nextcloud,
|
|
779
|
+
onEnabled: (enabled) => {
|
|
780
|
+
patchConnection("nextcloud", { enabled });
|
|
781
|
+
},
|
|
782
|
+
onUrl: (url) => {
|
|
783
|
+
patchConnection("nextcloud", { url });
|
|
784
|
+
},
|
|
785
|
+
onUsername: (username) => {
|
|
786
|
+
patchConnection("nextcloud", { username });
|
|
787
|
+
},
|
|
788
|
+
onSecret: (value) => {
|
|
789
|
+
setSecrets((prev) => ({
|
|
790
|
+
...prev,
|
|
791
|
+
nextcloud: value
|
|
792
|
+
}));
|
|
793
|
+
},
|
|
794
|
+
urlLabel: tt("config.nextcloud.url"),
|
|
795
|
+
usernameLabel: tt("config.nextcloud.username"),
|
|
796
|
+
secretLabel: tt("config.nextcloud.appPassword")
|
|
797
|
+
}),
|
|
798
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(McpSection, {
|
|
799
|
+
title: tt("config.wecom"),
|
|
800
|
+
row: config.connections.wechat,
|
|
801
|
+
secret: secrets.wechat,
|
|
802
|
+
onEnabled: (enabled) => {
|
|
803
|
+
patchConnection("wechat", { enabled });
|
|
804
|
+
},
|
|
805
|
+
onSecret: (value) => {
|
|
806
|
+
setSecrets((prev) => ({
|
|
807
|
+
...prev,
|
|
808
|
+
wechat: value
|
|
809
|
+
}));
|
|
810
|
+
},
|
|
811
|
+
secretLabel: tt("config.wecom.webhook")
|
|
812
|
+
}),
|
|
813
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(McpSection, {
|
|
814
|
+
title: tt("config.ha"),
|
|
815
|
+
row: config.connections.homeassistant,
|
|
816
|
+
secret: secrets.homeassistant,
|
|
817
|
+
onEnabled: (enabled) => {
|
|
818
|
+
patchConnection("homeassistant", { enabled });
|
|
819
|
+
},
|
|
820
|
+
onUrl: (url) => {
|
|
821
|
+
patchConnection("homeassistant", { url });
|
|
822
|
+
},
|
|
823
|
+
onSecret: (value) => {
|
|
824
|
+
setSecrets((prev) => ({
|
|
825
|
+
...prev,
|
|
826
|
+
homeassistant: value
|
|
827
|
+
}));
|
|
828
|
+
},
|
|
829
|
+
urlLabel: tt("config.ha.url"),
|
|
830
|
+
secretLabel: tt("config.ha.token")
|
|
831
|
+
}),
|
|
784
832
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Section, {
|
|
785
833
|
title: tt("config.billing"),
|
|
786
834
|
children: [
|
package/lib/index.d.ts
CHANGED
|
@@ -1702,12 +1702,32 @@ interface RezMcpServerSpec {
|
|
|
1702
1702
|
/** Per-tool-call timeout in milliseconds. */
|
|
1703
1703
|
toolCallTimeoutMs?: number;
|
|
1704
1704
|
}
|
|
1705
|
+
/** Company MCP endpoints persisted under ~/.dsh/dsh-rez-suite.json. Secrets are not stored here. */
|
|
1706
|
+
interface RezConnections {
|
|
1707
|
+
odoo: {
|
|
1708
|
+
enabled: boolean;
|
|
1709
|
+
url: string;
|
|
1710
|
+
};
|
|
1711
|
+
nextcloud: {
|
|
1712
|
+
enabled: boolean;
|
|
1713
|
+
url: string;
|
|
1714
|
+
username: string;
|
|
1715
|
+
};
|
|
1716
|
+
wechat: {
|
|
1717
|
+
enabled: boolean;
|
|
1718
|
+
};
|
|
1719
|
+
homeassistant: {
|
|
1720
|
+
enabled: boolean;
|
|
1721
|
+
url: string;
|
|
1722
|
+
};
|
|
1723
|
+
}
|
|
1705
1724
|
/** Full plugin configuration persisted under ~/.dsh/dsh-rez-suite.json. */
|
|
1706
1725
|
interface RezConfig {
|
|
1707
1726
|
enabled: boolean;
|
|
1708
1727
|
announceToAgent: boolean;
|
|
1709
1728
|
role: RezRoleId;
|
|
1710
1729
|
servers: Record<string, RezMcpServerSpec>;
|
|
1730
|
+
connections: RezConnections;
|
|
1711
1731
|
billing: {
|
|
1712
1732
|
inputCostPer1k: number;
|
|
1713
1733
|
outputCostPer1k: number;
|