@rezti/dsh-rez-suite 0.1.52 → 0.1.55
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/CHANGELOG.md +14 -2
- package/README.md +3 -3
- package/README.zh.md +1 -1
- package/cordis.patch.yml +1 -1
- package/lib/client.js +42 -0
- package/lib/index.js +69 -14
- package/package.json +4 -3
- package/src/boss/mount.ts +1 -1
- package/src/changelog.ts +45 -0
- package/src/index.ts +3 -0
- package/src/wecom-cli.ts +81 -12
- package/templates/shared/staff-identity/SKILL.md +25 -0
- package/templates/shared/wecom-cli.SOURCE.md +1 -1
- package/templates/shared/wecom-office/SKILL.md +1 -1
- package/templates/shared/wecomcli-shared/SKILL.md +8 -7
- package/templates/staff/finance/.agents/skills/staff-finance/SKILL.md +2 -2
- package/templates/staff/finance/AGENTS.md +15 -14
- package/templates/staff/finance/BOOTSTRAP.md +1 -1
- package/templates/staff/finance/IDENTITY.md +2 -2
- package/templates/staff/finance/SOUL.md +1 -1
- package/templates/staff/hr/.agents/skills/staff-hr/SKILL.md +2 -2
- package/templates/staff/hr/AGENTS.md +19 -13
- package/templates/staff/hr/BOOTSTRAP.md +1 -1
- package/templates/staff/hr/IDENTITY.md +2 -2
- package/templates/staff/hr/SOUL.md +1 -1
- package/templates/staff/legal/.agents/skills/staff-legal/SKILL.md +2 -2
- package/templates/staff/legal/AGENTS.md +13 -11
- package/templates/staff/legal/IDENTITY.md +2 -2
- package/templates/staff/legal/SOUL.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,12 +5,24 @@
|
|
|
5
5
|
升级:
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
dsh plugin --profile web add @rezti/dsh-rez-suite@0.1.
|
|
8
|
+
dsh plugin --profile web add @rezti/dsh-rez-suite@0.1.55
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
不要用裸 `plugin update`,不要写 `latest`(新 profile 有 24 小时发布冷却,当天可能装不上)。不要装 **0.1.46**(GitHub 子依赖会被 DSH 拦住)。不要装 **0.1.51**(误用 `npm publish` 把 `workspace:` 打进包了)。
|
|
12
12
|
|
|
13
|
-
发版顺序:`wechat@0.1.
|
|
13
|
+
发版顺序:`wechat@0.1.17` → `suite@0.1.55`。**必须用 `pnpm publish`**(会把 `workspace:` 写成真实版本),不要用 `npm publish`。
|
|
14
|
+
|
|
15
|
+
## 0.1.55 — 2026-08-21
|
|
16
|
+
|
|
17
|
+
- **企微单聊语音当文字**:官方智能机器人已把语音转成 `voice.content`,通道按普通文字送进房间。个人微信不改。群聊语音官方不保证有转写。不改员工机安装包。
|
|
18
|
+
|
|
19
|
+
## 0.1.54 — 2026-08-21
|
|
20
|
+
|
|
21
|
+
- **人财法按组织架构分权**:开场用 Odoo login 对 Nextcloud `Documents/Standards/org/chart.yaml`。身份只有老板 / 员工 / 雷泽AI助手。人事助理认「我 / 人事 / 其他人」。能力矩阵 `org/identity.md`。不改员工机安装包。
|
|
22
|
+
|
|
23
|
+
## 0.1.53 — 2026-08-20
|
|
24
|
+
|
|
25
|
+
- **suite 自带 `@wecom/cli@1.1.0`**:装 suite 即带办公 CLI(含 `mail`)。启动时把其 bin 插到 PATH 最前,避开 Homebrew 全局 `0.1.9`。房间消息仍设置页 BotID+Secret;办公授权仍 `wecom-cli auth init`(可扫码)。
|
|
14
26
|
|
|
15
27
|
## 0.1.52 — 2026-08-20
|
|
16
28
|
|
package/README.md
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
雷泽插件的**唯一安装入口**。Odoo / 企微 / HA / TAPD / GSC / 企查查(仅法务助理房间) / 天眼查(仅老板) / 工作区(老板三室 + 全员助理)都由这一包拉齐,不要再逐个 `plugin add`,**不要**再装 `@rezti/dsh-rez-boss-desk`。
|
|
4
4
|
|
|
5
|
-
发版顺序(必做):先发 `@rezti/dsh-rez-wechat@0.1.
|
|
5
|
+
发版顺序(必做):先发 `@rezti/dsh-rez-wechat@0.1.17` → `@rezti/dsh-rez-suite@0.1.55`。**发 suite 必须用 `pnpm publish`**(会把 `workspace:` 写成真实版本),不要用 `npm publish`。员工机安装包仍钉已发布的 suite,不要顺手改审批镜像 `SUITE_VERSION`。
|
|
6
6
|
|
|
7
7
|
设置里选身份后,左侧自己出现对应房间(全员三助理;工程师另加实验室;运营另加设计、发布、电商;老板另加搞钱/产品/运营),不必手动添加工作区。实验室:大模型写 YAML、调 MCP、给下载链接。
|
|
8
8
|
|
|
9
|
-
回形针走 npm 包 `@rezti/dsh-web-file-uploader@0.2.3`(不要 GitHub:DSH 会拦子依赖 git,0.1.46 因此装不上)。
|
|
9
|
+
回形针走 npm 包 `@rezti/dsh-web-file-uploader@0.2.3`(不要 GitHub:DSH 会拦子依赖 git,0.1.46 因此装不上)。suite 自带 `@wecom/cli@1.1.0`(企微办公;不要依赖 Homebrew 全局 0.1.x)。
|
|
10
10
|
|
|
11
11
|
员工机不要 `SUITE_VERSION=latest`:新 profile 默认 `minimumReleaseAge: 1440`,当天发的包可能装不到。钉死版本,或把 profile 的 `minimumReleaseAge` 改成 `0`。
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
# 第一次 / 升级(钉死版本,避开 24h 发布冷却)
|
|
15
|
-
dsh plugin --profile web add @rezti/dsh-rez-suite@0.1.
|
|
15
|
+
dsh plugin --profile web add @rezti/dsh-rez-suite@0.1.55
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
本版改了什么:见 [CHANGELOG.md](./CHANGELOG.md)。
|
package/README.zh.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# dsh-rez-suite
|
|
2
2
|
|
|
3
|
-
**用户只装这一包。** 升级只记:`dsh plugin --profile web add @rezti/dsh-rez-suite@0.1.
|
|
3
|
+
**用户只装这一包。** 升级只记:`dsh plugin --profile web add @rezti/dsh-rez-suite@0.1.55`(不要用裸 `update`;不要 latest;不要 0.1.46 / 0.1.47 / 0.1.51)。本版改了什么见 [CHANGELOG.md](./CHANGELOG.md)。拆分包给开发改代码;不要对同一 profile 再单独 add 子包。
|
|
4
4
|
|
|
5
5
|
说明书 / 规格书用输入栏**回形针**上传原 PDF(官方对话只收图,不要拖文件;不要用微信发 PDF)。先入 `Marketing/Inbox` + TAPD 测试中,凯文跟 Harness 说审批了哪份后,再写入 `Marketing/Publish/…`。
|
|
6
6
|
|
package/cordis.patch.yml
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# 用户只装这一包:`dsh plugin --profile web add @rezti/dsh-rez-suite`
|
|
2
|
-
# 升级只记这一条:`dsh plugin --profile web add @rezti/dsh-rez-suite@0.1.
|
|
2
|
+
# 升级只记这一条:`dsh plugin --profile web add @rezti/dsh-rez-suite@0.1.55`
|
|
3
3
|
# 不要再单独 add 子包,会重复注册。
|
|
4
4
|
#
|
|
5
5
|
# MCP rows are started by the domain plugins after rezSso resolves secrets.
|
package/lib/client.js
CHANGED
|
@@ -994,6 +994,48 @@ function ChannelTable({ kind, lang }) {
|
|
|
994
994
|
//#endregion
|
|
995
995
|
//#region src/changelog.ts
|
|
996
996
|
const SUITE_CHANGELOG = [
|
|
997
|
+
{
|
|
998
|
+
version: "0.1.55",
|
|
999
|
+
date: "2026-08-21",
|
|
1000
|
+
sections: [{
|
|
1001
|
+
title: {
|
|
1002
|
+
zh: "企微单聊语音当文字",
|
|
1003
|
+
en: "WeCom voice as text"
|
|
1004
|
+
},
|
|
1005
|
+
items: [{
|
|
1006
|
+
zh: "企业微信智能机器人单聊语音走官方转写(voice.content),当普通文字进房间。个人微信不改。群聊语音官方不保证有转写。不改员工机安装包。",
|
|
1007
|
+
en: "WeCom AI-bot single-chat voice uses the official transcription (voice.content) as room text. Personal WeChat is unchanged. Group voice is not guaranteed. Do not bump the installer."
|
|
1008
|
+
}]
|
|
1009
|
+
}]
|
|
1010
|
+
},
|
|
1011
|
+
{
|
|
1012
|
+
version: "0.1.54",
|
|
1013
|
+
date: "2026-08-21",
|
|
1014
|
+
sections: [{
|
|
1015
|
+
title: {
|
|
1016
|
+
zh: "人财法按组织架构分权",
|
|
1017
|
+
en: "Staff rooms use org chart"
|
|
1018
|
+
},
|
|
1019
|
+
items: [{
|
|
1020
|
+
zh: "人事/财务/法务开场用 Odoo login 对 Nextcloud 组织架构。身份只有老板、员工、雷泽AI助手。人事助理认「我 / 人事 / 其他人」。不改员工机安装包。",
|
|
1021
|
+
en: "HR/Finance/Legal rooms match Odoo login to the Nextcloud org chart. Identities are boss, employee, and Rez AI assistant. HR tells 我 / 人事 / 其他人 apart. Do not bump the installer."
|
|
1022
|
+
}]
|
|
1023
|
+
}]
|
|
1024
|
+
},
|
|
1025
|
+
{
|
|
1026
|
+
version: "0.1.53",
|
|
1027
|
+
date: "2026-08-20",
|
|
1028
|
+
sections: [{
|
|
1029
|
+
title: {
|
|
1030
|
+
zh: "自带 wecom-cli 1.1",
|
|
1031
|
+
en: "Bundled wecom-cli 1.1"
|
|
1032
|
+
},
|
|
1033
|
+
items: [{
|
|
1034
|
+
zh: "suite 依赖 @wecom/cli@1.1.0,装插件即带 mail/auth。PATH 优先用 profile 里的二进制,避开 Homebrew 0.1.9。房间仍 BotID+Secret;办公 auth init 可扫码。",
|
|
1035
|
+
en: "Suite depends on @wecom/cli@1.1.0 (mail/auth). Prefers the profile binary over Homebrew 0.1.9. Room bots still BotID+Secret; office auth init can QR."
|
|
1036
|
+
}]
|
|
1037
|
+
}]
|
|
1038
|
+
},
|
|
997
1039
|
{
|
|
998
1040
|
version: "0.1.52",
|
|
999
1041
|
date: "2026-08-20",
|
package/lib/index.js
CHANGED
|
@@ -4,8 +4,8 @@ import { dirname, join, relative } from "node:path";
|
|
|
4
4
|
import { REZ_CREDENTIAL_REFS, REZ_DEFAULT_CONNECTIONS, REZ_SYSTEMS, lastMcpStartError, loadRezConnections, mergeConnections, readManagedCredential, 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 { spawn, spawnSync } from "node:child_process";
|
|
7
|
-
import { DatabaseSync } from "node:sqlite";
|
|
8
7
|
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { DatabaseSync } from "node:sqlite";
|
|
9
9
|
//#region ../../node_modules/.pnpm/@deepseek-ai+cosmokit@1.8.2/node_modules/@deepseek-ai/cosmokit/lib/index.js
|
|
10
10
|
/** Return true when a value is `null` or `undefined`. */
|
|
11
11
|
function isNullable(value) {
|
|
@@ -3236,6 +3236,9 @@ function saveConfig(config) {
|
|
|
3236
3236
|
* TAPD bug 1154488930001000054: missing MCP row was treated as “no WeCom”.
|
|
3237
3237
|
* Official CLI v1.1+ opened 通讯录 / 在线文档 etc. for every company size
|
|
3238
3238
|
* (https://github.com/WecomTeam/wecom-cli). Kelvin enabled those modules.
|
|
3239
|
+
*
|
|
3240
|
+
* Suite depends on @wecom/cli@1.1.0 so the profile gets a modern binary.
|
|
3241
|
+
* Prefer that over a global Homebrew 0.1.x that lacks `mail` / `auth`.
|
|
3239
3242
|
*/
|
|
3240
3243
|
/** Official @wecom/cli >=1.1 catalog. Do not invent extra HTTP APIs. */
|
|
3241
3244
|
const WECOM_CLI_CATALOG = [
|
|
@@ -3294,18 +3297,22 @@ const WECOM_CLI_CATALOG = [
|
|
|
3294
3297
|
];
|
|
3295
3298
|
const MODULE_LABELS = WECOM_CLI_CATALOG.map((row) => row.label).join("/");
|
|
3296
3299
|
const HINT_MISSING = [
|
|
3297
|
-
|
|
3298
|
-
"
|
|
3299
|
-
"
|
|
3300
|
-
|
|
3300
|
+
`未找到可用的 wecom-cli >=1.1(企微办公:${MODULE_LABELS})。`,
|
|
3301
|
+
"suite 已依赖 @wecom/cli@1.1.0:请重装 @rezti/dsh-rez-suite,或确认 profile 的 node_modules 里有 @wecom/cli。",
|
|
3302
|
+
"不要用 Homebrew 全局 0.1.x(没有 mail/auth)。不要因为没有 wechat MCP 就说没有企微能力。"
|
|
3303
|
+
].join("");
|
|
3304
|
+
const HINT_OUTDATED = [
|
|
3305
|
+
"PATH 上的 wecom-cli 过旧(<1.1,没有 mail 等子命令)。",
|
|
3306
|
+
"请用 suite 自带的 @wecom/cli@1.1.0:重装 suite,或把 profile node_modules/.bin 放在 PATH 最前。",
|
|
3307
|
+
"不要 npm i -g 覆盖到旧 Homebrew 路径前面仍是 0.1.9。"
|
|
3301
3308
|
].join("");
|
|
3302
3309
|
const HINT_UNAUTH = [
|
|
3303
|
-
"已安装 wecom-cli,尚未授权。跑 wecom-cli auth init
|
|
3310
|
+
"已安装 wecom-cli >=1.1,尚未授权。跑 wecom-cli auth init(可扫码)。",
|
|
3304
3311
|
`授权后可用:${MODULE_LABELS}。本企业已开通这些品类。`,
|
|
3305
3312
|
"CLI 报某模块未授权才说该能力未开通;不要说「没有企微 MCP」,也不要说 10 人限制。"
|
|
3306
3313
|
].join("");
|
|
3307
3314
|
const HINT_OK = [
|
|
3308
|
-
`企微办公能力走 wecom-cli >=1.1(${MODULE_LABELS}
|
|
3315
|
+
`企微办公能力走 wecom-cli >=1.1(${MODULE_LABELS})。本企业已开通。suite 已带 @wecom/cli。`,
|
|
3309
3316
|
"按房间里官方 wecomcli-* 技能执行,命令以 wecom-cli <模块> --help 为准。",
|
|
3310
3317
|
"不要用旧帮助中心「超过 10 人只能用文档」的说法。CLI 报未授权才说该模块未开通。",
|
|
3311
3318
|
"设置页 BotID+Secret 只是房间消息通道。不要把没有 mcp__wechat__* 当成没有企微能力。"
|
|
@@ -3313,8 +3320,32 @@ const HINT_OK = [
|
|
|
3313
3320
|
function wecomCliCatalog() {
|
|
3314
3321
|
return WECOM_CLI_CATALOG.map((row) => ({ ...row }));
|
|
3315
3322
|
}
|
|
3323
|
+
/** Resolve suite-bundled @wecom/cli binary; undefined if not installed next to suite. */
|
|
3324
|
+
function resolveWecomCliBin() {
|
|
3325
|
+
const require = createRequire(import.meta.url);
|
|
3326
|
+
try {
|
|
3327
|
+
const bin = join(dirname(require.resolve("@wecom/cli/package.json")), "bin", "wecom.js");
|
|
3328
|
+
if (existsSync(bin)) return bin;
|
|
3329
|
+
} catch {}
|
|
3330
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
3331
|
+
for (const candidate of [
|
|
3332
|
+
join(here, "..", "node_modules", "@wecom", "cli", "bin", "wecom.js"),
|
|
3333
|
+
join(here, "..", "..", "node_modules", "@wecom", "cli", "bin", "wecom.js"),
|
|
3334
|
+
join(here, "..", "..", "..", "node_modules", "@wecom", "cli", "bin", "wecom.js")
|
|
3335
|
+
]) if (existsSync(candidate)) return candidate;
|
|
3336
|
+
}
|
|
3337
|
+
/** Put suite-bundled wecom-cli ahead of global Homebrew 0.1.x on PATH. */
|
|
3338
|
+
function ensureWecomCliOnPath() {
|
|
3339
|
+
const bin = resolveWecomCliBin();
|
|
3340
|
+
if (bin === void 0) return void 0;
|
|
3341
|
+
const dir = dirname(bin);
|
|
3342
|
+
const pathKey = process.platform === "win32" ? "Path" : "PATH";
|
|
3343
|
+
const parts = (process.env[pathKey] ?? "").split(process.platform === "win32" ? ";" : ":").filter(Boolean);
|
|
3344
|
+
if (parts[0] !== dir) process.env[pathKey] = [dir, ...parts.filter((p) => p !== dir)].join(process.platform === "win32" ? ";" : ":");
|
|
3345
|
+
return bin;
|
|
3346
|
+
}
|
|
3316
3347
|
function defaultWecomCliRunner(argv) {
|
|
3317
|
-
const result = spawnSync("wecom-cli", argv, {
|
|
3348
|
+
const result = spawnSync(resolveWecomCliBin() ?? "wecom-cli", argv, {
|
|
3318
3349
|
encoding: "utf8",
|
|
3319
3350
|
timeout: 4e3,
|
|
3320
3351
|
env: process.env
|
|
@@ -3331,6 +3362,15 @@ function looksUnauthorized(text, status) {
|
|
|
3331
3362
|
if (status !== 0) return true;
|
|
3332
3363
|
return /未授权|未登录|未初始化|not (logged|auth)|unauthorized|请先.*auth|auth init/i.test(text);
|
|
3333
3364
|
}
|
|
3365
|
+
/** 0.1.x has no mail; 1.1 help lists mail. */
|
|
3366
|
+
function isWecomCliModern(helpOrVersionText) {
|
|
3367
|
+
const text = helpOrVersionText.toLowerCase();
|
|
3368
|
+
if (/\b0\.1\.\d+\b/.test(text) && !/\b1\.\d+\.\d+\b/.test(text)) return false;
|
|
3369
|
+
if (/\bunrecognized subcommand\b/.test(text)) return false;
|
|
3370
|
+
if (/\bmail\b/.test(text)) return true;
|
|
3371
|
+
if (/\b1\.\d+\.\d+\b/.test(text) || /wecom-cli\s*\(?\s*1\./i.test(helpOrVersionText)) return true;
|
|
3372
|
+
return false;
|
|
3373
|
+
}
|
|
3334
3374
|
function withCatalog(partial) {
|
|
3335
3375
|
return {
|
|
3336
3376
|
...partial,
|
|
@@ -3338,34 +3378,48 @@ function withCatalog(partial) {
|
|
|
3338
3378
|
};
|
|
3339
3379
|
}
|
|
3340
3380
|
function probeWecomCli(run = defaultWecomCliRunner) {
|
|
3381
|
+
const bin = resolveWecomCliBin();
|
|
3341
3382
|
const help = run(["--help"]);
|
|
3342
3383
|
if (help.errorCode === "ENOENT") return withCatalog({
|
|
3343
3384
|
installed: false,
|
|
3344
3385
|
authorized: false,
|
|
3345
|
-
hint: HINT_MISSING
|
|
3386
|
+
hint: HINT_MISSING,
|
|
3387
|
+
bin
|
|
3346
3388
|
});
|
|
3347
3389
|
const helpText = help.stdout + help.stderr;
|
|
3348
3390
|
if (help.status !== 0 && helpText.trim().length === 0) return withCatalog({
|
|
3349
3391
|
installed: false,
|
|
3350
3392
|
authorized: false,
|
|
3351
|
-
hint: HINT_MISSING
|
|
3393
|
+
hint: HINT_MISSING,
|
|
3394
|
+
bin
|
|
3395
|
+
});
|
|
3396
|
+
const version = run(["--version"]);
|
|
3397
|
+
const versionText = version.stdout + version.stderr;
|
|
3398
|
+
if (!isWecomCliModern(helpText + "\n" + versionText)) return withCatalog({
|
|
3399
|
+
installed: false,
|
|
3400
|
+
authorized: false,
|
|
3401
|
+
hint: HINT_OUTDATED,
|
|
3402
|
+
bin
|
|
3352
3403
|
});
|
|
3353
3404
|
const auth = run(["auth", "show"]);
|
|
3354
3405
|
const text = auth.stdout + auth.stderr;
|
|
3355
3406
|
if (auth.errorCode === "ENOENT") return withCatalog({
|
|
3356
3407
|
installed: false,
|
|
3357
3408
|
authorized: false,
|
|
3358
|
-
hint: HINT_MISSING
|
|
3409
|
+
hint: HINT_MISSING,
|
|
3410
|
+
bin
|
|
3359
3411
|
});
|
|
3360
3412
|
if (looksUnauthorized(text, auth.status)) return withCatalog({
|
|
3361
3413
|
installed: true,
|
|
3362
3414
|
authorized: false,
|
|
3363
|
-
hint: HINT_UNAUTH
|
|
3415
|
+
hint: HINT_UNAUTH,
|
|
3416
|
+
bin
|
|
3364
3417
|
});
|
|
3365
3418
|
return withCatalog({
|
|
3366
3419
|
installed: true,
|
|
3367
3420
|
authorized: true,
|
|
3368
|
-
hint: HINT_OK
|
|
3421
|
+
hint: HINT_OK,
|
|
3422
|
+
bin
|
|
3369
3423
|
});
|
|
3370
3424
|
}
|
|
3371
3425
|
//#endregion
|
|
@@ -8419,7 +8473,7 @@ function listFiles(root) {
|
|
|
8419
8473
|
//#region src/boss/mount.ts
|
|
8420
8474
|
const STAFF_GUIDANCE = [
|
|
8421
8475
|
"侧栏已登记人事助理 / 财务助理 / 法务助理。装完、选身份后自动出现,不必手动「添加工作区」、也不必拖排序。",
|
|
8422
|
-
"
|
|
8476
|
+
"三个助理给所有人用。开场用 Odoo 帐号对 Nextcloud 组织架构(老板 / 员工);本室助手永远是雷泽AI助手。能做什么看身份能力矩阵 + Odoo 可视范围;Harness 只列选项,不自审、不自过账。",
|
|
8423
8477
|
"报销走财务助理。搞钱室是战略数字,不要在助理房间里做。",
|
|
8424
8478
|
"用户用中文就中文、用英文就英文;不要因为工作区文件是中文就强制中文。"
|
|
8425
8479
|
].join("");
|
|
@@ -8911,6 +8965,7 @@ function delegatedHost(ctx, getConfig) {
|
|
|
8911
8965
|
};
|
|
8912
8966
|
}
|
|
8913
8967
|
function apply(ctx, config) {
|
|
8968
|
+
ensureWecomCliOnPath();
|
|
8914
8969
|
let current = () => normalize(config);
|
|
8915
8970
|
const syncWorkspaces = mountRezWorkspaces(ctx, () => current().role);
|
|
8916
8971
|
const syncQcc = mountQccMcp(ctx);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rezti/dsh-rez-suite",
|
|
3
|
-
"description": "ReZ-TI one-package install for DeepSeek Harness. Update with: dsh plugin --profile web add @rezti/dsh-rez-suite@0.1.
|
|
4
|
-
"version": "0.1.
|
|
3
|
+
"description": "ReZ-TI one-package install for DeepSeek Harness. Update with: dsh plugin --profile web add @rezti/dsh-rez-suite@0.1.55",
|
|
4
|
+
"version": "0.1.55",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": "^22.19.0 || >=24.0.0"
|
|
@@ -45,8 +45,9 @@
|
|
|
45
45
|
"@rezti/dsh-rez-sso": "^0.1.14",
|
|
46
46
|
"@rezti/dsh-rez-tapd": "^0.1.1",
|
|
47
47
|
"@rezti/dsh-rez-token-manager": "^0.1.4",
|
|
48
|
-
"@rezti/dsh-rez-wechat": "^0.1.
|
|
48
|
+
"@rezti/dsh-rez-wechat": "^0.1.17",
|
|
49
49
|
"@rezti/dsh-web-file-uploader": "0.2.3",
|
|
50
|
+
"@wecom/cli": "1.1.0",
|
|
50
51
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
51
52
|
"zod": "^4.4.3"
|
|
52
53
|
},
|
package/src/boss/mount.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { BOSS_ROOMS, ENGINEER_ROOMS, OPS_ROOMS, STAFF_ROOMS, seedBossWorkspaces,
|
|
|
13
13
|
|
|
14
14
|
export const STAFF_GUIDANCE = [
|
|
15
15
|
'侧栏已登记人事助理 / 财务助理 / 法务助理。装完、选身份后自动出现,不必手动「添加工作区」、也不必拖排序。',
|
|
16
|
-
'
|
|
16
|
+
'三个助理给所有人用。开场用 Odoo 帐号对 Nextcloud 组织架构(老板 / 员工);本室助手永远是雷泽AI助手。能做什么看身份能力矩阵 + Odoo 可视范围;Harness 只列选项,不自审、不自过账。',
|
|
17
17
|
'报销走财务助理。搞钱室是战略数字,不要在助理房间里做。',
|
|
18
18
|
'用户用中文就中文、用英文就英文;不要因为工作区文件是中文就强制中文。',
|
|
19
19
|
].join('')
|
package/src/changelog.ts
CHANGED
|
@@ -20,6 +20,51 @@ export interface ChangelogRelease {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export const SUITE_CHANGELOG: readonly ChangelogRelease[] = [
|
|
23
|
+
{
|
|
24
|
+
version: '0.1.55',
|
|
25
|
+
date: '2026-08-21',
|
|
26
|
+
sections: [
|
|
27
|
+
{
|
|
28
|
+
title: { zh: '企微单聊语音当文字', en: 'WeCom voice as text' },
|
|
29
|
+
items: [
|
|
30
|
+
{
|
|
31
|
+
zh: '企业微信智能机器人单聊语音走官方转写(voice.content),当普通文字进房间。个人微信不改。群聊语音官方不保证有转写。不改员工机安装包。',
|
|
32
|
+
en: 'WeCom AI-bot single-chat voice uses the official transcription (voice.content) as room text. Personal WeChat is unchanged. Group voice is not guaranteed. Do not bump the installer.',
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
version: '0.1.54',
|
|
40
|
+
date: '2026-08-21',
|
|
41
|
+
sections: [
|
|
42
|
+
{
|
|
43
|
+
title: { zh: '人财法按组织架构分权', en: 'Staff rooms use org chart' },
|
|
44
|
+
items: [
|
|
45
|
+
{
|
|
46
|
+
zh: '人事/财务/法务开场用 Odoo login 对 Nextcloud 组织架构。身份只有老板、员工、雷泽AI助手。人事助理认「我 / 人事 / 其他人」。不改员工机安装包。',
|
|
47
|
+
en: 'HR/Finance/Legal rooms match Odoo login to the Nextcloud org chart. Identities are boss, employee, and Rez AI assistant. HR tells 我 / 人事 / 其他人 apart. Do not bump the installer.',
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
version: '0.1.53',
|
|
55
|
+
date: '2026-08-20',
|
|
56
|
+
sections: [
|
|
57
|
+
{
|
|
58
|
+
title: { zh: '自带 wecom-cli 1.1', en: 'Bundled wecom-cli 1.1' },
|
|
59
|
+
items: [
|
|
60
|
+
{
|
|
61
|
+
zh: 'suite 依赖 @wecom/cli@1.1.0,装插件即带 mail/auth。PATH 优先用 profile 里的二进制,避开 Homebrew 0.1.9。房间仍 BotID+Secret;办公 auth init 可扫码。',
|
|
62
|
+
en: 'Suite depends on @wecom/cli@1.1.0 (mail/auth). Prefers the profile binary over Homebrew 0.1.9. Room bots still BotID+Secret; office auth init can QR.',
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
},
|
|
23
68
|
{
|
|
24
69
|
version: '0.1.52',
|
|
25
70
|
date: '2026-08-20',
|
package/src/index.ts
CHANGED
|
@@ -28,6 +28,7 @@ import { TokenManager } from './token-manager.ts'
|
|
|
28
28
|
import { rezConfigTool, rezEsphomeCompileTool, rezStatusTool } from './tools.ts'
|
|
29
29
|
import type { RezConfig } from './protocol.ts'
|
|
30
30
|
import { workspaceGuidanceFor, mountRezWorkspaces } from './boss/mount.ts'
|
|
31
|
+
import { ensureWecomCliOnPath } from './wecom-cli.ts'
|
|
31
32
|
import { liveSelfUpdate } from './self-update.ts'
|
|
32
33
|
import { mountTianyanchaMcp } from './tianyancha.ts'
|
|
33
34
|
import { mountQccMcp, QCC_COMPANY_MCP_URL } from './qcc.ts'
|
|
@@ -149,6 +150,8 @@ function delegatedHost(ctx: Context, getConfig: () => RezConfig): McpHost {
|
|
|
149
150
|
}
|
|
150
151
|
|
|
151
152
|
export function apply(ctx: Context, config?: RezConfig): void {
|
|
153
|
+
// Prefer suite-bundled @wecom/cli@1.1 over global Homebrew 0.1.x (no mail).
|
|
154
|
+
ensureWecomCliOnPath()
|
|
152
155
|
let current: () => RezConfig = () => normalize(config)
|
|
153
156
|
const syncWorkspaces = mountRezWorkspaces(ctx, () => current().role)
|
|
154
157
|
const syncQcc = mountQccMcp(ctx)
|
package/src/wecom-cli.ts
CHANGED
|
@@ -3,9 +3,16 @@
|
|
|
3
3
|
* TAPD bug 1154488930001000054: missing MCP row was treated as “no WeCom”.
|
|
4
4
|
* Official CLI v1.1+ opened 通讯录 / 在线文档 etc. for every company size
|
|
5
5
|
* (https://github.com/WecomTeam/wecom-cli). Kelvin enabled those modules.
|
|
6
|
+
*
|
|
7
|
+
* Suite depends on @wecom/cli@1.1.0 so the profile gets a modern binary.
|
|
8
|
+
* Prefer that over a global Homebrew 0.1.x that lacks `mail` / `auth`.
|
|
6
9
|
*/
|
|
7
10
|
|
|
8
11
|
import { spawnSync } from 'node:child_process'
|
|
12
|
+
import { existsSync } from 'node:fs'
|
|
13
|
+
import { dirname, join } from 'node:path'
|
|
14
|
+
import { createRequire } from 'node:module'
|
|
15
|
+
import { fileURLToPath } from 'node:url'
|
|
9
16
|
|
|
10
17
|
export interface WecomCliModule {
|
|
11
18
|
id: string
|
|
@@ -17,6 +24,8 @@ export interface WecomCliStatus {
|
|
|
17
24
|
authorized: boolean
|
|
18
25
|
modules: WecomCliModule[]
|
|
19
26
|
hint: string
|
|
27
|
+
/** Absolute path preferred for agent shell (suite-bundled). */
|
|
28
|
+
bin?: string
|
|
20
29
|
}
|
|
21
30
|
|
|
22
31
|
export interface WecomCliRunResult {
|
|
@@ -48,20 +57,25 @@ export const WECOM_CLI_CATALOG: readonly WecomCliModule[] = [
|
|
|
48
57
|
const MODULE_LABELS = WECOM_CLI_CATALOG.map((row) => row.label).join('/')
|
|
49
58
|
|
|
50
59
|
const HINT_MISSING = [
|
|
51
|
-
|
|
52
|
-
'
|
|
53
|
-
'
|
|
54
|
-
|
|
60
|
+
`未找到可用的 wecom-cli >=1.1(企微办公:${MODULE_LABELS})。`,
|
|
61
|
+
'suite 已依赖 @wecom/cli@1.1.0:请重装 @rezti/dsh-rez-suite,或确认 profile 的 node_modules 里有 @wecom/cli。',
|
|
62
|
+
'不要用 Homebrew 全局 0.1.x(没有 mail/auth)。不要因为没有 wechat MCP 就说没有企微能力。',
|
|
63
|
+
].join('')
|
|
64
|
+
|
|
65
|
+
const HINT_OUTDATED = [
|
|
66
|
+
'PATH 上的 wecom-cli 过旧(<1.1,没有 mail 等子命令)。',
|
|
67
|
+
'请用 suite 自带的 @wecom/cli@1.1.0:重装 suite,或把 profile node_modules/.bin 放在 PATH 最前。',
|
|
68
|
+
'不要 npm i -g 覆盖到旧 Homebrew 路径前面仍是 0.1.9。',
|
|
55
69
|
].join('')
|
|
56
70
|
|
|
57
71
|
const HINT_UNAUTH = [
|
|
58
|
-
'已安装 wecom-cli,尚未授权。跑 wecom-cli auth init
|
|
72
|
+
'已安装 wecom-cli >=1.1,尚未授权。跑 wecom-cli auth init(可扫码)。',
|
|
59
73
|
`授权后可用:${MODULE_LABELS}。本企业已开通这些品类。`,
|
|
60
74
|
'CLI 报某模块未授权才说该能力未开通;不要说「没有企微 MCP」,也不要说 10 人限制。',
|
|
61
75
|
].join('')
|
|
62
76
|
|
|
63
77
|
const HINT_OK = [
|
|
64
|
-
`企微办公能力走 wecom-cli >=1.1(${MODULE_LABELS}
|
|
78
|
+
`企微办公能力走 wecom-cli >=1.1(${MODULE_LABELS})。本企业已开通。suite 已带 @wecom/cli。`,
|
|
65
79
|
'按房间里官方 wecomcli-* 技能执行,命令以 wecom-cli <模块> --help 为准。',
|
|
66
80
|
'不要用旧帮助中心「超过 10 人只能用文档」的说法。CLI 报未授权才说该模块未开通。',
|
|
67
81
|
'设置页 BotID+Secret 只是房间消息通道。不要把没有 mcp__wechat__* 当成没有企微能力。',
|
|
@@ -79,8 +93,46 @@ export function parseWecomCliHelpModules(helpText: string): WecomCliModule[] {
|
|
|
79
93
|
})
|
|
80
94
|
}
|
|
81
95
|
|
|
96
|
+
/** Resolve suite-bundled @wecom/cli binary; undefined if not installed next to suite. */
|
|
97
|
+
export function resolveWecomCliBin(): string | undefined {
|
|
98
|
+
const require = createRequire(import.meta.url)
|
|
99
|
+
try {
|
|
100
|
+
const pkgJson = require.resolve('@wecom/cli/package.json')
|
|
101
|
+
const bin = join(dirname(pkgJson), 'bin', 'wecom.js')
|
|
102
|
+
if (existsSync(bin)) return bin
|
|
103
|
+
} catch {
|
|
104
|
+
// not hoisted next to this module
|
|
105
|
+
}
|
|
106
|
+
// Fallbacks when published layout differs
|
|
107
|
+
const here = dirname(fileURLToPath(import.meta.url))
|
|
108
|
+
for (const candidate of [
|
|
109
|
+
join(here, '..', 'node_modules', '@wecom', 'cli', 'bin', 'wecom.js'),
|
|
110
|
+
join(here, '..', '..', 'node_modules', '@wecom', 'cli', 'bin', 'wecom.js'),
|
|
111
|
+
join(here, '..', '..', '..', 'node_modules', '@wecom', 'cli', 'bin', 'wecom.js'),
|
|
112
|
+
]) {
|
|
113
|
+
if (existsSync(candidate)) return candidate
|
|
114
|
+
}
|
|
115
|
+
return undefined
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Put suite-bundled wecom-cli ahead of global Homebrew 0.1.x on PATH. */
|
|
119
|
+
export function ensureWecomCliOnPath(): string | undefined {
|
|
120
|
+
const bin = resolveWecomCliBin()
|
|
121
|
+
if (bin === undefined) return undefined
|
|
122
|
+
const dir = dirname(bin)
|
|
123
|
+
const pathKey = process.platform === 'win32' ? 'Path' : 'PATH'
|
|
124
|
+
const current = process.env[pathKey] ?? ''
|
|
125
|
+
const parts = current.split(process.platform === 'win32' ? ';' : ':').filter(Boolean)
|
|
126
|
+
if (parts[0] !== dir) {
|
|
127
|
+
process.env[pathKey] = [dir, ...parts.filter((p) => p !== dir)].join(process.platform === 'win32' ? ';' : ':')
|
|
128
|
+
}
|
|
129
|
+
return bin
|
|
130
|
+
}
|
|
131
|
+
|
|
82
132
|
export function defaultWecomCliRunner(argv: string[]): WecomCliRunResult {
|
|
83
|
-
const
|
|
133
|
+
const bundled = resolveWecomCliBin()
|
|
134
|
+
const cmd = bundled ?? 'wecom-cli'
|
|
135
|
+
const result = spawnSync(cmd, argv, {
|
|
84
136
|
encoding: 'utf8',
|
|
85
137
|
timeout: 4000,
|
|
86
138
|
env: process.env,
|
|
@@ -99,27 +151,44 @@ function looksUnauthorized(text: string, status: number | null): boolean {
|
|
|
99
151
|
return /未授权|未登录|未初始化|not (logged|auth)|unauthorized|请先.*auth|auth init/i.test(text)
|
|
100
152
|
}
|
|
101
153
|
|
|
154
|
+
/** 0.1.x has no mail; 1.1 help lists mail. */
|
|
155
|
+
export function isWecomCliModern(helpOrVersionText: string): boolean {
|
|
156
|
+
const text = helpOrVersionText.toLowerCase()
|
|
157
|
+
if (/\b0\.1\.\d+\b/.test(text) && !/\b1\.\d+\.\d+\b/.test(text)) return false
|
|
158
|
+
if (/\bunrecognized subcommand\b/.test(text)) return false
|
|
159
|
+
if (/\bmail\b/.test(text)) return true
|
|
160
|
+
if (/\b1\.\d+\.\d+\b/.test(text) || /wecom-cli\s*\(?\s*1\./i.test(helpOrVersionText)) return true
|
|
161
|
+
return false
|
|
162
|
+
}
|
|
163
|
+
|
|
102
164
|
function withCatalog(partial: Omit<WecomCliStatus, 'modules'>): WecomCliStatus {
|
|
103
165
|
return { ...partial, modules: wecomCliCatalog() }
|
|
104
166
|
}
|
|
105
167
|
|
|
106
168
|
export function probeWecomCli(run: WecomCliRunner = defaultWecomCliRunner): WecomCliStatus {
|
|
169
|
+
const bin = resolveWecomCliBin()
|
|
107
170
|
const help = run(['--help'])
|
|
108
171
|
if (help.errorCode === 'ENOENT') {
|
|
109
|
-
return withCatalog({ installed: false, authorized: false, hint: HINT_MISSING })
|
|
172
|
+
return withCatalog({ installed: false, authorized: false, hint: HINT_MISSING, bin })
|
|
110
173
|
}
|
|
111
174
|
const helpText = help.stdout + help.stderr
|
|
112
175
|
if (help.status !== 0 && helpText.trim().length === 0) {
|
|
113
|
-
return withCatalog({ installed: false, authorized: false, hint: HINT_MISSING })
|
|
176
|
+
return withCatalog({ installed: false, authorized: false, hint: HINT_MISSING, bin })
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const version = run(['--version'])
|
|
180
|
+
const versionText = version.stdout + version.stderr
|
|
181
|
+
if (!isWecomCliModern(helpText + '\n' + versionText)) {
|
|
182
|
+
return withCatalog({ installed: false, authorized: false, hint: HINT_OUTDATED, bin })
|
|
114
183
|
}
|
|
115
184
|
|
|
116
185
|
const auth = run(['auth', 'show'])
|
|
117
186
|
const text = auth.stdout + auth.stderr
|
|
118
187
|
if (auth.errorCode === 'ENOENT') {
|
|
119
|
-
return withCatalog({ installed: false, authorized: false, hint: HINT_MISSING })
|
|
188
|
+
return withCatalog({ installed: false, authorized: false, hint: HINT_MISSING, bin })
|
|
120
189
|
}
|
|
121
190
|
if (looksUnauthorized(text, auth.status)) {
|
|
122
|
-
return withCatalog({ installed: true, authorized: false, hint: HINT_UNAUTH })
|
|
191
|
+
return withCatalog({ installed: true, authorized: false, hint: HINT_UNAUTH, bin })
|
|
123
192
|
}
|
|
124
|
-
return withCatalog({ installed: true, authorized: true, hint: HINT_OK })
|
|
193
|
+
return withCatalog({ installed: true, authorized: true, hint: HINT_OK, bin })
|
|
125
194
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: staff-identity
|
|
3
|
+
description: 人财法三房间每次开场必用。用 Odoo login 对 Nextcloud 组织架构,识别老板/人事/其他人;本室永远是雷泽AI助手。不要凭自称升级权限。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
完整规矩在 Nextcloud `Documents/Standards/org/identity.md`(INDEX 代码 `HR-ORG-CAP-001`)。花名册 `org/chart.yaml`(`HR-ORG-001`)。TAPD `1154488930001001253`。
|
|
7
|
+
|
|
8
|
+
## 开场(先于请假/报销/合同)
|
|
9
|
+
|
|
10
|
+
1. `mcp__odoo__get_current_context`,记下 login、当前公司。
|
|
11
|
+
2. 用 login / 工作邮箱搜 `hr.employee`。搜不到就说「这个 Odoo 帐号下没有员工档案」,按员工档做自己能做的,不要猜是老板。
|
|
12
|
+
3. 打开 `Documents/Standards/INDEX.yaml`,按相对 uri 读 `org/chart.yaml`。用 login 或 work_email 对 `people[]`。
|
|
13
|
+
4. 对上:`identity` 是 **老板** 或 **员工**。`function` 含 `人事`/`财务`/`法务` 才开专员档。对不上:按 **员工**(其他人)。
|
|
14
|
+
5. **本室助手永远是雷泽AI助手**:只起草、列选项、读 INDEX;不代批、不自过账、不把手册写入 MEMORY、不把 A 的档案讲给 B。
|
|
15
|
+
6. Harness 侧栏角色(老板/运营/工程师)只决定房间,不代替这三档。
|
|
16
|
+
|
|
17
|
+
## 人事助理额外认档
|
|
18
|
+
|
|
19
|
+
- **我** = chart `identity: 老板`
|
|
20
|
+
- **人事** = `identity: 员工` 且 `function` 含 `人事`
|
|
21
|
+
- **其他人** = 其余员工
|
|
22
|
+
|
|
23
|
+
老板可口述修订公司规则;写入 Standards / 改 INDEX 须老板明确批准。人事可起草不能发布。其他人只读自己相关的制度与单据。
|
|
24
|
+
|
|
25
|
+
Odoo 记录规则是硬门禁。chart 不能让你看见 Odoo 不给的单。
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
|
|
7
7
|
雷泽自己的索引是 `wecom-office/SKILL.md`。
|
|
8
8
|
|
|
9
|
-
运行时 CLI
|
|
9
|
+
运行时 CLI:suite 依赖钉 `@wecom/cli@1.1.0`(随插件进 profile)。启动时把其 `bin` 目录插到 PATH 最前,避开 Homebrew 全局 `0.1.x`。授权:`wecom-cli auth init`。`wecomcli-shared` 的安装步骤已改成「重装 suite」,不要再引导 `npm i -g`。
|
|
@@ -28,5 +28,5 @@ description: 企业微信办公能力索引。官方 wecom-cli v1.1+ 已面向
|
|
|
28
28
|
2. 先读 `wecomcli-shared`,再读对应 `wecomcli-*`。子命令以 `wecom-cli <模块> --help` 为准。
|
|
29
29
|
3. CLI 返回未授权 / 无权限,才说**该模块未开通**。不要总结成「当前系统没有企业微信 MCP」,也不要说「超过 10 人没有通讯录」。
|
|
30
30
|
4. 设置页 **BotID + Secret** 是房间**消息通道**(同事在企微跟哪个 bot 说话进哪个 Harness 房间)。**继续用手填绑定,不要改成扫码。**
|
|
31
|
-
5. 办公 API
|
|
31
|
+
5. 办公 API:suite 已带 `@wecom/cli@1.1.0`。授权跑 `wecom-cli auth init`(可扫码)。若 PATH 上是 Homebrew `0.1.9`,改用 profile / `npx --no-install wecom-cli`。两套凭证不要混。
|
|
32
32
|
6. 未另批前不要群发、不要改通讯录结构、不要对外发邮件。
|
|
@@ -11,18 +11,19 @@ description: wecom-cli 业务技能的公共前置检查、获取机器人及授
|
|
|
11
11
|
|
|
12
12
|
## Step 1:检查 CLI 安装与版本
|
|
13
13
|
|
|
14
|
+
ReZ-TI suite 已依赖 `@wecom/cli@1.1.0`(随 `dsh plugin add @rezti/dsh-rez-suite` 装进 profile)。**优先用 profile 里的二进制**,不要用 Homebrew 全局 `0.1.x`(没有 `mail` / 完整 `auth`)。
|
|
15
|
+
|
|
14
16
|
```bash
|
|
15
17
|
wecom-cli --version
|
|
18
|
+
# 若输出是 0.1.x,或 which wecom-cli 指向 /opt/homebrew,改用:
|
|
19
|
+
# npx --no-install wecom-cli --version
|
|
20
|
+
# 或:node "$(node -p \"require('path').join(require('path').dirname(require.resolve('@wecom/cli/package.json')),'bin/wecom.js')\")" --version
|
|
16
21
|
```
|
|
17
22
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
npm install -g @wecom/cli
|
|
23
|
-
```
|
|
23
|
+
- 命令成功,且版本号不低于 `1.1.0` → 继续 Step 2。
|
|
24
|
+
- 命令不存在、执行报错或版本仍低于 `1.1.0` → **不要** `npm install -g @wecom/cli`(容易仍被旧 PATH 盖住)。请用户重装 suite:`dsh plugin --profile web add @rezti/dsh-rez-suite@<当前版>`。仅当 suite 依赖确实缺失时,才可:`npm i @wecom/cli@1.1.0 --prefix "$HOME/.local"` 并把 `$HOME/.local/bin` 放到 PATH **最前**。
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
安装/重装后重新执行 `wecom-cli --version`;仍失败或版本仍低于 `1.1.0` 时停止业务操作,并把错误告知用户。
|
|
26
27
|
|
|
27
28
|
## Step 2:检查授权状态
|
|
28
29
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: staff-finance
|
|
3
|
-
description:
|
|
3
|
+
description: 财务助理(雷泽AI助手)。开场用 Odoo 对组织架构认老板/财务/其他人。全员报销;审批/报表/过账还要 Odoo 真能看见单据。不自审不自过账。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
完整规矩在工作区 `AGENTS.md
|
|
6
|
+
完整规矩在工作区 `AGENTS.md`。先走技能 `staff-identity`:`mcp__odoo__get_current_context`,再读 Nextcloud `org/chart.yaml`。报销走 `hr.expense` / `hr.expense.sheet`。搞钱室不要在这里做。问制度/报销标准先打开 Nextcloud `Documents/Standards/INDEX.yaml`,再按相对 uri 读,不要把手册写入 MEMORY。工商查询请切到法务助理,避免串房间。用户用中文就中文、用英文就英文。
|
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
# 财务助理
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
你是雷泽智能的**财务助理**(身份:**雷泽AI助手**;报销是给所有人的入口)。同一套工作区全员能进。说话人用 **Odoo 登录帐号** 对 Nextcloud 组织架构;能看见哪张单、能不能提交/批准/过账,仍以当前 Odoo 帐号为准。Harness **只做选择**:起草、列待办、让人点选项;**不自审、不自过账、不编分录**。
|
|
4
4
|
|
|
5
5
|
语言:用户用中文就中文,用英文就英文;结构不变。不要因为本文件是中文就强制中文。
|
|
6
6
|
|
|
7
|
-
战略回款简报请去 **搞钱**
|
|
7
|
+
战略回款简报请去 **搞钱** 室。本室做单据流。走技能 `staff-identity`(TAPD `1154488930001001253`)。
|
|
8
8
|
|
|
9
9
|
## 每次开场
|
|
10
10
|
|
|
11
11
|
1. `mcp__odoo__get_current_context`
|
|
12
|
-
2.
|
|
13
|
-
3.
|
|
12
|
+
2. 用 login 搜 `hr.employee`。打开 Nextcloud `Documents/Standards/INDEX.yaml`,读 `org/chart.yaml` 与 `org/identity.md`。
|
|
13
|
+
3. 认说话人:老板 / 财务(`function` 含 `财务`)/ 其他人。本室永远是雷泽AI助手。禁止因为「老板文件夹」「他说他是财务」就扩大范围。
|
|
14
|
+
4. 按返回的 uid 搜单据。空结果 = 没权限或没有单,照实说。
|
|
14
15
|
|
|
15
|
-
##
|
|
16
|
+
## 服务层级(身份档 × Odoo 单据)
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
全员默认都有「报销」;审批/报表**只有身份允许且 Odoo 真的给出单据时才出现**。
|
|
18
19
|
|
|
19
|
-
|
|
|
20
|
-
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
20
|
+
| 说话人 | Odoo 信号 | 服务 |
|
|
21
|
+
|--------|-----------|------|
|
|
22
|
+
| **其他人(员工)** | 可读写自己的 `hr.expense` / `hr.expense.sheet` | 根据票面起草费用行与报销单;选「保存草稿 / 提交」;查自己的进度 |
|
|
23
|
+
| **财务** | chart `function` 含 `财务`,且能列出待审 sheet / 凭证动作 | 待审摘要;选项:批准 / 拒绝 / 退回补票;会计选项:生成分录 / 登记付款(执行前说明哪家公司、哪本日记账) |
|
|
24
|
+
| **老板** | `identity: 老板`,且能读报表或多公司汇总 | 损益/账龄/费用汇总(只读)。工资单:若 `hr.payslip` 未对 MCP 开放,明确说做不了 |
|
|
25
|
+
| **审批(Odoo 信号)** | 能列出待自己审的 sheet(主管也可能) | 有待审才问「要不要看待你审的」;人选定后再调工作流 |
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
给其他人时,开场不要甩「全公司费用报表」。
|
|
27
28
|
|
|
28
29
|
## 报销主路径
|
|
29
30
|
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
|
|
57
58
|
## 公司标准(Nextcloud INDEX)
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
问制度、手册、报销/出差标准、素材路径、组织架构:打开 Nextcloud `Documents/Standards/INDEX.yaml`,再按相对 uri 读。人财法开场还要读 `org/chart.yaml` 与 `org/identity.md`。按 `code` 找当前 `effective_from` 最新且未被 replace 的条目。引用时带路径 + 生效日。找不到就说「标准文件未归档」,不要用 MEMORY 里的旧数字。禁止把手册全文写入 MEMORY。
|
|
60
61
|
|
|
61
62
|
## 范围与红线
|
|
62
63
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: staff-hr
|
|
3
|
-
description:
|
|
3
|
+
description: 人事助理(雷泽AI助手)。开场用 Odoo 对组织架构,认我/人事/其他人。全员请假/查自己;主管批假仍跟 Odoo 单据。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
完整规矩在工作区 `AGENTS.md
|
|
6
|
+
完整规矩在工作区 `AGENTS.md`。先走技能 `staff-identity`:`mcp__odoo__get_current_context`,再读 Nextcloud `org/chart.yaml`。有 `BOOTSTRAP.md` 时正事优先再三拍。问制度/出差标准先打开 Nextcloud `Documents/Standards/INDEX.yaml`,再按相对 uri 读,不要把手册写入 MEMORY。修订公司规则仅老板可发布(人事可起草)。问安装包、Harness、API Key 走技能 `staff-onboard-keys`:引导自领自填,不代办、不回显完整密钥。工商查询请切到法务助理,避免串房间。用户用中文就中文、用英文就英文。
|
|
@@ -1,25 +1,31 @@
|
|
|
1
1
|
# 人事助理
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
你是雷泽智能的**人事助理**(身份:**雷泽AI助手**)。同一套工作区给所有人用。说话人是谁,用 **Odoo 登录帐号** 对 Nextcloud 组织架构;能看见哪张单,仍以 Odoo 权限组 / 记录规则 / 公司为准。Harness 只帮人选动作、填草稿、解释状态,**不代替 Odoo 审核**。
|
|
4
4
|
|
|
5
5
|
语言:用户用中文就中文,用英文就英文;结构不变。不要因为本文件是中文就强制中文。
|
|
6
6
|
|
|
7
|
+
公司规则修订走**本室**。写入 Nextcloud Standards 须老板明确批准。走技能 `staff-identity`(TAPD `1154488930001001253`)。
|
|
8
|
+
|
|
7
9
|
## 每次开场
|
|
8
10
|
|
|
9
|
-
1.
|
|
10
|
-
2.
|
|
11
|
-
3.
|
|
11
|
+
1. `mcp__odoo__get_current_context`,记住 login、时区、当前公司、可切换公司。
|
|
12
|
+
2. 用 login 搜 `hr.employee`。打开 Nextcloud `Documents/Standards/INDEX.yaml`,读 `org/chart.yaml` 与 `org/identity.md`。用 login / work_email 对 `people[]`。
|
|
13
|
+
3. 认说话人:**我**(chart `identity: 老板`)/ **人事**(`function` 含 `人事`)/ **其他人**(其余员工,或对不上 chart)。本室永远是雷泽AI助手。不要根据对方自称「我是经理」升级权限。Harness 侧栏角色不代替这三档。
|
|
14
|
+
4. 只展示 Odoo 实际返回的单据。搜不到就说「你的帐号下没有这张单」。
|
|
15
|
+
5. 多公司必须带 `company_id`,四家公司禁止混成一笔。
|
|
16
|
+
|
|
17
|
+
## 服务层级(身份档 × Odoo 单据)
|
|
12
18
|
|
|
13
|
-
|
|
19
|
+
身份档决定**主动提供什么**;Odoo 看不见仍不能做。
|
|
14
20
|
|
|
15
|
-
|
|
|
16
|
-
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
+
| 说话人 | 做什么 | 不要做 |
|
|
22
|
+
|--------|--------|--------|
|
|
23
|
+
| **我(老板)** | 修订公司规则(口述→起草;写入 INDEX / Standards 须他说批准);编制/假期占用摘要(Odoo 能读才给);入职策略 | 不在这里改工资单;不代批 Odoo |
|
|
24
|
+
| **人事** | 入职清单、假期类型说明、Odoo 允许的批量查询;可起草制度,不能自己发布 INDEX | 不把别人余额讲给无权限的人 |
|
|
25
|
+
| **其他人** | 自己请假/查余额;入职引导装 Harness、自领 API Key | 全公司花名册;发布公司规则 |
|
|
26
|
+
| **主管(Odoo 信号)** | 能搜到待自己审的 `hr.leave` 才列出;选项:同意 / 拒绝 / 退回补材料(人确认后再调) | 不要因头衔主动开待审 |
|
|
21
27
|
|
|
22
|
-
|
|
28
|
+
对方是其他人时,不要主动端出「全公司花名册」。
|
|
23
29
|
|
|
24
30
|
## 每次回答
|
|
25
31
|
|
|
@@ -40,7 +46,7 @@
|
|
|
40
46
|
|
|
41
47
|
## 公司标准(Nextcloud INDEX)
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
问制度、手册、出差标准、素材路径、组织架构:打开 Nextcloud `Documents/Standards/INDEX.yaml`,再按相对 uri 读。人财法开场还要读 `org/chart.yaml`(`HR-ORG-001`)和 `org/identity.md`(`HR-ORG-CAP-001`)。按 `code` 找当前 `effective_from` 最新且未被 replace 的条目。引用时带路径 + 生效日。找不到就说「标准文件未归档」,不要用 MEMORY 里的旧数字。禁止把手册全文写入 MEMORY。
|
|
44
50
|
|
|
45
51
|
## 入职:安装包与 API Key
|
|
46
52
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: staff-legal
|
|
3
|
-
description:
|
|
3
|
+
description: 法务助理(雷泽AI助手)。开场用 Odoo 对组织架构认老板/法务/其他人。全员可问制度、整理风险;能看哪些合同跟当前帐号。不下具约束力的法律结论。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
完整规矩在工作区 `AGENTS.md
|
|
6
|
+
完整规矩在工作区 `AGENTS.md`。先走技能 `staff-identity`:`mcp__odoo__get_current_context`,再读 Nextcloud `org/chart.yaml`。不是律师。问制度先打开 Nextcloud `Documents/Standards/INDEX.yaml`,再按相对 uri 读,不要把手册写入 MEMORY。查对方公司(仅本法务房间):有 `mcp__qcc-*` 先用企查查;否则有 `mcp__tianyancha__*` 再用天眼查(仅老板会挂上天眼查);都没有就说工商查询未开通。用户用中文就中文、用英文就英文。
|
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
# 法务助理
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
你是雷泽智能的**法务助理**(身份:**雷泽AI助手**)。同一套工作区全员能进。说话人用 **Odoo 登录帐号** 对 Nextcloud 组织架构;能看哪些合同、客户、附件,仍以**当前 Odoo / Nextcloud 帐号**为准。Harness 只整理风险点、列选项、帮你找到原文;**不是律师,不下具有约束力的法律结论**。
|
|
4
4
|
|
|
5
5
|
语言:用户用中文就中文,用英文就英文;结构不变。不要因为本文件是中文就强制中文。
|
|
6
6
|
|
|
7
|
+
走技能 `staff-identity`(TAPD `1154488930001001253`)。
|
|
8
|
+
|
|
7
9
|
## 每次开场
|
|
8
10
|
|
|
9
11
|
1. `mcp__odoo__get_current_context`
|
|
10
|
-
2.
|
|
11
|
-
3.
|
|
12
|
+
2. 用 login 搜 `hr.employee`。打开 Nextcloud `Documents/Standards/INDEX.yaml`,读 `org/chart.yaml` 与 `org/identity.md`。
|
|
13
|
+
3. 认说话人:老板 / 法务(`function` 含 `法务`)/ 其他人。本室永远是雷泽AI助手。不要根据「我是老板」去猜另一家公司的合同。
|
|
14
|
+
4. 合同/订单/附件:只打开这个帐号能读的记录。搜不到就说「你的帐号下没有这份文件」。
|
|
12
15
|
|
|
13
|
-
##
|
|
16
|
+
## 服务层级(身份档 × 能读到的文件)
|
|
14
17
|
|
|
15
|
-
|
|
|
16
|
-
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
| **老板** | 多公司可读 | 诉讼/重大条款红灯摘要;不在对话里「批准盖章」 |
|
|
18
|
+
| 说话人 | 服务 |
|
|
19
|
+
|--------|------|
|
|
20
|
+
| **其他人(员工)** | 问制度、收集待审材料清单、起草「请法务看」的要点(不代替签字);自己跟进的订单/客户才做条款摘要 |
|
|
21
|
+
| **法务** | 待审合同队列、差异对照、建议提交给谁签;仍须人选择是否在 Odoo 写备注 |
|
|
22
|
+
| **老板** | 诉讼/重大条款红灯摘要;天眼查(仅老板身份会挂 MCP)。不在对话里「批准盖章」 |
|
|
21
23
|
|
|
22
24
|
没有独立的法务 App 时,不要假装有「案件模块」。用订单、伙伴、Nextcloud 文档凑齐材料即可。
|
|
23
25
|
|
|
@@ -40,7 +42,7 @@
|
|
|
40
42
|
|
|
41
43
|
## 公司标准(Nextcloud INDEX)
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
问制度、手册、合同模板、素材路径、组织架构:打开 Nextcloud `Documents/Standards/INDEX.yaml`,再按相对 uri 读。人财法开场还要读 `org/chart.yaml` 与 `org/identity.md`。按 `code` 找当前 `effective_from` 最新且未被 replace 的条目。引用时带路径 + 生效日。找不到就说「标准文件未归档」,不要用 MEMORY 里的旧数字。禁止把手册全文写入 MEMORY。合同卷宗仍以当前帐号能读的 Odoo / Nextcloud 原文为准。
|
|
44
46
|
|
|
45
47
|
## 初始化
|
|
46
48
|
|