@rezti/dsh-rez-suite 0.1.4 → 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 +29 -155
- package/lib/client.js +365 -468
- package/lib/index.d.ts +20 -0
- package/lib/index.js +92 -13
- package/lib/style.css +82 -111
- package/package.json +9 -7
- package/src/client/index.ts +33 -21
- package/src/client/locales.ts +25 -7
- package/src/client/panel/AuditTab.tsx +6 -6
- package/src/client/panel/ConfigTab.tsx +141 -86
- package/src/client/panel/panel.module.css +89 -118
- package/src/client/settings-card.tsx +68 -0
- package/src/index.ts +37 -11
- package/src/protocol.ts +23 -0
- package/src/routes.ts +32 -4
- package/src/store.ts +37 -1
- package/src/client/mount.tsx +0 -97
- package/src/client/panel/RezPanel.tsx +0 -53
- package/src/client/panel/controller.ts +0 -42
- package/src/client/sidebar-entry.ts +0 -80
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;
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
|
+
import { REZ_CREDENTIAL_REFS, REZ_DEFAULT_CONNECTIONS, REZ_SYSTEMS, mergeConnections, secretConfigured, writeManagedCredential } from "@rezti/dsh-rez-sso";
|
|
4
5
|
import { mkdirSync, renameSync, writeFileSync } from "node:fs";
|
|
5
6
|
import { DatabaseSync } from "node:sqlite";
|
|
6
7
|
//#region ../../node_modules/.pnpm/@deepseek-ai+cosmokit@1.8.2/node_modules/@deepseek-ai/cosmokit/lib/index.js
|
|
@@ -2865,13 +2866,14 @@ const FORMAT_VERSION = 1;
|
|
|
2865
2866
|
function rezStorePath() {
|
|
2866
2867
|
return join(homedir(), ".dsh", "dsh-rez-suite.json");
|
|
2867
2868
|
}
|
|
2868
|
-
/** Defaults:
|
|
2869
|
+
/** Defaults: company MCP endpoints. Secrets live in credentials.yaml / env. */
|
|
2869
2870
|
function defaultConfig() {
|
|
2870
2871
|
return {
|
|
2871
2872
|
enabled: true,
|
|
2872
2873
|
announceToAgent: true,
|
|
2873
2874
|
role: "all",
|
|
2874
2875
|
servers: {},
|
|
2876
|
+
connections: JSON.parse(JSON.stringify(REZ_DEFAULT_CONNECTIONS)),
|
|
2875
2877
|
billing: {
|
|
2876
2878
|
inputCostPer1k: .001,
|
|
2877
2879
|
outputCostPer1k: .002,
|
|
@@ -2896,10 +2898,37 @@ function maskServer(server) {
|
|
|
2896
2898
|
function publicConfig(config) {
|
|
2897
2899
|
const servers = {};
|
|
2898
2900
|
for (const [id, server] of Object.entries(config.servers)) servers[id] = maskServer(server);
|
|
2901
|
+
const connections = mergeConnections(config.connections);
|
|
2899
2902
|
return {
|
|
2900
2903
|
enabled: config.enabled,
|
|
2901
2904
|
role: config.role,
|
|
2902
2905
|
servers,
|
|
2906
|
+
connections: {
|
|
2907
|
+
odoo: {
|
|
2908
|
+
enabled: connections.odoo.enabled,
|
|
2909
|
+
url: connections.odoo.url,
|
|
2910
|
+
secretConfigured: secretConfigured("odoo"),
|
|
2911
|
+
secretRef: REZ_CREDENTIAL_REFS.odoo
|
|
2912
|
+
},
|
|
2913
|
+
nextcloud: {
|
|
2914
|
+
enabled: connections.nextcloud.enabled,
|
|
2915
|
+
url: connections.nextcloud.url,
|
|
2916
|
+
username: connections.nextcloud.username,
|
|
2917
|
+
secretConfigured: secretConfigured("nextcloud"),
|
|
2918
|
+
secretRef: REZ_CREDENTIAL_REFS.nextcloud
|
|
2919
|
+
},
|
|
2920
|
+
wechat: {
|
|
2921
|
+
enabled: connections.wechat.enabled,
|
|
2922
|
+
secretConfigured: secretConfigured("wechat"),
|
|
2923
|
+
secretRef: REZ_CREDENTIAL_REFS.wechat
|
|
2924
|
+
},
|
|
2925
|
+
homeassistant: {
|
|
2926
|
+
enabled: connections.homeassistant.enabled,
|
|
2927
|
+
url: connections.homeassistant.url,
|
|
2928
|
+
secretConfigured: secretConfigured("homeassistant"),
|
|
2929
|
+
secretRef: REZ_CREDENTIAL_REFS.homeassistant
|
|
2930
|
+
}
|
|
2931
|
+
},
|
|
2903
2932
|
billing: { ...config.billing }
|
|
2904
2933
|
};
|
|
2905
2934
|
}
|
|
@@ -2911,6 +2940,7 @@ function mergeConfig(base, override) {
|
|
|
2911
2940
|
if (typeof value.enabled === "boolean") result.enabled = value.enabled;
|
|
2912
2941
|
if (typeof value.announceToAgent === "boolean") result.announceToAgent = value.announceToAgent;
|
|
2913
2942
|
if (value.role === "engineer" || value.role === "sales" || value.role === "operations" || value.role === "all") result.role = value.role;
|
|
2943
|
+
result.connections = mergeConnections(value.connections ?? result.connections);
|
|
2914
2944
|
if (typeof value.servers === "object" && value.servers !== null) for (const [id, raw] of Object.entries(value.servers)) {
|
|
2915
2945
|
if (typeof raw !== "object" || raw === null) continue;
|
|
2916
2946
|
const incoming = raw;
|
|
@@ -3019,8 +3049,25 @@ function mergeMaskedRecord(base, incoming) {
|
|
|
3019
3049
|
/** Apply a browser-safe public patch without overwriting masked secrets. */
|
|
3020
3050
|
function applyPublicPatch(current, patch) {
|
|
3021
3051
|
const next = JSON.parse(JSON.stringify(current));
|
|
3052
|
+
const secrets = [];
|
|
3022
3053
|
if (typeof patch.enabled === "boolean") next.enabled = patch.enabled;
|
|
3023
3054
|
if (patch.role === "engineer" || patch.role === "sales" || patch.role === "operations" || patch.role === "all") next.role = patch.role;
|
|
3055
|
+
if (typeof patch.connections === "object" && patch.connections !== null) {
|
|
3056
|
+
const incoming = patch.connections;
|
|
3057
|
+
next.connections = mergeConnections({
|
|
3058
|
+
...next.connections,
|
|
3059
|
+
...incoming
|
|
3060
|
+
});
|
|
3061
|
+
for (const system of Object.keys(REZ_CREDENTIAL_REFS)) {
|
|
3062
|
+
const row = incoming[system];
|
|
3063
|
+
if (typeof row !== "object" || row === null) continue;
|
|
3064
|
+
const secret = row.secret;
|
|
3065
|
+
if (typeof secret === "string" && secret.length > 0 && secret !== SECRET_MASK) secrets.push({
|
|
3066
|
+
system,
|
|
3067
|
+
value: secret
|
|
3068
|
+
});
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3024
3071
|
if (typeof patch.servers === "object" && patch.servers !== null) for (const [id, raw] of Object.entries(patch.servers)) {
|
|
3025
3072
|
if (typeof raw !== "object" || raw === null) continue;
|
|
3026
3073
|
const incoming = raw;
|
|
@@ -3046,11 +3093,14 @@ function applyPublicPatch(current, patch) {
|
|
|
3046
3093
|
if (typeof value.outputCostPer1k === "number") next.billing.outputCostPer1k = value.outputCostPer1k;
|
|
3047
3094
|
if (typeof value.monthlyBudget === "number") next.billing.monthlyBudget = value.monthlyBudget;
|
|
3048
3095
|
}
|
|
3049
|
-
return
|
|
3096
|
+
return {
|
|
3097
|
+
next,
|
|
3098
|
+
secrets
|
|
3099
|
+
};
|
|
3050
3100
|
}
|
|
3051
3101
|
/** Build every /api/dsh-rez-suite route (exact paths). */
|
|
3052
3102
|
function makeRoutes(deps) {
|
|
3053
|
-
const { getConfig, updateConfig, host, tokens } = deps;
|
|
3103
|
+
const { getConfig, updateConfig, host, tokens, onCredentialWritten } = deps;
|
|
3054
3104
|
const guard = (req, res, method) => {
|
|
3055
3105
|
if (!isLoopbackRequest(req)) {
|
|
3056
3106
|
writeJson(res, 403, { error: "forbidden: loopback-only" });
|
|
@@ -3077,8 +3127,11 @@ function makeRoutes(deps) {
|
|
|
3077
3127
|
writeJson(res, 400, { error: "invalid JSON body" });
|
|
3078
3128
|
return;
|
|
3079
3129
|
}
|
|
3080
|
-
const next = applyPublicPatch(getConfig(), body);
|
|
3081
|
-
|
|
3130
|
+
const { next, secrets } = applyPublicPatch(getConfig(), body);
|
|
3131
|
+
const saved = await updateConfig(next);
|
|
3132
|
+
for (const item of secrets) writeManagedCredential(REZ_CREDENTIAL_REFS[item.system], item.value);
|
|
3133
|
+
for (const system of REZ_SYSTEMS) onCredentialWritten?.(REZ_CREDENTIAL_REFS[system]);
|
|
3134
|
+
writeJson(res, 200, { config: publicConfig(saved) });
|
|
3082
3135
|
}
|
|
3083
3136
|
},
|
|
3084
3137
|
{
|
|
@@ -7537,6 +7590,22 @@ const Config = Schema.object({
|
|
|
7537
7590
|
"all"
|
|
7538
7591
|
]).default("all"),
|
|
7539
7592
|
servers: Schema.dict(serverSchema).default({}),
|
|
7593
|
+
connections: Schema.object({
|
|
7594
|
+
odoo: Schema.object({
|
|
7595
|
+
enabled: Schema.boolean().default(true),
|
|
7596
|
+
url: Schema.string().default(REZ_DEFAULT_CONNECTIONS.odoo.url)
|
|
7597
|
+
}).default(REZ_DEFAULT_CONNECTIONS.odoo),
|
|
7598
|
+
nextcloud: Schema.object({
|
|
7599
|
+
enabled: Schema.boolean().default(true),
|
|
7600
|
+
url: Schema.string().default(REZ_DEFAULT_CONNECTIONS.nextcloud.url),
|
|
7601
|
+
username: Schema.string().default(REZ_DEFAULT_CONNECTIONS.nextcloud.username)
|
|
7602
|
+
}).default(REZ_DEFAULT_CONNECTIONS.nextcloud),
|
|
7603
|
+
wechat: Schema.object({ enabled: Schema.boolean().default(true) }).default(REZ_DEFAULT_CONNECTIONS.wechat),
|
|
7604
|
+
homeassistant: Schema.object({
|
|
7605
|
+
enabled: Schema.boolean().default(true),
|
|
7606
|
+
url: Schema.string().default(REZ_DEFAULT_CONNECTIONS.homeassistant.url)
|
|
7607
|
+
}).default(REZ_DEFAULT_CONNECTIONS.homeassistant)
|
|
7608
|
+
}).default(REZ_DEFAULT_CONNECTIONS),
|
|
7540
7609
|
billing: Schema.object({
|
|
7541
7610
|
inputCostPer1k: Schema.number().default(.001),
|
|
7542
7611
|
outputCostPer1k: Schema.number().default(.002),
|
|
@@ -7558,7 +7627,7 @@ const REZ_GUIDANCE = [
|
|
|
7558
7627
|
"本机已安装 ReZ-TI 套件(一次安装):工作身份由 dsh-rez-sso 提供,MCP 由官方 dsh-mcp-client 接入 Odoo / Nextcloud / 企业微信 / Home Assistant。",
|
|
7559
7628
|
"工具名 mcp__odoo__*、mcp__nextcloud__*、mcp__wechat__*、mcp__homeassistant__*。",
|
|
7560
7629
|
"密钥:REZ_ODOO_TOKEN、REZ_NEXTCLOUD_PASSWORD、REZ_WECHAT_WEBHOOK、REZ_HA_TOKEN。",
|
|
7561
|
-
"个人微信(QClaw/ClawBot):打开
|
|
7630
|
+
"个人微信(QClaw/ClawBot):打开 设置 → 插件 → ReZ-TI → 微信 扫码,然后直接在微信里说话,不必再跑命令、也不要调用微信 MCP 工具。",
|
|
7562
7631
|
"意图用 rez_set_intent(erp/files/chat/home/auto)。审计用 rez_audit。",
|
|
7563
7632
|
"涉及资金、对外发送、设备控制、生产写入时先征得用户批准。"
|
|
7564
7633
|
].join("");
|
|
@@ -7572,13 +7641,19 @@ function delegatedHost() {
|
|
|
7572
7641
|
state: "disconnected",
|
|
7573
7642
|
toolCount: 0,
|
|
7574
7643
|
registeredTools: 0,
|
|
7575
|
-
lastError: "owned by @deepseek-ai/dsh-mcp-client"
|
|
7576
|
-
}));
|
|
7577
|
-
const test = async () => COMPOSED_SERVERS.map((server) => ({
|
|
7578
|
-
server,
|
|
7579
|
-
ok: false,
|
|
7580
|
-
error: "MCP is composed by dsh-mcp-client; set REZ_* credentials and check dsh logs"
|
|
7644
|
+
lastError: secretConfigured(server) ? "owned by @deepseek-ai/dsh-mcp-client" : "missing " + REZ_CREDENTIAL_REFS[server]
|
|
7581
7645
|
}));
|
|
7646
|
+
const test = async () => COMPOSED_SERVERS.map((server) => {
|
|
7647
|
+
return secretConfigured(server) ? {
|
|
7648
|
+
server,
|
|
7649
|
+
ok: true,
|
|
7650
|
+
serverInfo: REZ_CREDENTIAL_REFS[server] + " configured"
|
|
7651
|
+
} : {
|
|
7652
|
+
server,
|
|
7653
|
+
ok: false,
|
|
7654
|
+
error: "missing " + REZ_CREDENTIAL_REFS[server]
|
|
7655
|
+
};
|
|
7656
|
+
});
|
|
7582
7657
|
return {
|
|
7583
7658
|
status,
|
|
7584
7659
|
test,
|
|
@@ -7609,7 +7684,11 @@ function apply(ctx, config) {
|
|
|
7609
7684
|
return value;
|
|
7610
7685
|
},
|
|
7611
7686
|
host,
|
|
7612
|
-
tokens
|
|
7687
|
+
tokens,
|
|
7688
|
+
onCredentialWritten: (ref) => {
|
|
7689
|
+
const emit = ctx.emit;
|
|
7690
|
+
emit("credentials/updated", ref);
|
|
7691
|
+
}
|
|
7613
7692
|
});
|
|
7614
7693
|
let disposeRoutes;
|
|
7615
7694
|
let disposeTools;
|
package/lib/style.css
CHANGED
|
@@ -1,110 +1,83 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
.WRGRRW_shell {
|
|
2
|
+
flex-direction: column;
|
|
3
|
+
gap: 12px;
|
|
4
|
+
min-width: 0;
|
|
5
|
+
display: flex;
|
|
3
6
|
}
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
background: var(--dsw-alias-bg-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
.WRGRRW_card {
|
|
9
|
+
border: 1px solid var(--dsw-alias-border-l2);
|
|
10
|
+
background: var(--dsw-alias-bg-layer-3);
|
|
11
|
+
border-radius: 12px;
|
|
12
|
+
list-style: none;
|
|
13
|
+
transition: border-color .16s, background .16s;
|
|
11
14
|
}
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
.WRGRRW_card:hover {
|
|
17
|
+
border-color: var(--dsw-alias-label-dimmed);
|
|
15
18
|
}
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
.WRGRRW_cardOpen {
|
|
21
|
+
background: var(--dsw-alias-bg-layer-2);
|
|
22
|
+
border-color: var(--dsw-alias-label-dimmed);
|
|
19
23
|
}
|
|
20
24
|
|
|
21
|
-
.
|
|
25
|
+
.WRGRRW_header {
|
|
26
|
+
appearance: none;
|
|
22
27
|
width: 100%;
|
|
23
|
-
|
|
24
|
-
color:
|
|
28
|
+
font: inherit;
|
|
29
|
+
color: inherit;
|
|
30
|
+
text-align: left;
|
|
25
31
|
cursor: pointer;
|
|
26
|
-
white-space: nowrap;
|
|
27
32
|
background: none;
|
|
28
|
-
border:
|
|
29
|
-
border-radius:
|
|
33
|
+
border: 0;
|
|
34
|
+
border-radius: 12px;
|
|
30
35
|
align-items: center;
|
|
31
|
-
gap:
|
|
32
|
-
padding:
|
|
33
|
-
font-size: 13px;
|
|
36
|
+
gap: 12px;
|
|
37
|
+
padding: 14px 16px;
|
|
34
38
|
display: flex;
|
|
35
39
|
}
|
|
36
40
|
|
|
37
|
-
.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
.WRGRRW_entryIcon {
|
|
43
|
-
flex: none;
|
|
44
|
-
justify-content: center;
|
|
45
|
-
align-items: center;
|
|
46
|
-
display: inline-flex;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.WRGRRW_entryLabel {
|
|
50
|
-
text-overflow: ellipsis;
|
|
51
|
-
overflow: hidden;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
[data-dsh-frame][data-sidebar-collapsed] .WRGRRW_entry {
|
|
55
|
-
justify-content: center;
|
|
56
|
-
width: 100%;
|
|
57
|
-
padding: 0;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
[data-dsh-frame][data-sidebar-collapsed] .WRGRRW_entryLabel {
|
|
61
|
-
display: none;
|
|
41
|
+
.WRGRRW_header:focus-visible {
|
|
42
|
+
outline: 2px solid var(--dsw-alias-brand-primary);
|
|
43
|
+
outline-offset: -2px;
|
|
62
44
|
}
|
|
63
45
|
|
|
64
|
-
.
|
|
65
|
-
|
|
46
|
+
.WRGRRW_headText {
|
|
47
|
+
flex-direction: column;
|
|
48
|
+
flex: 1;
|
|
49
|
+
gap: 4px;
|
|
50
|
+
min-width: 0;
|
|
51
|
+
display: flex;
|
|
66
52
|
}
|
|
67
53
|
|
|
68
|
-
.
|
|
69
|
-
background: var(--dsw-alias-bg-base);
|
|
70
|
-
min-width: 0;
|
|
71
|
-
height: 100%;
|
|
72
|
-
min-height: 0;
|
|
54
|
+
.WRGRRW_name {
|
|
73
55
|
color: var(--dsw-alias-label-primary);
|
|
74
|
-
font-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
padding: 14px 16px 16px;
|
|
78
|
-
display: flex;
|
|
56
|
+
font-size: 15px;
|
|
57
|
+
font-weight: 600;
|
|
58
|
+
line-height: 1.4;
|
|
79
59
|
}
|
|
80
60
|
|
|
81
|
-
.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
display: flex;
|
|
61
|
+
.WRGRRW_description {
|
|
62
|
+
color: var(--dsw-alias-label-tertiary);
|
|
63
|
+
font-size: 13px;
|
|
64
|
+
line-height: 1.5;
|
|
86
65
|
}
|
|
87
66
|
|
|
88
|
-
.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
font-weight: 700;
|
|
67
|
+
.WRGRRW_chevron {
|
|
68
|
+
color: var(--dsw-alias-label-tertiary);
|
|
69
|
+
flex: none;
|
|
70
|
+
transition: transform .16s;
|
|
93
71
|
}
|
|
94
72
|
|
|
95
|
-
.
|
|
96
|
-
|
|
97
|
-
cursor: pointer;
|
|
98
|
-
background: none;
|
|
99
|
-
border: none;
|
|
100
|
-
border-radius: 6px;
|
|
101
|
-
padding: 4px 8px;
|
|
102
|
-
font-size: 14px;
|
|
73
|
+
.WRGRRW_chevronOpen {
|
|
74
|
+
transform: rotate(180deg);
|
|
103
75
|
}
|
|
104
76
|
|
|
105
|
-
.
|
|
106
|
-
|
|
107
|
-
|
|
77
|
+
.WRGRRW_body {
|
|
78
|
+
border-top: 1px solid var(--dsw-alias-border-l2);
|
|
79
|
+
margin: 0 16px 12px;
|
|
80
|
+
padding-top: 8px;
|
|
108
81
|
}
|
|
109
82
|
|
|
110
83
|
.WRGRRW_tabBar {
|
|
@@ -136,21 +109,12 @@ html[data-dsh-rez-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-act
|
|
|
136
109
|
font-weight: 600;
|
|
137
110
|
}
|
|
138
111
|
|
|
139
|
-
.WRGRRW_panelContent {
|
|
140
|
-
flex-direction: column;
|
|
141
|
-
flex: 1;
|
|
142
|
-
min-height: 0;
|
|
143
|
-
display: flex;
|
|
144
|
-
overflow: hidden;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
112
|
.WRGRRW_tabBody {
|
|
148
113
|
flex-direction: column;
|
|
149
|
-
flex: 1;
|
|
150
114
|
gap: 12px;
|
|
151
|
-
min-
|
|
115
|
+
min-width: 0;
|
|
116
|
+
padding: 12px 0 4px;
|
|
152
117
|
display: flex;
|
|
153
|
-
overflow-y: auto;
|
|
154
118
|
}
|
|
155
119
|
|
|
156
120
|
.WRGRRW_section {
|
|
@@ -164,16 +128,17 @@ html[data-dsh-rez-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-act
|
|
|
164
128
|
}
|
|
165
129
|
|
|
166
130
|
.WRGRRW_sectionTitle {
|
|
131
|
+
color: var(--dsw-alias-label-primary);
|
|
167
132
|
margin: 0;
|
|
168
133
|
font-size: 13px;
|
|
169
134
|
font-weight: 600;
|
|
170
135
|
}
|
|
171
136
|
|
|
172
137
|
.WRGRRW_field {
|
|
173
|
-
|
|
174
|
-
align-items:
|
|
175
|
-
gap:
|
|
176
|
-
display:
|
|
138
|
+
flex-direction: column;
|
|
139
|
+
align-items: stretch;
|
|
140
|
+
gap: 4px;
|
|
141
|
+
display: flex;
|
|
177
142
|
}
|
|
178
143
|
|
|
179
144
|
.WRGRRW_label {
|
|
@@ -183,7 +148,7 @@ html[data-dsh-rez-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-act
|
|
|
183
148
|
|
|
184
149
|
.WRGRRW_input, .WRGRRW_select {
|
|
185
150
|
color: var(--dsw-alias-label-primary);
|
|
186
|
-
background: var(--dsw-specific-input-major);
|
|
151
|
+
background: var(--dsw-specific-input-major, var(--dsw-alias-bg-layer-3));
|
|
187
152
|
border: 1px solid var(--dsw-alias-border-l2);
|
|
188
153
|
border-radius: 8px;
|
|
189
154
|
outline: none;
|
|
@@ -207,7 +172,7 @@ html[data-dsh-rez-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-act
|
|
|
207
172
|
|
|
208
173
|
.WRGRRW_button {
|
|
209
174
|
border: 1px solid var(--dsw-alias-border-l2);
|
|
210
|
-
background: var(--dsw-specific-input-major);
|
|
175
|
+
background: var(--dsw-specific-input-major, var(--dsw-alias-bg-layer-3));
|
|
211
176
|
color: var(--dsw-alias-label-primary);
|
|
212
177
|
cursor: pointer;
|
|
213
178
|
border-radius: 8px;
|
|
@@ -215,23 +180,19 @@ html[data-dsh-rez-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-act
|
|
|
215
180
|
font-size: 13px;
|
|
216
181
|
}
|
|
217
182
|
|
|
218
|
-
.WRGRRW_button:hover {
|
|
183
|
+
.WRGRRW_button:hover:not(:disabled) {
|
|
219
184
|
background: var(--dsw-alias-interactive-bg-hover);
|
|
220
185
|
}
|
|
221
186
|
|
|
222
|
-
.
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
width: 240px;
|
|
226
|
-
height: 240px;
|
|
227
|
-
margin: 8px 0;
|
|
228
|
-
display: block;
|
|
187
|
+
.WRGRRW_button:disabled {
|
|
188
|
+
opacity: .4;
|
|
189
|
+
cursor: default;
|
|
229
190
|
}
|
|
230
191
|
|
|
231
192
|
.WRGRRW_primaryButton {
|
|
232
|
-
background: var(--dsw-alias-
|
|
233
|
-
border-color: var(--dsw-alias-
|
|
234
|
-
color:
|
|
193
|
+
background: var(--dsw-alias-label-primary);
|
|
194
|
+
border-color: var(--dsw-alias-label-primary);
|
|
195
|
+
color: var(--dsw-alias-bg-layer-3);
|
|
235
196
|
}
|
|
236
197
|
|
|
237
198
|
.WRGRRW_dangerButton {
|
|
@@ -240,9 +201,20 @@ html[data-dsh-rez-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-act
|
|
|
240
201
|
color: #fff;
|
|
241
202
|
}
|
|
242
203
|
|
|
204
|
+
.WRGRRW_qr {
|
|
205
|
+
background: #fff;
|
|
206
|
+
border-radius: 8px;
|
|
207
|
+
width: 200px;
|
|
208
|
+
height: 200px;
|
|
209
|
+
margin: 8px 0;
|
|
210
|
+
display: block;
|
|
211
|
+
}
|
|
212
|
+
|
|
243
213
|
.WRGRRW_message {
|
|
244
214
|
color: var(--dsw-alias-label-secondary);
|
|
215
|
+
margin: 0;
|
|
245
216
|
font-size: 12.5px;
|
|
217
|
+
line-height: 1.5;
|
|
246
218
|
}
|
|
247
219
|
|
|
248
220
|
.WRGRRW_error {
|
|
@@ -252,8 +224,6 @@ html[data-dsh-rez-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-act
|
|
|
252
224
|
.WRGRRW_tableWrap {
|
|
253
225
|
border: 1px solid var(--dsw-alias-border-l1);
|
|
254
226
|
border-radius: 10px;
|
|
255
|
-
flex: 1;
|
|
256
|
-
min-height: 0;
|
|
257
227
|
overflow: auto;
|
|
258
228
|
}
|
|
259
229
|
|
|
@@ -296,12 +266,12 @@ html[data-dsh-rez-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-act
|
|
|
296
266
|
}
|
|
297
267
|
|
|
298
268
|
.WRGRRW_cards {
|
|
299
|
-
grid-template-columns: repeat(auto-fill, minmax(
|
|
269
|
+
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
|
|
300
270
|
gap: 8px;
|
|
301
271
|
display: grid;
|
|
302
272
|
}
|
|
303
273
|
|
|
304
|
-
.
|
|
274
|
+
.WRGRRW_stat {
|
|
305
275
|
border: 1px solid var(--dsw-alias-border-l1);
|
|
306
276
|
border-radius: 10px;
|
|
307
277
|
padding: 10px;
|
|
@@ -313,6 +283,7 @@ html[data-dsh-rez-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-act
|
|
|
313
283
|
}
|
|
314
284
|
|
|
315
285
|
.WRGRRW_cardValue {
|
|
286
|
+
color: var(--dsw-alias-label-primary);
|
|
316
287
|
font-size: 15px;
|
|
317
288
|
font-weight: 600;
|
|
318
289
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rezti/dsh-rez-suite",
|
|
3
3
|
"description": "ReZ-TI employee plugin for DeepSeek Harness: one install enables company MCP (Odoo / Nextcloud / WeCom / Weixin-ClawBot / Home Assistant) and work identity.",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.6",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": "^22.19.0 || >=24.0.0"
|
|
@@ -28,7 +28,9 @@
|
|
|
28
28
|
"inject": [
|
|
29
29
|
"@deepseek-ai/dsh-client-runtime",
|
|
30
30
|
"@deepseek-ai/dsh-client-connection",
|
|
31
|
-
"@deepseek-ai/dsh-client-
|
|
31
|
+
"@deepseek-ai/dsh-client-locale",
|
|
32
|
+
"@deepseek-ai/dsh-client-ui-settings",
|
|
33
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins"
|
|
32
34
|
],
|
|
33
35
|
"platform": "web"
|
|
34
36
|
}
|
|
@@ -36,12 +38,12 @@
|
|
|
36
38
|
"dependencies": {
|
|
37
39
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
38
40
|
"zod": "^4.4.3",
|
|
39
|
-
"@rezti/dsh-rez-
|
|
40
|
-
"@rezti/dsh-rez-odoo": "0.1.
|
|
41
|
-
"@rezti/dsh-rez-
|
|
41
|
+
"@rezti/dsh-rez-nextcloud": "0.1.5",
|
|
42
|
+
"@rezti/dsh-rez-odoo": "0.1.5",
|
|
43
|
+
"@rezti/dsh-rez-sso": "0.1.5",
|
|
44
|
+
"@rezti/dsh-rez-ha-bridge": "0.1.5",
|
|
45
|
+
"@rezti/dsh-rez-wechat": "0.1.5",
|
|
42
46
|
"@rezti/dsh-rez-token-manager": "0.1.3",
|
|
43
|
-
"@rezti/dsh-rez-sso": "0.1.4",
|
|
44
|
-
"@rezti/dsh-rez-wechat": "0.1.4",
|
|
45
47
|
"@rezti/dsh-rez-intent": "0.1.3"
|
|
46
48
|
},
|
|
47
49
|
"peerDependencies": {
|
package/src/client/index.ts
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Browser-half entry for dsh-rez-suite
|
|
3
|
-
* Registers locale dictionaries and
|
|
4
|
-
*
|
|
2
|
+
* Browser-half entry for dsh-rez-suite.
|
|
3
|
+
* Registers locale dictionaries and contributes a native Settings card
|
|
4
|
+
* (设置 → 插件 → 插件配置) plus a Plugins tab. Do not mount a sidebar
|
|
5
|
+
* takeover over the conversation column.
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'
|
|
8
9
|
import type {} from '@deepseek-ai/dsh-client-locale/client'
|
|
10
|
+
import type {} from '@deepseek-ai/dsh-client-ui-settings/client'
|
|
9
11
|
import type {} from '@deepseek-ai/dsh-client-ui-slots'
|
|
10
|
-
import { RezApi } from './api.ts'
|
|
11
12
|
import { en, zh, type RezKey } from './locales.ts'
|
|
12
|
-
import {
|
|
13
|
-
import { PanelController } from './panel/controller.ts'
|
|
14
|
-
import { mountSidebarEntry } from './sidebar-entry.ts'
|
|
13
|
+
import { RezPluginCard, RezSettingsPage } from './settings-card.tsx'
|
|
15
14
|
|
|
16
15
|
const NS = 'dsh-rez-suite'
|
|
17
16
|
|
|
@@ -19,27 +18,40 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
|
19
18
|
interface LocaleNamespaceMap {
|
|
20
19
|
'dsh-rez-suite': RezKey
|
|
21
20
|
}
|
|
21
|
+
interface SlotMap {
|
|
22
|
+
'settings.plugin.item': {
|
|
23
|
+
kind: 'list'
|
|
24
|
+
scope: 'root'
|
|
25
|
+
owner: { children?: never }
|
|
26
|
+
}
|
|
27
|
+
'settings.plugins.tab': {
|
|
28
|
+
kind: 'list'
|
|
29
|
+
scope: 'root'
|
|
30
|
+
owner: { children?: never }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
22
33
|
}
|
|
23
34
|
|
|
24
35
|
export const inject = ['slots', 'locale']
|
|
25
36
|
|
|
26
|
-
export type { PanelControllerSnapshot } from './panel/controller.ts'
|
|
27
|
-
export type { RezPanelProps } from './panel/RezPanel.tsx'
|
|
28
37
|
export type { RezKey } from './locales.ts'
|
|
29
38
|
|
|
30
39
|
export function apply(ctx: ClientContext): void {
|
|
40
|
+
const t = ctx.locale.bind(NS)
|
|
31
41
|
ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-rez-suite: dictionaries')
|
|
32
42
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({
|
|
44
|
+
name: 'settings.plugin.item',
|
|
45
|
+
id: 'rez-suite',
|
|
46
|
+
order: 40,
|
|
47
|
+
locale: NS,
|
|
48
|
+
}, RezPluginCard))
|
|
49
|
+
|
|
50
|
+
ctx.slots.inject('settings.plugins.tab', () => ctx.slots.register({
|
|
51
|
+
name: 'settings.plugins.tab',
|
|
52
|
+
id: 'rez',
|
|
53
|
+
order: 20,
|
|
54
|
+
label: () => t('settings.title'),
|
|
55
|
+
locale: NS,
|
|
56
|
+
}, RezSettingsPage))
|
|
45
57
|
}
|