@rezti/dsh-rez-suite 0.1.26 → 0.1.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/client.d.ts +7 -0
- package/lib/client.js +388 -187
- package/lib/index.d.ts +4 -0
- package/lib/index.js +85 -7
- package/lib/style.css +47 -0
- package/package.json +7 -7
- package/src/boss/mount.ts +2 -0
- package/src/client/assets/rez-mark.png +0 -0
- package/src/client/brand-mark.ts +4 -0
- package/src/client/brand.module.css +51 -0
- package/src/client/brand.ts +135 -0
- package/src/client/index.ts +11 -0
- package/src/client/locales.ts +14 -0
- package/src/client/panel/AuditTab.tsx +20 -19
- package/src/client/panel/ConfigTab.tsx +57 -39
- package/src/client/panel/StatusTab.tsx +11 -10
- package/src/client/panel/WeixinTab.tsx +9 -8
- package/src/client/panel/helpers.ts +20 -5
- package/src/client/settings-card.tsx +48 -42
- package/src/client/upgrade-button.tsx +24 -12
- package/src/index.ts +11 -0
- package/src/observe-mcp.ts +5 -2
- package/src/presets.ts +1 -0
- package/src/protocol.ts +2 -0
- package/src/store.ts +6 -0
- package/src/tianyancha.ts +79 -0
- package/templates/boss/money/AGENTS.md +2 -0
- package/templates/boss/ops/AGENTS.md +2 -0
- package/templates/boss/product/AGENTS.md +4 -0
- package/templates/staff/finance/.agents/skills/staff-finance/SKILL.md +1 -1
- package/templates/staff/finance/AGENTS.md +6 -0
- package/templates/staff/finance/MEMORY.md +1 -1
- package/templates/staff/hr/.agents/skills/staff-hr/SKILL.md +1 -1
- package/templates/staff/hr/AGENTS.md +6 -0
- package/templates/staff/hr/MEMORY.md +1 -1
- package/templates/staff/legal/.agents/skills/staff-legal/SKILL.md +1 -1
- package/templates/staff/legal/AGENTS.md +10 -0
- package/templates/staff/legal/MEMORY.md +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -1730,6 +1730,10 @@ interface RezConnections {
|
|
|
1730
1730
|
enabled: boolean;
|
|
1731
1731
|
siteUrl: string;
|
|
1732
1732
|
};
|
|
1733
|
+
tianyancha: {
|
|
1734
|
+
enabled: boolean;
|
|
1735
|
+
url: string;
|
|
1736
|
+
};
|
|
1733
1737
|
}
|
|
1734
1738
|
/** Full plugin configuration persisted under ~/.dsh/dsh-rez-suite.json. */
|
|
1735
1739
|
interface RezConfig {
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { dirname, join, relative } from "node:path";
|
|
4
|
-
import { REZ_CREDENTIAL_REFS, REZ_DEFAULT_CONNECTIONS, REZ_SYSTEMS, lastMcpStartError, mergeConnections, secretConfigured, writeManagedCredential } from "@rezti/dsh-rez-sso";
|
|
4
|
+
import { REZ_CREDENTIAL_REFS, REZ_DEFAULT_CONNECTIONS, REZ_SYSTEMS, lastMcpStartError, loadRezConnections, mergeConnections, secretConfigured, startMcpWhenSecret, writeManagedCredential } from "@rezti/dsh-rez-sso";
|
|
5
5
|
import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, statSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { DatabaseSync } from "node:sqlite";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
@@ -2858,7 +2858,8 @@ const COMPOSED_SERVERS = [
|
|
|
2858
2858
|
"wechat",
|
|
2859
2859
|
"homeassistant",
|
|
2860
2860
|
"tapd",
|
|
2861
|
-
"gsc"
|
|
2861
|
+
"gsc",
|
|
2862
|
+
"tianyancha"
|
|
2862
2863
|
];
|
|
2863
2864
|
function mcpToolPrefix(server) {
|
|
2864
2865
|
return "mcp__" + server + "__";
|
|
@@ -2920,7 +2921,7 @@ function observeServer(server, input) {
|
|
|
2920
2921
|
};
|
|
2921
2922
|
}
|
|
2922
2923
|
function observeComposedServers(input) {
|
|
2923
|
-
return COMPOSED_SERVERS.map((server) => observeServer(server, input));
|
|
2924
|
+
return (input.config.role === "boss" ? COMPOSED_SERVERS : COMPOSED_SERVERS.filter((server) => server !== "tianyancha")).map((server) => observeServer(server, input));
|
|
2924
2925
|
}
|
|
2925
2926
|
function testComposedServers(input) {
|
|
2926
2927
|
return observeComposedServers(input).map((row) => {
|
|
@@ -3049,6 +3050,12 @@ function publicConfig(config) {
|
|
|
3049
3050
|
siteUrl: connections.gsc.siteUrl,
|
|
3050
3051
|
secretConfigured: secretConfigured("gsc"),
|
|
3051
3052
|
secretRef: REZ_CREDENTIAL_REFS.gsc
|
|
3053
|
+
},
|
|
3054
|
+
tianyancha: {
|
|
3055
|
+
enabled: connections.tianyancha.enabled,
|
|
3056
|
+
url: connections.tianyancha.url,
|
|
3057
|
+
secretConfigured: secretConfigured("tianyancha"),
|
|
3058
|
+
secretRef: REZ_CREDENTIAL_REFS.tianyancha
|
|
3052
3059
|
}
|
|
3053
3060
|
},
|
|
3054
3061
|
billing: { ...config.billing }
|
|
@@ -7883,14 +7890,16 @@ function listFiles(root) {
|
|
|
7883
7890
|
const STAFF_GUIDANCE = [
|
|
7884
7891
|
"侧栏已登记人事助理 / 财务助理 / 法务助理。装完、选身份后自动出现,不必手动「添加工作区」、也不必拖排序。",
|
|
7885
7892
|
"三个助理给所有人用。能做什么看当前 Odoo 帐号的可视范围;Harness 只列选项,不自审、不自过账。",
|
|
7886
|
-
"报销走财务助理。搞钱室是战略数字,不要在助理房间里做。"
|
|
7893
|
+
"报销走财务助理。搞钱室是战略数字,不要在助理房间里做。",
|
|
7894
|
+
"用户用中文就中文、用英文就英文;不要因为工作区文件是中文就强制中文。"
|
|
7887
7895
|
].join("");
|
|
7888
7896
|
const BOSS_GUIDANCE = [
|
|
7889
7897
|
"当前角色是老板。侧栏已登记搞钱 / 产品 / 运营,后面是人事助理 / 财务助理 / 法务助理。不必手动「添加工作区」。",
|
|
7890
7898
|
"每个文件夹是独立作战室,官方 dsh 会注入该目录 AGENTS.md。",
|
|
7891
7899
|
"若该室仍有 BOOTSTRAP.md:本会话先做短问三拍,沉淀到 PRIORITIES.md / MEMORY.md,然后删除 BOOTSTRAP.md。",
|
|
7892
7900
|
"已初始化后:读 PRIORITIES.md + MEMORY.md + 今日/昨日 memory/;老板三室回答固定四行:结论 → 数字(哪家公司、哪段时间)→ 拍板 1~3 件事 → 未执行任何过账/付款/对外发送。",
|
|
7893
|
-
"微信文件夹仍是收件箱,不要在那边查账、报销或砍 SKU。"
|
|
7901
|
+
"微信文件夹仍是收件箱,不要在那边查账、报销或砍 SKU。",
|
|
7902
|
+
"用户用中文就中文、用英文就英文;不要因为工作区文件是中文就强制中文。"
|
|
7894
7903
|
].join("");
|
|
7895
7904
|
const BOSS_ROLE_HINT = "搞钱 / 产品 / 运营仅角色选「老板」时出现。人事 / 财务 / 法务助理所有角色都会登记。";
|
|
7896
7905
|
function workspaceGuidanceFor(role) {
|
|
@@ -8080,6 +8089,65 @@ function liveSelfUpdate() {
|
|
|
8080
8089
|
});
|
|
8081
8090
|
}
|
|
8082
8091
|
//#endregion
|
|
8092
|
+
//#region src/tianyancha.ts
|
|
8093
|
+
const TIANYANCHA_MCP_URL = "https://mcp.tianyancha.com/mcp";
|
|
8094
|
+
function shouldStartTianyancha(role) {
|
|
8095
|
+
return role === "boss";
|
|
8096
|
+
}
|
|
8097
|
+
function bearerAuthorization(secret) {
|
|
8098
|
+
const trimmed = secret.trim();
|
|
8099
|
+
if (/^bearer\s+/i.test(trimmed)) return "Bearer " + trimmed.replace(/^bearer\s+/i, "");
|
|
8100
|
+
return "Bearer " + trimmed;
|
|
8101
|
+
}
|
|
8102
|
+
function tianyanchaMcpConfig(secret) {
|
|
8103
|
+
const { url } = loadRezConnections().tianyancha;
|
|
8104
|
+
return {
|
|
8105
|
+
serverName: "tianyancha",
|
|
8106
|
+
transport: "streamable-http",
|
|
8107
|
+
url: url.length > 0 ? url : TIANYANCHA_MCP_URL,
|
|
8108
|
+
headers: { Authorization: bearerAuthorization(secret) },
|
|
8109
|
+
failOnStartupError: false
|
|
8110
|
+
};
|
|
8111
|
+
}
|
|
8112
|
+
/** Start when role is boss; dispose the mcp-client fiber when the identity leaves. */
|
|
8113
|
+
function mountTianyanchaMcp(ctx, getRole, start = startMcpWhenSecret) {
|
|
8114
|
+
let session;
|
|
8115
|
+
let pending = false;
|
|
8116
|
+
const ensure = () => {
|
|
8117
|
+
(async () => {
|
|
8118
|
+
if (!shouldStartTianyancha(getRole())) {
|
|
8119
|
+
session?.();
|
|
8120
|
+
session = void 0;
|
|
8121
|
+
return;
|
|
8122
|
+
}
|
|
8123
|
+
if (session !== void 0 || pending) return;
|
|
8124
|
+
pending = true;
|
|
8125
|
+
let raced = false;
|
|
8126
|
+
try {
|
|
8127
|
+
const dispose = await start(ctx, {
|
|
8128
|
+
system: "tianyancha",
|
|
8129
|
+
label: "天眼查",
|
|
8130
|
+
config: tianyanchaMcpConfig
|
|
8131
|
+
});
|
|
8132
|
+
if (!shouldStartTianyancha(getRole())) {
|
|
8133
|
+
raced = true;
|
|
8134
|
+
dispose();
|
|
8135
|
+
return;
|
|
8136
|
+
}
|
|
8137
|
+
session = dispose;
|
|
8138
|
+
} catch (error) {
|
|
8139
|
+
const why = error instanceof Error ? error.message : String(error);
|
|
8140
|
+
console.error("[dsh-rez-suite] tianyancha MCP start failed:", why);
|
|
8141
|
+
} finally {
|
|
8142
|
+
pending = false;
|
|
8143
|
+
if (raced && shouldStartTianyancha(getRole()) && session === void 0) ensure();
|
|
8144
|
+
}
|
|
8145
|
+
})();
|
|
8146
|
+
};
|
|
8147
|
+
ensure();
|
|
8148
|
+
return ensure;
|
|
8149
|
+
}
|
|
8150
|
+
//#endregion
|
|
8083
8151
|
//#region src/index.ts
|
|
8084
8152
|
const name = "rez-suite";
|
|
8085
8153
|
const inject = [
|
|
@@ -8133,7 +8201,11 @@ const Config = Schema.object({
|
|
|
8133
8201
|
gsc: Schema.object({
|
|
8134
8202
|
enabled: Schema.boolean().default(true),
|
|
8135
8203
|
siteUrl: Schema.string().default(REZ_DEFAULT_CONNECTIONS.gsc.siteUrl)
|
|
8136
|
-
}).default(REZ_DEFAULT_CONNECTIONS.gsc)
|
|
8204
|
+
}).default(REZ_DEFAULT_CONNECTIONS.gsc),
|
|
8205
|
+
tianyancha: Schema.object({
|
|
8206
|
+
enabled: Schema.boolean().default(true),
|
|
8207
|
+
url: Schema.string().default(REZ_DEFAULT_CONNECTIONS.tianyancha.url)
|
|
8208
|
+
}).default(REZ_DEFAULT_CONNECTIONS.tianyancha)
|
|
8137
8209
|
}).default(REZ_DEFAULT_CONNECTIONS),
|
|
8138
8210
|
billing: Schema.object({
|
|
8139
8211
|
inputCostPer1k: Schema.number().default(.001),
|
|
@@ -8152,7 +8224,9 @@ const REZ_GUIDANCE_CORE = [
|
|
|
8152
8224
|
"密钥:REZ_ODOO_TOKEN、REZ_NEXTCLOUD_PASSWORD、REZ_WECHAT_WEBHOOK、REZ_HA_TOKEN、REZ_TAPD_TOKEN、REZ_GSC_KEY。",
|
|
8153
8225
|
"个人微信(QClaw/ClawBot):打开 设置 → 插件 → ReZ-TI → 微信 扫码,然后直接在微信里说话。消息进入网页左侧「微信」文件夹并延续同一会话,模型跟网页默认。网页归档了再从微信说话会自动恢复到侧栏。发「重启对话」会新开一条可见会话并把旧会话归档。网页端必须开着。不必再跑命令、也不要调用微信 MCP 工具。",
|
|
8154
8226
|
"意图用 rez_set_intent(erp/files/chat/home/auto)。审计用 rez_audit。",
|
|
8155
|
-
"涉及资金、对外发送、设备控制、生产写入时先征得用户批准。"
|
|
8227
|
+
"涉及资金、对外发送、设备控制、生产写入时先征得用户批准。",
|
|
8228
|
+
"Match the user language: Chinese or English. Do not force 中文 when they write English.",
|
|
8229
|
+
"制度、手册、出差/报销标准、素材路径:打开 Nextcloud Documents/Standards/INDEX.yaml,按 code 取当前 effective_from 最新且未被 replace 的条目,再按相对 uri 打开。引用带路径+生效日。找不到就说「标准文件未归档」,不要用 MEMORY 旧数字。素材文件夹用首次创建标题,不用会变的 Odoo/销售名。"
|
|
8156
8230
|
].join("");
|
|
8157
8231
|
function rezGuidanceFor(role) {
|
|
8158
8232
|
return REZ_GUIDANCE_CORE + workspaceGuidanceFor(role);
|
|
@@ -8180,6 +8254,7 @@ function delegatedHost(ctx, getConfig) {
|
|
|
8180
8254
|
function apply(ctx, config) {
|
|
8181
8255
|
let current = () => normalize(config);
|
|
8182
8256
|
const syncWorkspaces = mountRezWorkspaces(ctx, () => current().role);
|
|
8257
|
+
const syncTianyancha = mountTianyanchaMcp(ctx, () => current().role);
|
|
8183
8258
|
const tokens = new TokenManager(joinTokenDb());
|
|
8184
8259
|
const host = delegatedHost(ctx, () => current());
|
|
8185
8260
|
ctx.effect(() => () => {
|
|
@@ -8193,6 +8268,7 @@ function apply(ctx, config) {
|
|
|
8193
8268
|
saveConfig(value);
|
|
8194
8269
|
current = () => value;
|
|
8195
8270
|
syncWorkspaces();
|
|
8271
|
+
syncTianyancha();
|
|
8196
8272
|
try {
|
|
8197
8273
|
const settings = ctx.get("settings");
|
|
8198
8274
|
if (settings?.update !== void 0) await settings.update(REZ_SETTINGS_NAMESPACE, value);
|
|
@@ -8250,10 +8326,12 @@ function apply(ctx, config) {
|
|
|
8250
8326
|
current = source;
|
|
8251
8327
|
sync();
|
|
8252
8328
|
syncWorkspaces();
|
|
8329
|
+
syncTianyancha();
|
|
8253
8330
|
},
|
|
8254
8331
|
onChange: () => {
|
|
8255
8332
|
sync();
|
|
8256
8333
|
syncWorkspaces();
|
|
8334
|
+
syncTianyancha();
|
|
8257
8335
|
}
|
|
8258
8336
|
});
|
|
8259
8337
|
sync();
|
package/lib/style.css
CHANGED
|
@@ -1,3 +1,50 @@
|
|
|
1
|
+
.r9dlUa_wordmark {
|
|
2
|
+
min-width: 0;
|
|
3
|
+
color: inherit;
|
|
4
|
+
align-items: center;
|
|
5
|
+
gap: 8px;
|
|
6
|
+
display: inline-flex;
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.r9dlUa_mark {
|
|
11
|
+
object-fit: contain;
|
|
12
|
+
flex: none;
|
|
13
|
+
width: 28px;
|
|
14
|
+
height: 28px;
|
|
15
|
+
display: block;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.r9dlUa_markOnly {
|
|
19
|
+
object-fit: contain;
|
|
20
|
+
width: 100%;
|
|
21
|
+
max-width: 28px;
|
|
22
|
+
height: 100%;
|
|
23
|
+
max-height: 28px;
|
|
24
|
+
display: block;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.r9dlUa_name {
|
|
28
|
+
letter-spacing: .02em;
|
|
29
|
+
white-space: nowrap;
|
|
30
|
+
text-overflow: ellipsis;
|
|
31
|
+
font-size: 15px;
|
|
32
|
+
font-weight: 650;
|
|
33
|
+
overflow: hidden;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.r9dlUa_badge {
|
|
37
|
+
letter-spacing: .06em;
|
|
38
|
+
opacity: .72;
|
|
39
|
+
white-space: nowrap;
|
|
40
|
+
border: 1px solid;
|
|
41
|
+
border-radius: 4px;
|
|
42
|
+
flex: none;
|
|
43
|
+
padding: 2px 6px;
|
|
44
|
+
font-size: 10px;
|
|
45
|
+
font-weight: 700;
|
|
46
|
+
line-height: 1.2;
|
|
47
|
+
}
|
|
1
48
|
.LOjPTW_shell {
|
|
2
49
|
flex-direction: column;
|
|
3
50
|
gap: 12px;
|
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.
|
|
4
|
+
"version": "0.1.33",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": "^22.19.0 || >=24.0.0"
|
|
@@ -39,15 +39,15 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
41
41
|
"zod": "^4.4.3",
|
|
42
|
-
"@rezti/dsh-rez-
|
|
43
|
-
"@rezti/dsh-rez-
|
|
42
|
+
"@rezti/dsh-rez-gsc": "0.1.0",
|
|
43
|
+
"@rezti/dsh-rez-ha-bridge": "0.1.9",
|
|
44
44
|
"@rezti/dsh-rez-odoo": "0.1.9",
|
|
45
|
-
"@rezti/dsh-rez-
|
|
46
|
-
"@rezti/dsh-rez-tapd": "0.1.0",
|
|
45
|
+
"@rezti/dsh-rez-nextcloud": "0.1.9",
|
|
47
46
|
"@rezti/dsh-rez-token-manager": "0.1.4",
|
|
48
|
-
"@rezti/dsh-rez-
|
|
47
|
+
"@rezti/dsh-rez-tapd": "0.1.0",
|
|
49
48
|
"@rezti/dsh-rez-wechat": "0.1.14",
|
|
50
|
-
"@rezti/dsh-rez-
|
|
49
|
+
"@rezti/dsh-rez-sso": "0.1.10",
|
|
50
|
+
"@rezti/dsh-rez-intent": "0.1.5"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"react": "^18.2.0",
|
package/src/boss/mount.ts
CHANGED
|
@@ -15,6 +15,7 @@ export const STAFF_GUIDANCE = [
|
|
|
15
15
|
'侧栏已登记人事助理 / 财务助理 / 法务助理。装完、选身份后自动出现,不必手动「添加工作区」、也不必拖排序。',
|
|
16
16
|
'三个助理给所有人用。能做什么看当前 Odoo 帐号的可视范围;Harness 只列选项,不自审、不自过账。',
|
|
17
17
|
'报销走财务助理。搞钱室是战略数字,不要在助理房间里做。',
|
|
18
|
+
'用户用中文就中文、用英文就英文;不要因为工作区文件是中文就强制中文。',
|
|
18
19
|
].join('')
|
|
19
20
|
|
|
20
21
|
export const BOSS_GUIDANCE = [
|
|
@@ -23,6 +24,7 @@ export const BOSS_GUIDANCE = [
|
|
|
23
24
|
'若该室仍有 BOOTSTRAP.md:本会话先做短问三拍,沉淀到 PRIORITIES.md / MEMORY.md,然后删除 BOOTSTRAP.md。',
|
|
24
25
|
'已初始化后:读 PRIORITIES.md + MEMORY.md + 今日/昨日 memory/;老板三室回答固定四行:结论 → 数字(哪家公司、哪段时间)→ 拍板 1~3 件事 → 未执行任何过账/付款/对外发送。',
|
|
25
26
|
'微信文件夹仍是收件箱,不要在那边查账、报销或砍 SKU。',
|
|
27
|
+
'用户用中文就中文、用英文就英文;不要因为工作区文件是中文就强制中文。',
|
|
26
28
|
].join('')
|
|
27
29
|
|
|
28
30
|
export const BOSS_ROLE_HINT = '搞钱 / 产品 / 运营仅角色选「老板」时出现。人事 / 财务 / 法务助理所有角色都会登记。'
|
|
Binary file
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Cropped circular R from Nextcloud MKT_brand/VI/2.png (transparent).
|
|
2
|
+
* Do not edit by hand — regenerate from src/client/assets/rez-mark.png.
|
|
3
|
+
*/
|
|
4
|
+
export const REZ_MARK_DATA_URL = 'data:image/png;base64,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'
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Light overlay on official BrandWordmark / FishLogo. Colors follow Host tokens.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
.wordmark {
|
|
6
|
+
display: inline-flex;
|
|
7
|
+
align-items: center;
|
|
8
|
+
gap: 8px;
|
|
9
|
+
min-width: 0;
|
|
10
|
+
color: inherit;
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.mark {
|
|
15
|
+
width: 28px;
|
|
16
|
+
height: 28px;
|
|
17
|
+
flex: none;
|
|
18
|
+
object-fit: contain;
|
|
19
|
+
display: block;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.markOnly {
|
|
23
|
+
width: 100%;
|
|
24
|
+
height: 100%;
|
|
25
|
+
max-width: 28px;
|
|
26
|
+
max-height: 28px;
|
|
27
|
+
object-fit: contain;
|
|
28
|
+
display: block;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.name {
|
|
32
|
+
font-weight: 650;
|
|
33
|
+
font-size: 15px;
|
|
34
|
+
letter-spacing: 0.02em;
|
|
35
|
+
white-space: nowrap;
|
|
36
|
+
overflow: hidden;
|
|
37
|
+
text-overflow: ellipsis;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.badge {
|
|
41
|
+
flex: none;
|
|
42
|
+
font-size: 10px;
|
|
43
|
+
font-weight: 700;
|
|
44
|
+
letter-spacing: 0.06em;
|
|
45
|
+
line-height: 1.2;
|
|
46
|
+
padding: 2px 6px;
|
|
47
|
+
border-radius: 4px;
|
|
48
|
+
border: 1px solid currentColor;
|
|
49
|
+
opacity: 0.72;
|
|
50
|
+
white-space: nowrap;
|
|
51
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Official DSH has no brand slot: ui-sidebar paints BrandWordmark, the empty
|
|
3
|
+
* hero paints FishLogo + a fixed headline. Replacing the whole sidebar or
|
|
4
|
+
* the center column would drop their inner seats. This overlay swaps only
|
|
5
|
+
* those two SVGs and the known headline strings.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'
|
|
9
|
+
import { REZ_MARK_DATA_URL } from './brand-mark.ts'
|
|
10
|
+
import css from './brand.module.css'
|
|
11
|
+
|
|
12
|
+
/** Official BrandWordmark viewBox (182:24 wordmark). */
|
|
13
|
+
export const WORDMARK_VIEWBOX = '0 0 182 24'
|
|
14
|
+
/** Official FishLogo viewBox. */
|
|
15
|
+
export const FISH_VIEWBOX = '0 0 23.16 17.04'
|
|
16
|
+
/** Official empty-hero headlines we replace. */
|
|
17
|
+
export const OFFICIAL_HEADLINES = ['探索未至之境', 'Into the Unknown'] as const
|
|
18
|
+
|
|
19
|
+
function normViewBox(value: string | null): string {
|
|
20
|
+
return (value ?? '').trim().replace(/\s+/g, ' ')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function alreadyBranded(node: Node): boolean {
|
|
24
|
+
const el = node instanceof Element ? node : node.parentElement
|
|
25
|
+
return el?.closest('[data-rez-brand]') != null
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function markImg(kind: 'wordmark' | 'icon', className: string): HTMLImageElement {
|
|
29
|
+
const img = document.createElement('img')
|
|
30
|
+
img.src = REZ_MARK_DATA_URL
|
|
31
|
+
img.alt = ''
|
|
32
|
+
img.draggable = false
|
|
33
|
+
img.className = className
|
|
34
|
+
img.setAttribute('data-rez-brand', kind)
|
|
35
|
+
return img
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function paintWordmark(svg: SVGSVGElement, t: TranslateNS<'dsh-rez-suite'>): void {
|
|
39
|
+
const parent = svg.parentNode
|
|
40
|
+
if (parent === null || alreadyBranded(svg)) return
|
|
41
|
+
const row = document.createElement('span')
|
|
42
|
+
row.className = css.wordmark
|
|
43
|
+
row.setAttribute('data-rez-brand', 'wordmark')
|
|
44
|
+
row.setAttribute('aria-label', t('brand.wordmarkAria'))
|
|
45
|
+
const name = document.createElement('span')
|
|
46
|
+
name.className = css.name
|
|
47
|
+
name.textContent = t('brand.name')
|
|
48
|
+
const badge = document.createElement('span')
|
|
49
|
+
badge.className = css.badge
|
|
50
|
+
badge.textContent = t('brand.badge')
|
|
51
|
+
row.append(markImg('wordmark', css.mark), name, badge)
|
|
52
|
+
parent.replaceChild(row, svg)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function paintFish(svg: SVGSVGElement): void {
|
|
56
|
+
const parent = svg.parentNode
|
|
57
|
+
if (parent === null || alreadyBranded(svg)) return
|
|
58
|
+
const wrap = document.createElement('span')
|
|
59
|
+
wrap.setAttribute('data-rez-brand', 'icon')
|
|
60
|
+
wrap.style.display = 'inline-flex'
|
|
61
|
+
wrap.style.alignItems = 'center'
|
|
62
|
+
wrap.style.justifyContent = 'center'
|
|
63
|
+
const width = svg.getAttribute('width')
|
|
64
|
+
const height = svg.getAttribute('height')
|
|
65
|
+
if (width) wrap.style.width = /px$/.test(width) ? width : `${width}px`
|
|
66
|
+
if (height) wrap.style.height = /px$/.test(height) ? height : `${height}px`
|
|
67
|
+
wrap.append(markImg('icon', css.markOnly))
|
|
68
|
+
parent.replaceChild(wrap, svg)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function paintHeadline(el: Element, t: TranslateNS<'dsh-rez-suite'>): void {
|
|
72
|
+
el.setAttribute('data-rez-brand', 'headline')
|
|
73
|
+
el.textContent = t('brand.headline')
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function refreshCopy(root: ParentNode, t: TranslateNS<'dsh-rez-suite'>): void {
|
|
77
|
+
for (const row of root.querySelectorAll('[data-rez-brand="wordmark"]')) {
|
|
78
|
+
const name = row.querySelector(`.${css.name}`)
|
|
79
|
+
const badge = row.querySelector(`.${css.badge}`)
|
|
80
|
+
if (name) name.textContent = t('brand.name')
|
|
81
|
+
if (badge) badge.textContent = t('brand.badge')
|
|
82
|
+
row.setAttribute('aria-label', t('brand.wordmarkAria'))
|
|
83
|
+
}
|
|
84
|
+
for (const el of root.querySelectorAll('[data-rez-brand="headline"]')) {
|
|
85
|
+
el.textContent = t('brand.headline')
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function paintBrand(root: ParentNode, t: TranslateNS<'dsh-rez-suite'>): void {
|
|
90
|
+
refreshCopy(root, t)
|
|
91
|
+
const svgs = root.querySelectorAll('svg[aria-hidden="true"]')
|
|
92
|
+
for (const node of svgs) {
|
|
93
|
+
if (!(node instanceof SVGSVGElement)) continue
|
|
94
|
+
const box = normViewBox(node.getAttribute('viewBox'))
|
|
95
|
+
if (box === WORDMARK_VIEWBOX) paintWordmark(node, t)
|
|
96
|
+
else if (box === FISH_VIEWBOX) paintFish(node)
|
|
97
|
+
}
|
|
98
|
+
const doc = root instanceof Document ? root : root.ownerDocument
|
|
99
|
+
if (doc === null) return
|
|
100
|
+
const walker = doc.createTreeWalker(root as Node, NodeFilter.SHOW_TEXT)
|
|
101
|
+
const headlines: Text[] = []
|
|
102
|
+
while (walker.nextNode()) {
|
|
103
|
+
const text = walker.currentNode as Text
|
|
104
|
+
const value = text.data.trim()
|
|
105
|
+
if ((OFFICIAL_HEADLINES as readonly string[]).includes(value)) headlines.push(text)
|
|
106
|
+
}
|
|
107
|
+
for (const text of headlines) {
|
|
108
|
+
const host = text.parentElement
|
|
109
|
+
if (host) paintHeadline(host, t)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function mountRezBrand(t: TranslateNS<'dsh-rez-suite'>): () => void {
|
|
114
|
+
if (typeof document === 'undefined') return () => undefined
|
|
115
|
+
let frame = 0
|
|
116
|
+
const run = (): void => {
|
|
117
|
+
frame = 0
|
|
118
|
+
paintBrand(document, t)
|
|
119
|
+
}
|
|
120
|
+
const schedule = (): void => {
|
|
121
|
+
if (frame !== 0) return
|
|
122
|
+
frame = requestAnimationFrame(run)
|
|
123
|
+
}
|
|
124
|
+
run()
|
|
125
|
+
const observer = new MutationObserver(schedule)
|
|
126
|
+
observer.observe(document.documentElement, {
|
|
127
|
+
childList: true,
|
|
128
|
+
subtree: true,
|
|
129
|
+
characterData: true,
|
|
130
|
+
})
|
|
131
|
+
return () => {
|
|
132
|
+
observer.disconnect()
|
|
133
|
+
if (frame !== 0) cancelAnimationFrame(frame)
|
|
134
|
+
}
|
|
135
|
+
}
|
package/src/client/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'
|
|
|
9
9
|
import type {} from '@deepseek-ai/dsh-client-locale/client'
|
|
10
10
|
import type {} from '@deepseek-ai/dsh-client-ui-settings/client'
|
|
11
11
|
import type {} from '@deepseek-ai/dsh-client-ui-slots'
|
|
12
|
+
import { mountRezBrand, paintBrand } from './brand.ts'
|
|
12
13
|
import { en, zh, type RezKey } from './locales.ts'
|
|
13
14
|
import { RezPluginCard, RezSettingsPage } from './settings-card.tsx'
|
|
14
15
|
import { UpgradeButton } from './upgrade-button.tsx'
|
|
@@ -45,6 +46,16 @@ export type { RezKey } from './locales.ts'
|
|
|
45
46
|
export function apply(ctx: ClientContext): void {
|
|
46
47
|
const t = ctx.locale.bind(NS)
|
|
47
48
|
ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-rez-suite: dictionaries')
|
|
49
|
+
ctx.effect(() => {
|
|
50
|
+
const stop = mountRezBrand(t)
|
|
51
|
+
const unsub = ctx.locale.subscribe(() => {
|
|
52
|
+
if (typeof document !== 'undefined') paintBrand(document, t)
|
|
53
|
+
})
|
|
54
|
+
return () => {
|
|
55
|
+
unsub()
|
|
56
|
+
stop()
|
|
57
|
+
}
|
|
58
|
+
}, 'dsh-rez-suite: brand')
|
|
48
59
|
|
|
49
60
|
ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({
|
|
50
61
|
name: 'settings.plugin.item',
|
package/src/client/locales.ts
CHANGED
|
@@ -52,6 +52,9 @@ export const zh = {
|
|
|
52
52
|
'config.gsc': 'Google Search Console',
|
|
53
53
|
'config.gsc.siteUrl': '站点 URL',
|
|
54
54
|
'config.gsc.key': '服务账号 JSON 或密钥文件路径',
|
|
55
|
+
'config.tianyancha': '天眼查(法务助理 · 仅老板)',
|
|
56
|
+
'config.tianyancha.url': '天眼查 MCP URL',
|
|
57
|
+
'config.tianyancha.token': 'OpenAPI Token',
|
|
55
58
|
'config.fs': '本地文件 (fs-mcp-server)',
|
|
56
59
|
'config.fs.root': '根目录',
|
|
57
60
|
'config.sqlite': 'SQLite (sqlite-mcp-server)',
|
|
@@ -118,6 +121,10 @@ export const zh = {
|
|
|
118
121
|
'upgrade.reloading': '正在重载',
|
|
119
122
|
'upgrade.already': '已是 {version}',
|
|
120
123
|
'upgrade.reloadTimeout': '升级完成,但网页还没重新连上。请刷新这一页。',
|
|
124
|
+
'brand.name': '雷泽智能',
|
|
125
|
+
'brand.badge': '定制版',
|
|
126
|
+
'brand.headline': '雷泽智能定制版',
|
|
127
|
+
'brand.wordmarkAria': '雷泽智能定制版',
|
|
121
128
|
} as const
|
|
122
129
|
|
|
123
130
|
export type RezKey = keyof typeof zh
|
|
@@ -171,6 +178,9 @@ export const en: Record<RezKey, string> = {
|
|
|
171
178
|
'config.gsc': 'Google Search Console',
|
|
172
179
|
'config.gsc.siteUrl': 'Site URL',
|
|
173
180
|
'config.gsc.key': 'Service-account JSON or key file path',
|
|
181
|
+
'config.tianyancha': 'Tianyancha (Legal assistant, boss only)',
|
|
182
|
+
'config.tianyancha.url': 'Tianyancha MCP URL',
|
|
183
|
+
'config.tianyancha.token': 'OpenAPI token',
|
|
174
184
|
'config.fs': 'Local files (fs-mcp-server)',
|
|
175
185
|
'config.fs.root': 'Root directory',
|
|
176
186
|
'config.sqlite': 'SQLite (sqlite-mcp-server)',
|
|
@@ -234,6 +244,10 @@ export const en: Record<RezKey, string> = {
|
|
|
234
244
|
'upgrade.reloading': 'Reloading',
|
|
235
245
|
'upgrade.already': 'Already {version}',
|
|
236
246
|
'upgrade.reloadTimeout': 'Update finished, but the page did not reconnect. Refresh this tab.',
|
|
247
|
+
'brand.name': 'ReZ-TI',
|
|
248
|
+
'brand.badge': 'Custom',
|
|
249
|
+
'brand.headline': 'ReZ-TI Custom Edition',
|
|
250
|
+
'brand.wordmarkAria': 'ReZ-TI Custom Edition',
|
|
237
251
|
}
|
|
238
252
|
|
|
239
253
|
/** Minimal {name} interpolator shared by the panel helpers. */
|