weaver-work-cli 0.1.33 → 0.1.38
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/dist/chunks/{archive-FVFY6GZN.js → archive-PDV724YK.js} +5 -4
- package/dist/chunks/{archive-oa-NW3OD4UV.js → archive-oa-4XE4MNXQ.js} +4 -3
- package/dist/chunks/{asset-7QJKMIDV.js → asset-PDL2QE2N.js} +8 -7
- package/dist/chunks/{attachment-content-OSAVA6K3.js → attachment-content-MDDGOE5E.js} +3 -3
- package/dist/chunks/{blog-I7SDPNW4.js → blog-UYR3EUXW.js} +5 -4
- package/dist/chunks/{caizhilian-O37ZIQNY.js → caizhilian-LG2X5NMF.js} +5 -4
- package/dist/chunks/{calendar-7KXE4ED3.js → calendar-FG4BAZHE.js} +4 -3
- package/dist/chunks/{chunk-Q6LWB5HX.js → chunk-6FTTSA45.js} +4 -3
- package/dist/chunks/{chunk-MQ2I5AA3.js → chunk-6LTFIFLM.js} +3 -2
- package/dist/chunks/{chunk-WRRJ4GG2.js → chunk-CORFRD7Q.js} +4 -3
- package/dist/chunks/{chunk-WY74UBJ6.js → chunk-DMV2TOMH.js} +2194 -240
- package/dist/chunks/{chunk-MEEFGWTM.js → chunk-ELYDWBZJ.js} +135 -10
- package/dist/chunks/{chunk-EEWPQE3O.js → chunk-FUWVHMVV.js} +7 -6
- package/dist/chunks/{chunk-HEL5XTYI.js → chunk-GGJFMNJM.js} +26 -4
- package/dist/chunks/{chunk-KAS45KNR.js → chunk-IZUDA353.js} +1 -1
- package/dist/chunks/{chunk-2FLWXFVS.js → chunk-J7USS3ED.js} +4 -4
- package/dist/chunks/{chunk-IHUYP6LO.js → chunk-JSMFPO43.js} +1 -1
- package/dist/chunks/{chunk-RBGOMK4Y.js → chunk-KKRL3REV.js} +5 -4
- package/dist/chunks/{chunk-OCU4RLHC.js → chunk-NI6GIPIM.js} +195 -36
- package/dist/chunks/{chunk-PRHJGPMA.js → chunk-NR6RKXPA.js} +2 -2
- package/dist/chunks/{chunk-D223PTXU.js → chunk-OJQUJZQF.js} +33 -7
- package/dist/chunks/{chunk-ILMBNVSG.js → chunk-UJJD4QWF.js} +4 -3
- package/dist/chunks/{chunk-6ATGWRZM.js → chunk-UZZBA6PV.js} +177 -14
- package/dist/chunks/{chunk-GFPXQIY2.js → chunk-VRYHGG6O.js} +2 -2
- package/dist/chunks/{chunk-NHA62QD7.js → chunk-XJY7G4DD.js} +3 -3
- package/dist/chunks/{chunk-VBCFFFGT.js → chunk-Z32KWY6G.js} +4 -1
- package/dist/chunks/{conflict-SFNEVJY5.js → conflict-BQZEQ4SP.js} +2 -2
- package/dist/chunks/contract-XIRAFTEV.js +9111 -0
- package/dist/chunks/{cowork-CKWYHXYB.js → cowork-BLG62BL2.js} +46 -26
- package/dist/chunks/{ebuilder-form-KOLJRVZD.js → ebuilder-form-NUKG5QW4.js} +3 -3
- package/dist/chunks/{ehr-WFOC3B4D.js → ehr-2STW5ILH.js} +174 -10
- package/dist/chunks/{esb-LJZTN663.js → esb-UUDQUNKY.js} +4 -4
- package/dist/chunks/{fna-F7QRIIZC.js → fna-6RCY4NU5.js} +15 -9
- package/dist/chunks/{host-VQ6JJXGQ.js → host-7RXEDMAH.js} +3 -3
- package/dist/chunks/{host-KXPTEWFS.js → host-EJZFROU3.js} +3 -3
- package/dist/chunks/{host-BCGUVEWX.js → host-FWDOSRH5.js} +3 -3
- package/dist/chunks/{host-DGE2TZD4.js → host-RHM3NPXV.js} +3 -3
- package/dist/chunks/{host-BQBRHVR3.js → host-UFF33TWJ.js} +3 -3
- package/dist/chunks/{hrm-NI6XAKW5.js → hrm-PKJ6ELSH.js} +3 -3
- package/dist/chunks/{im-7TRTF3KT.js → im-YJAXS7CO.js} +3 -3
- package/dist/chunks/{invoice-AOXWJKYT.js → invoice-HWVSXGX6.js} +3 -3
- package/dist/chunks/{jiuchuanhui-7NQWEZAW.js → jiuchuanhui-L7VKILZB.js} +4 -3
- package/dist/chunks/{lazy-dispatch-RNS4EE4S.js → lazy-dispatch-NMYEIHRH.js} +4 -4
- package/dist/chunks/{mail-VDHJAB4O.js → mail-B42RRU7G.js} +46 -24
- package/dist/chunks/{meeting-GA7XCNNP.js → meeting-CFYVBJSS.js} +77 -12
- package/dist/chunks/{okr-TQIRERPQ.js → okr-GCLF6V7W.js} +4 -3
- package/dist/chunks/{plan-4RY4LN2P.js → plan-ZVL7GBRI.js} +4 -3
- package/dist/chunks/{project-D6XT2OC5.js → project-4YWAAE2K.js} +4 -3
- package/dist/chunks/{registry-QKMI43Q6.js → registry-EP4VTHZS.js} +8 -8
- package/dist/chunks/{registry-JHRIDQ3A.js → registry-FRJ6H7BT.js} +4 -4
- package/dist/chunks/{registry-VOGKFFTR.js → registry-SG2PGVCF.js} +2 -2
- package/dist/chunks/{room-recommend-D4EUOOWY.js → room-recommend-R3JVUUAC.js} +4 -4
- package/dist/chunks/{schedule-XPFBHPCV.js → schedule-NIJBTYDO.js} +4 -4
- package/dist/chunks/{workflow-HLBZRWIY.js → workflow-BB24DFBY.js} +11 -4
- package/dist/index.js +31 -26
- package/dist/internal/e10/auth-recovery.js +114 -1
- package/dist/internal/e10/client.js +16 -2
- package/dist/internal/e10/fetch-timing.js +31 -0
- package/dist/internal/e10/request-runtime.js +108 -7
- package/dist/shortcuts/archive/host.js +3 -2
- package/dist/shortcuts/archive-oa/host.js +2 -1
- package/dist/shortcuts/asset/host.js +6 -5
- package/dist/shortcuts/blog/host.js +3 -2
- package/dist/shortcuts/caizhilian/host.js +3 -2
- package/dist/shortcuts/calendar/host.js +2 -1
- package/dist/shortcuts/contract/host.js +2 -1
- package/dist/shortcuts/cowork/host.js +10 -1
- package/dist/shortcuts/cowork/operations/types.js +17 -2
- package/dist/shortcuts/ebuilder-form/host.js +3 -1
- package/dist/shortcuts/ehr/host.js +2 -1
- package/dist/shortcuts/ehr/operations/recruit-write.js +35 -0
- package/dist/shortcuts/ehr/operations/recruit.js +147 -0
- package/dist/shortcuts/esb/host.js +2 -1
- package/dist/shortcuts/fna/host.js +2 -1
- package/dist/shortcuts/fna/operations/expense-chart.js +19 -7
- package/dist/shortcuts/hrm/host.js +2 -1
- package/dist/shortcuts/im/host.js +3 -2
- package/dist/shortcuts/index.js +5 -0
- package/dist/shortcuts/invoice/host.js +5 -4
- package/dist/shortcuts/jiuchuanhui/host.js +2 -1
- package/dist/shortcuts/mail/host.js +10 -1
- package/dist/shortcuts/mail/operations/types.js +17 -2
- package/dist/shortcuts/meeting/host.js +3 -2
- package/dist/shortcuts/meeting/index.js +79 -1
- package/dist/shortcuts/meeting/invitation/text.js +71 -0
- package/dist/shortcuts/meeting/manifest.js +10 -0
- package/dist/shortcuts/meeting/operations/eb/catalog.js +5 -0
- package/dist/shortcuts/meeting/operations/eb/conflict.js +6 -1
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +2105 -169
- package/dist/shortcuts/meeting/operations/eb/crm-search.js +478 -0
- package/dist/shortcuts/meeting/operations/eb/factory.js +161 -8
- package/dist/shortcuts/meeting/operations/eb/index.js +2 -0
- package/dist/shortcuts/meeting/operations/eb/room-recommend.js +36 -2
- package/dist/shortcuts/meeting/operations/eb-fallback.js +4 -0
- package/dist/shortcuts/meeting/operations/env.js +6 -0
- package/dist/shortcuts/meeting/operations/invitation.js +200 -28
- package/dist/shortcuts/okr/host.js +2 -1
- package/dist/shortcuts/plan/host.js +2 -1
- package/dist/shortcuts/project/host.js +2 -1
- package/dist/shortcuts/workflow/endpoints.js +8 -3
- package/dist/shortcuts/workflow/operations/form.js +341 -36
- package/dist/shortcuts/workflow/operations.js +23 -1
- package/docs/ehr.md +1 -1
- package/docs/fna.md +2 -1
- package/package.json +1 -1
- package/skill-template/business-info.json +18 -0
- package/skill-template/domains/cowork.md +14 -0
- package/skills/weaver-e10-cowork/SKILL.md +101 -0
- package/skills/weaver-e10-cowork/references/cowork-read.md +90 -0
- package/skills/weaver-e10-cowork/references/cowork-write.md +131 -0
- package/skills/weaver-e10-cowork/references/safety-boundaries.md +45 -0
- package/skills/weaver-e10-jucailin/SKILL.md +21 -3
- package/skills/weaver-e10-jucailin/references/recruit-read.md +25 -0
- package/skills/weaver-e10-jucailin/references/recruit-write.md +13 -0
- package/skills/weaver-e10-jucailin/references/salary.md +15 -11
- package/skills/weaver-e10-mail/SKILL.md +12 -9
- package/skills/weaver-e10-meeting/SKILL.md +499 -300
- package/skills/weaver-e10-meeting/references/meeting-eb.md +334 -0
- package/skills/weaver-e10-meeting/references/meeting-invitation.md +64 -6
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-okr/references/source-manifest.json +3 -3
- package/skills/weaver-e10-qiyecheng/SKILL.md +5 -2
- package/skills/weaver-e10-qiyecheng/references/catalog.md +2 -2
- package/skills/weaver-e10-qiyecheng/references/expense-chart.md +15 -1
- package/skills/weaver-e10-qiyecheng/references/source-manifest.json +22 -21
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +3 -3
|
@@ -3,7 +3,9 @@ import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js
|
|
|
3
3
|
import { requireE10Session } from '../../internal/e10/context.js';
|
|
4
4
|
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
5
5
|
import { E10ApiError, createE10RequestRuntime } from '../../internal/e10/request-runtime.js';
|
|
6
|
+
import { isE10SessionExpiredResponse } from '../../internal/e10/auth-recovery.js';
|
|
6
7
|
import { mailAuthError, mailNetworkError, MailCliError, mailValidationError } from './errors.js';
|
|
8
|
+
import { mailPerf } from './operations/types.js';
|
|
7
9
|
function inferProfile(ctx) {
|
|
8
10
|
const options = ctx.getGlobalOptions();
|
|
9
11
|
return options.profile || getActiveProfile();
|
|
@@ -102,7 +104,9 @@ export function createMailHost(ctx, dependencies = {}) {
|
|
|
102
104
|
|| ((innerCtx) => requireE10Session(innerCtx, { skipProfileEnrichment: true }));
|
|
103
105
|
async function ensureSession() {
|
|
104
106
|
if (!e10Session) {
|
|
107
|
+
const sessionStart = Date.now();
|
|
105
108
|
e10Session = await requireSession(ctx);
|
|
109
|
+
mailPerf.sessionMs = Date.now() - sessionStart;
|
|
106
110
|
sessionContext = {
|
|
107
111
|
baseUrl: e10Session.getBaseUrl(),
|
|
108
112
|
profile: inferProfile(ctx),
|
|
@@ -128,6 +132,7 @@ export function createMailHost(ctx, dependencies = {}) {
|
|
|
128
132
|
assertPath(path);
|
|
129
133
|
const resolvedMethod = method || (body === undefined && form === undefined && multipart === undefined ? 'GET' : 'POST');
|
|
130
134
|
let response;
|
|
135
|
+
const reqStart = Date.now();
|
|
131
136
|
try {
|
|
132
137
|
response = await (await runtime()).requestJson({
|
|
133
138
|
module: 'mail',
|
|
@@ -152,7 +157,11 @@ export function createMailHost(ctx, dependencies = {}) {
|
|
|
152
157
|
}
|
|
153
158
|
throw error;
|
|
154
159
|
}
|
|
155
|
-
|
|
160
|
+
finally {
|
|
161
|
+
mailPerf.requestCount += 1;
|
|
162
|
+
mailPerf.requestMs += Date.now() - reqStart;
|
|
163
|
+
}
|
|
164
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
156
165
|
throw mailAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
157
166
|
}
|
|
158
167
|
if (response.parseError) {
|
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
export const READ = 'read';
|
|
2
2
|
export const WRITE = 'write';
|
|
3
|
+
/** 进程内耗时收集器(周军锋 2026-10-20 要求:全链路耗时可量化)。host 写入、mailSuccess 注出;内部诊断字段不进回答。 */
|
|
4
|
+
export const mailPerf = {
|
|
5
|
+
t0: Date.now(),
|
|
6
|
+
sessionMs: 0,
|
|
7
|
+
requestCount: 0,
|
|
8
|
+
requestMs: 0,
|
|
9
|
+
};
|
|
3
10
|
export function mailSuccess(action, data, meta) {
|
|
4
11
|
const payload = { ok: true, action, data };
|
|
5
|
-
|
|
6
|
-
|
|
12
|
+
const perf = {
|
|
13
|
+
elapsed_ms: Date.now() - mailPerf.t0,
|
|
14
|
+
session_ms: mailPerf.sessionMs || undefined,
|
|
15
|
+
requests: mailPerf.requestCount || undefined,
|
|
16
|
+
network_ms: mailPerf.requestMs || undefined,
|
|
17
|
+
};
|
|
18
|
+
for (const k of Object.keys(perf))
|
|
19
|
+
if (perf[k] === undefined)
|
|
20
|
+
delete perf[k];
|
|
21
|
+
payload.meta = { ...(meta || {}), ...perf };
|
|
7
22
|
return payload;
|
|
8
23
|
}
|
|
9
24
|
/** 构造「对象类型 + 严格禁止额外字段」的 JSON Schema。 */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js';
|
|
2
|
+
import { isE10SessionExpiredResponse, } from '../../internal/e10/auth-recovery.js';
|
|
2
3
|
import { requireE10Session } from '../../internal/e10/context.js';
|
|
3
4
|
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
4
5
|
import { E10ApiError, createE10RequestRuntime } from '../../internal/e10/request-runtime.js';
|
|
@@ -127,7 +128,7 @@ export function createMeetingHost(ctx, dependencies = {}) {
|
|
|
127
128
|
catch (error) {
|
|
128
129
|
mapRuntimeNetworkError(error);
|
|
129
130
|
}
|
|
130
|
-
if (response
|
|
131
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
131
132
|
throw meetingAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
132
133
|
}
|
|
133
134
|
if (response.status !== 200) {
|
|
@@ -177,7 +178,7 @@ export function createMeetingHost(ctx, dependencies = {}) {
|
|
|
177
178
|
catch (error) {
|
|
178
179
|
mapRuntimeNetworkError(error);
|
|
179
180
|
}
|
|
180
|
-
if (response
|
|
181
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
181
182
|
throw meetingAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
182
183
|
}
|
|
183
184
|
if (response.parseError) {
|
|
@@ -2,7 +2,7 @@ import { readFile } from 'node:fs/promises';
|
|
|
2
2
|
import { ExitCode, isCliError, toErrorEnvelope } from '../../core/errors.js';
|
|
3
3
|
import { createMeetingContinuationSigner } from './continuation.js';
|
|
4
4
|
import { createMeetingHost } from './host.js';
|
|
5
|
-
import { meetingManifest } from './manifest.js';
|
|
5
|
+
import { meetingManifest, OPERATION_INDEX_HINT } from './manifest.js';
|
|
6
6
|
import { executeMeetingOperation } from './operations.js';
|
|
7
7
|
import { meetingValidationError } from './errors.js';
|
|
8
8
|
function asOptions(value) {
|
|
@@ -102,6 +102,84 @@ export const meetingShortcut = {
|
|
|
102
102
|
.action(action((ctx) => {
|
|
103
103
|
ctx.output.write(meetingManifest, { json: true });
|
|
104
104
|
}));
|
|
105
|
+
// 能力清单:**纯文本、不压缩**。
|
|
106
|
+
// 为什么必须单独开一条命令:`meeting schema --json` 完整 308KB,stdout 只回 20KB 预览,
|
|
107
|
+
// operations 数组被截到前 10 条 —— agent 拿这个判断"有没有某能力"必然误判
|
|
108
|
+
// (2026-10-30 真机:回复用户"当前 CLI 版本没有建会建议时间操作",实际 suggest 一直存在)。
|
|
109
|
+
meeting.command('ops')
|
|
110
|
+
.description('列出全部会议 operation(纯文本不压缩);判断"有没有某能力"用这个,不要用 schema')
|
|
111
|
+
.option('--grep <keyword>', '只看名字或摘要命中关键词的(不区分大小写)')
|
|
112
|
+
.option('--capability <name>', '只看某个能力分组,如 eb / meeting / room / conflict / sign')
|
|
113
|
+
.option('--json', 'JSON 输出(注意:JSON 走信封压缩,条目多时会被截断,查全量请用文本)')
|
|
114
|
+
.action(action((ctx, ...rest) => {
|
|
115
|
+
// commander 对无位置参数的子命令传的是 (options, command),别取错 —— 用 "没有 opts 方法"
|
|
116
|
+
// 把 command 实例挑出去(2026-10-30:一开始取了最后一个,拿到 command 对象,导致 --grep 失效)。
|
|
117
|
+
const options = rest.find((item) => item && typeof item === 'object' && typeof item.opts !== 'function') ?? {};
|
|
118
|
+
const keyword = String(options?.grep ?? '').trim().toLowerCase();
|
|
119
|
+
const capability = String(options?.capability ?? '').trim().toLowerCase();
|
|
120
|
+
const all = meetingManifest.operations;
|
|
121
|
+
const hit = all.filter((item) => {
|
|
122
|
+
// 分组支持前缀:--capability eb 能命中 eb.meeting / eb.room / eb.sign ...
|
|
123
|
+
if (capability && !String(item.capability ?? '').toLowerCase().startsWith(capability))
|
|
124
|
+
return false;
|
|
125
|
+
if (!keyword)
|
|
126
|
+
return true;
|
|
127
|
+
return item.name.toLowerCase().includes(keyword)
|
|
128
|
+
|| String(item.summary ?? '').toLowerCase().includes(keyword);
|
|
129
|
+
});
|
|
130
|
+
if (options?.json === true) {
|
|
131
|
+
ctx.output.write({
|
|
132
|
+
ok: true,
|
|
133
|
+
schemaVersion: 1,
|
|
134
|
+
operationIndexHint: OPERATION_INDEX_HINT,
|
|
135
|
+
count: hit.length,
|
|
136
|
+
total: all.length,
|
|
137
|
+
operations: hit.map((item) => ({
|
|
138
|
+
name: item.name,
|
|
139
|
+
capability: item.capability,
|
|
140
|
+
risk: item.risk,
|
|
141
|
+
summary: item.summary,
|
|
142
|
+
})),
|
|
143
|
+
withheldOperations: meetingManifest.withheldOperations,
|
|
144
|
+
}, { json: true });
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const clip = (text, max) => (text.length > max ? `${text.slice(0, max)}…` : text);
|
|
148
|
+
const lines = [
|
|
149
|
+
`泛微E10会议 CLI 能力清单:命中 ${hit.length} / 共 ${all.length} 项`
|
|
150
|
+
+ `${keyword ? `(关键词「${keyword}」)` : ''}${capability ? `(分组 ${capability})` : ''}`,
|
|
151
|
+
'用法:weaver-work-cli --json meeting run <operation> --input-json \'{...}\'',
|
|
152
|
+
'',
|
|
153
|
+
];
|
|
154
|
+
const groups = new Map();
|
|
155
|
+
for (const item of hit) {
|
|
156
|
+
const key = String(item.capability ?? 'other');
|
|
157
|
+
if (!groups.has(key))
|
|
158
|
+
groups.set(key, []);
|
|
159
|
+
groups.get(key).push(item);
|
|
160
|
+
}
|
|
161
|
+
for (const [group, items] of [...groups.entries()].sort((a, b) => b[1].length - a[1].length)) {
|
|
162
|
+
lines.push(`## ${group}(${items.length})`);
|
|
163
|
+
for (const item of items) {
|
|
164
|
+
lines.push(` ${item.name} ${clip(String(item.summary ?? ''), 96)}`);
|
|
165
|
+
}
|
|
166
|
+
lines.push('');
|
|
167
|
+
}
|
|
168
|
+
if (!capability || 'withheld'.startsWith(capability)) {
|
|
169
|
+
const withheld = meetingManifest.withheldOperations.filter((item) => {
|
|
170
|
+
if (!keyword)
|
|
171
|
+
return true;
|
|
172
|
+
return item.name.toLowerCase().includes(keyword) || item.reason.toLowerCase().includes(keyword);
|
|
173
|
+
});
|
|
174
|
+
if (withheld.length > 0) {
|
|
175
|
+
lines.push(`## 不可用(${withheld.length})`);
|
|
176
|
+
for (const item of withheld) {
|
|
177
|
+
lines.push(` ${item.name} ${clip(item.reason, 120)}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
process.stdout.write(`${lines.join('\n')}\n`);
|
|
182
|
+
}));
|
|
105
183
|
meeting.command('run')
|
|
106
184
|
.description('Run a meeting operation with JSON input')
|
|
107
185
|
.argument('<operation>', 'operation name, e.g. meeting.room.list')
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 邀请函的**对话内文本版**(Markdown),与 docx 版同源同字段。
|
|
3
|
+
*
|
|
4
|
+
* 为什么要有这一份(2026-10-31 用户明确要求):
|
|
5
|
+
* 「邀请函不是在对话里给个文件让我自己下载,而是**直接展示在对话里**」。
|
|
6
|
+
* docx 是给人打印/发出去的成品,但小E 会话里用户看不到 docx 内容 ——
|
|
7
|
+
* 只回一个 filePath,用户还得去本地打开才知道写了什么。
|
|
8
|
+
* 所以渲染 docx 的同时产出一份纯文本,模型可以把正文直接贴进回复。
|
|
9
|
+
*
|
|
10
|
+
* 版式与 `templates/meeting/invitation.docx` 一致:标题 / 称呼 / 邀请语 /
|
|
11
|
+
* 会议要素 / 议程表 / 落款 / 备注。取不到的字段统一写【待补充】,与 docx 的黄色高亮同义。
|
|
12
|
+
*/
|
|
13
|
+
import { PENDING_MARK } from './docx.js';
|
|
14
|
+
/** 单元格里的 `|` 会破坏 Markdown 表格,换行会破坏行结构 —— 统一折成空格。 */
|
|
15
|
+
function cell(value) {
|
|
16
|
+
return String(value ?? '').replace(/\|/g, '/').replace(/\s*\r?\n\s*/g, ' ').trim();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 生成邀请函的对话文本版。
|
|
20
|
+
*
|
|
21
|
+
* @param resolver 与 docx 共用的占位符解析器(保证两版内容一字不差)
|
|
22
|
+
* @param agendaRows 议程行(来自会议议题 / extra.agenda / 模板示例行)
|
|
23
|
+
* @param options.pendingHint 是否在末尾附「【待补充】需人工补」的提示(默认附)
|
|
24
|
+
*/
|
|
25
|
+
export function renderInvitationMarkdown(resolver, agendaRows, options = {}) {
|
|
26
|
+
const pending = new Set();
|
|
27
|
+
const val = (key) => {
|
|
28
|
+
const rendered = resolver(key);
|
|
29
|
+
if (rendered.pending) {
|
|
30
|
+
pending.add(key);
|
|
31
|
+
return PENDING_MARK;
|
|
32
|
+
}
|
|
33
|
+
return String(rendered.text ?? '').trim();
|
|
34
|
+
};
|
|
35
|
+
const lines = [];
|
|
36
|
+
lines.push('# 邀请函');
|
|
37
|
+
lines.push('');
|
|
38
|
+
lines.push(`**尊敬的 ${val('guest_org')}:**`);
|
|
39
|
+
lines.push('');
|
|
40
|
+
lines.push(`${val('caller')} 诚邀您参加「${val('mt_name')}」,现将会议安排通知如下:`);
|
|
41
|
+
lines.push('');
|
|
42
|
+
lines.push(`- **会议名称**:${val('mt_name')}`);
|
|
43
|
+
lines.push(`- **会议时间**:${val('begin_datetime')}~${val('end_datetime')}`);
|
|
44
|
+
lines.push(`- **会议地点**:${val('address')}`);
|
|
45
|
+
lines.push(`- **参会人员**:${val('hrm_members')}`);
|
|
46
|
+
lines.push(`- **会议内容**:${val('mt_desc')}`);
|
|
47
|
+
lines.push('');
|
|
48
|
+
lines.push(`**${val('begin_date')}会议议程安排:**`);
|
|
49
|
+
lines.push('');
|
|
50
|
+
lines.push('| 议程安排 | 议程内容 | 议程时间 |');
|
|
51
|
+
lines.push('| --- | --- | --- |');
|
|
52
|
+
if (agendaRows.length === 0) {
|
|
53
|
+
lines.push('| — | 暂无议程 | — |');
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
for (const [name, content, timeRange] of agendaRows) {
|
|
57
|
+
lines.push(`| ${cell(name) || '—'} | ${cell(content) || '—'} | ${cell(timeRange) || '—'} |`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
lines.push('');
|
|
61
|
+
lines.push(val('company_name'));
|
|
62
|
+
lines.push('');
|
|
63
|
+
lines.push(val('issue_date'));
|
|
64
|
+
lines.push('');
|
|
65
|
+
lines.push('> 注:以上为拟定会议安排,具体会议时间与议程需根据实际情况确认。');
|
|
66
|
+
if (options.pendingHint !== false && pending.size > 0) {
|
|
67
|
+
lines.push('');
|
|
68
|
+
lines.push(`> ⚠️ 标 ${PENDING_MARK} 的字段会议里没有值,需要人工补;补完可用 mtId 重新生成。`);
|
|
69
|
+
}
|
|
70
|
+
return { markdown: lines.join('\n'), pendingFields: [...pending] };
|
|
71
|
+
}
|
|
@@ -62,8 +62,18 @@ function buildOperations() {
|
|
|
62
62
|
inputSchema: definition.inputSchema,
|
|
63
63
|
}));
|
|
64
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* 给模型的**能力自查提示**。放在 manifest 靠前位置、且控制在 200 字符内 ——
|
|
67
|
+
* 输出压缩时字符串最多留 200 字符,这句话必须能完整活下来。
|
|
68
|
+
* 2026-10-30 真机事故:`meeting schema --json` 完整 308KB、预览只给 20KB,
|
|
69
|
+
* operations 数组被截到前 10 条,`meeting.eb.meeting.create.suggest` 根本不在预览里,
|
|
70
|
+
* agent 于是回复用户"当前 CLI 版本没有建会建议时间操作"——能力是有的,是被压缩藏住了。
|
|
71
|
+
*/
|
|
72
|
+
export const OPERATION_INDEX_HINT = '本 JSON 可能被压缩截断,别据此判断能力是否存在;'
|
|
73
|
+
+ '完整清单跑 `weaver-work-cli meeting ops`(纯文本、不压缩,支持 --grep 关键词)';
|
|
65
74
|
export const meetingManifest = {
|
|
66
75
|
schemaVersion: 1,
|
|
76
|
+
operationIndexHint: OPERATION_INDEX_HINT,
|
|
67
77
|
name: 'meeting',
|
|
68
78
|
title: '泛微E10会议管理(双模式:标准版 Java REST + EB 版 eBuilder)',
|
|
69
79
|
version: '1.0.0',
|
|
@@ -204,6 +204,11 @@ export const EB_ENDPOINTS = [
|
|
|
204
204
|
interfacePk: 'query_meeting_room_list',
|
|
205
205
|
countPk: 'query_meeting_room_count',
|
|
206
206
|
queryParams: ['manager', 'departmentId', 'mr_type', 'room_attr'],
|
|
207
|
+
// 按 e-builder openApi 文档:这些是 `mainTable` 节点的传入字段,服务端据此过滤。
|
|
208
|
+
// ⚠️ 2026-10-30 实测(用户刚在后端把「会议室名称」配成传入字段后):
|
|
209
|
+
// 服务端是**精确匹配** —— room_name=测试会议室1 → 1 条;room_name=测试 / 重庆 → 0 条
|
|
210
|
+
// (全量里明明有「重庆会议室一/二」)。模糊由 factory 的 fallback 在本地兜底。
|
|
211
|
+
mainTableParams: ['room_name', 'status', 'place', 'org_id', 'hrm_ids'],
|
|
207
212
|
summarizeRows: summarizeRoomRows,
|
|
208
213
|
summary: 'EB 版会议室列表(query_meeting_room_list + count):自带 statusText 与状态字典',
|
|
209
214
|
emptyHint: 'EB 会议室表(`uf_mt_room_base`)查不到任何记录。可能是:① 该环境确实还没建过会议室;'
|
|
@@ -136,7 +136,12 @@ export async function fetchEbAppSettings(env, operation) {
|
|
|
136
136
|
* - 开关为空 / 非 `1` → 放行(交由后续冲突检测与用户确认)。
|
|
137
137
|
*
|
|
138
138
|
* 拒绝后 CLI 不代为发起流程(流程集成不在本模块范围),只把已确认的信息交回调用方,
|
|
139
|
-
*
|
|
139
|
+
* 由调用方改用 `meeting.eb.meeting.create.flow.prepare/quick`(按 `mt_new_wf` 走流程建会)。
|
|
140
|
+
*
|
|
141
|
+
* ⚠️ 2026-10-29 更正:这里原先写的是"由调用方转 `weaver-e10-workflow`",是过时口径 ——
|
|
142
|
+
* 转去通用 workflow 模块会拿不到会议表单字段映射/会议室联动/邀请函,且容易让 agent
|
|
143
|
+
* 用关键词检索流程(真实事故:检索出「会议室预定流程-北方大区业务运营中心」当配置项)。
|
|
144
|
+
* 会议流程必须走 `create.flow`。
|
|
140
145
|
*/
|
|
141
146
|
export function assertEbCreatePathAllowed(settings) {
|
|
142
147
|
if (settings.error) {
|