openyida 2026.5.20-beta.0 → 2026.5.20
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 +2 -0
- package/bin/yida.js +13 -0
- package/lib/agent-center/agent-center.js +261 -0
- package/lib/agent-center/api.js +463 -0
- package/lib/app/nav-group.js +632 -0
- package/lib/core/command-manifest.js +4 -0
- package/lib/core/locales/ar.js +2 -0
- package/lib/core/locales/de.js +2 -0
- package/lib/core/locales/en.js +2 -0
- package/lib/core/locales/es.js +2 -0
- package/lib/core/locales/fr.js +2 -0
- package/lib/core/locales/hi.js +2 -0
- package/lib/core/locales/ja.js +2 -0
- package/lib/core/locales/ko.js +2 -0
- package/lib/core/locales/pt.js +2 -0
- package/lib/core/locales/vi.js +2 -0
- package/lib/core/locales/zh-HK.js +2 -0
- package/lib/core/locales/zh.js +2 -0
- package/package.json +1 -1
- package/scripts/e2e-real/skill-coverage.js +2 -0
- package/yida-skills/SKILL.md +2 -0
- package/yida-skills/skills/yida-agent-center/SKILL.md +128 -0
- package/yida-skills/skills/yida-nav-group/SKILL.md +83 -0
package/README.md
CHANGED
|
@@ -297,6 +297,7 @@ For overseas apps, pass `--locale en_US` or `--locale ja_JP` on creation command
|
|
|
297
297
|
| `openyida corp-efficiency [overview\|details\|detail\|groups\|notify] [options] [--open\|--no-open]` | Query enterprise efficiency metrics, detail report entries, and related notification actions |
|
|
298
298
|
| `openyida create-app "<name>"\|--name <name> [options] [--locale zh_CN\|en_US\|ja_JP] [--open\|--no-open]` | Create an application and output `appType` |
|
|
299
299
|
| `openyida update-app <appType> --name "..."` | Update application metadata |
|
|
300
|
+
| `openyida nav-group <list\|create\|rename\|delete\|move\|hide\|show> <appType> ...` | Manage sidebar navigation groups and move pages between groups |
|
|
300
301
|
| `openyida app-permission <get\|set\|add\|remove\|search-user> ...` | Manage app primary admins, data admins, and developer members |
|
|
301
302
|
| `openyida i18n <overview\|config\|languages\|list\|upsert\|delete\|translate\|translate-all\|upgrade> <appType> ...` | Manage app multilingual copy and language configuration |
|
|
302
303
|
| `openyida export <appType> [output]` | Export an application migration package |
|
|
@@ -329,6 +330,7 @@ For overseas apps, pass `--locale en_US` or `--locale ja_JP` on creation command
|
|
|
329
330
|
| `openyida data <action> <resource> [args]` | Unified data management for forms, processes, tasks, and subforms |
|
|
330
331
|
| `openyida data check <appType> <formUuid> <rules.json>` | Detect anomalous process-form records |
|
|
331
332
|
| `openyida task-center <type> [options]` | Query todo, created, processed, CC, or proxy-submitted tasks |
|
|
333
|
+
| `openyida agent-center <sub-command>` | Manage Yida process delegation and departure delegation |
|
|
332
334
|
| `openyida basic-info <overview\|commodity\|grant\|capacity\|quota\|abs-path\|dataflow\|i18n\|domain>` | Query organization basic info, capacity, quotas, fixed-domain records, and domain settings |
|
|
333
335
|
| `openyida get-permission <appType> <formUuid>` | Query form permission configuration |
|
|
334
336
|
| `openyida save-permission <appType> <formUuid> [options]` | Save form permission configuration, including raw `--field-permission <json>` |
|
package/bin/yida.js
CHANGED
|
@@ -705,6 +705,13 @@ async function main() {
|
|
|
705
705
|
break;
|
|
706
706
|
}
|
|
707
707
|
|
|
708
|
+
case 'nav-group':
|
|
709
|
+
case 'group': {
|
|
710
|
+
const { run: runNavGroup } = require('../lib/app/nav-group');
|
|
711
|
+
await runNavGroup(args);
|
|
712
|
+
break;
|
|
713
|
+
}
|
|
714
|
+
|
|
708
715
|
case 'app-permission': {
|
|
709
716
|
const { run: runAppPermission } = require('../lib/app-permission/app-permission');
|
|
710
717
|
await runAppPermission(args);
|
|
@@ -919,6 +926,12 @@ async function main() {
|
|
|
919
926
|
break;
|
|
920
927
|
}
|
|
921
928
|
|
|
929
|
+
case 'agent-center': {
|
|
930
|
+
const { run: runAgentCenter } = require('../lib/agent-center/agent-center');
|
|
931
|
+
await runAgentCenter(args);
|
|
932
|
+
break;
|
|
933
|
+
}
|
|
934
|
+
|
|
922
935
|
case 'flash-to-prd': {
|
|
923
936
|
const { run: runFlashToPrd } = require('../lib/flash-note/flash-to-prd');
|
|
924
937
|
await runFlashToPrd(args);
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
listAgentTasks,
|
|
7
|
+
createAgentTask,
|
|
8
|
+
updateAgentTask,
|
|
9
|
+
cancelAgentTask,
|
|
10
|
+
isLeaderShip,
|
|
11
|
+
getLastDepartureAgent,
|
|
12
|
+
getAgentRange,
|
|
13
|
+
} = require('./api');
|
|
14
|
+
const { searchUsers } = require('../corp-manager/api');
|
|
15
|
+
|
|
16
|
+
const USAGE = `openyida agent-center - 代理中心
|
|
17
|
+
|
|
18
|
+
Usage:
|
|
19
|
+
openyida agent-center list [--status ALL|DIS|EFF|OUT|CANCEL] [--keyword TEXT] [--page N] [--size N]
|
|
20
|
+
openyida agent-center search-user <keyword> [--dept <text>] [--size N]
|
|
21
|
+
openyida agent-center create --source-user <userId> --target-user <userId> [--type normal|departure] [options]
|
|
22
|
+
openyida agent-center update <agentUuid> --target-user <userId> [--type normal|departure] [options]
|
|
23
|
+
openyida agent-center cancel <agentUuid> --type normal|departure
|
|
24
|
+
openyida agent-center range <agentUuid>
|
|
25
|
+
openyida agent-center is-leader
|
|
26
|
+
openyida agent-center last-departure
|
|
27
|
+
|
|
28
|
+
Create/update options for normal agents:
|
|
29
|
+
--start <time> 开始时间,例如 "2026-05-20 09:00" 或毫秒时间戳
|
|
30
|
+
--end <time> 结束时间,例如 "2026-05-21 18:00" 或毫秒时间戳
|
|
31
|
+
--category execute|start execute=代处理流程,start=代提交流程,默认 execute
|
|
32
|
+
--notify-source y|n 代理任务是否通知被代理人,默认 n
|
|
33
|
+
--range all|part 代理范围,默认 all
|
|
34
|
+
--range-form <appType:formUuid[,appType:formUuid]>
|
|
35
|
+
--range-json <json> 代理范围 JSON 数组,元素含 appType/formUuid
|
|
36
|
+
--range-file <file> 从 JSON 文件读取代理范围
|
|
37
|
+
|
|
38
|
+
Examples:
|
|
39
|
+
openyida agent-center list --status EFF --size 20
|
|
40
|
+
openyida agent-center search-user "余浩" --dept "宜搭,钉钉官方同学"
|
|
41
|
+
openyida agent-center create --source-user 111 --target-user 222 --start "2026-05-20 09:00" --end "2026-05-21 18:00"
|
|
42
|
+
openyida agent-center create --type departure --source-user 111 --target-user 222
|
|
43
|
+
openyida agent-center cancel Agent_xxx --type departure
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
function fail(message) {
|
|
47
|
+
console.error(message);
|
|
48
|
+
console.error(USAGE);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function parseCliOptions(tokens) {
|
|
53
|
+
const positionals = [];
|
|
54
|
+
const options = {};
|
|
55
|
+
|
|
56
|
+
for (let i = 0; i < tokens.length; i += 1) {
|
|
57
|
+
const token = tokens[i];
|
|
58
|
+
if (token.startsWith('--')) {
|
|
59
|
+
const key = token.slice(2).replace(/-/g, '_');
|
|
60
|
+
const next = tokens[i + 1];
|
|
61
|
+
const value = next && !next.startsWith('--') ? next : true;
|
|
62
|
+
if (Object.prototype.hasOwnProperty.call(options, key)) {
|
|
63
|
+
options[key] = Array.isArray(options[key]) ? options[key].concat(value) : [options[key], value];
|
|
64
|
+
} else {
|
|
65
|
+
options[key] = value;
|
|
66
|
+
}
|
|
67
|
+
if (value !== true) {
|
|
68
|
+
i += 1;
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
positionals.push(token);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return { positionals, options };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function splitList(value) {
|
|
79
|
+
if (!value) {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
if (Array.isArray(value)) {
|
|
83
|
+
return value.flatMap(splitList);
|
|
84
|
+
}
|
|
85
|
+
return String(value).split(',').map(item => item.trim()).filter(Boolean);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function toPositiveInt(value, defaultValue) {
|
|
89
|
+
const parsed = Number.parseInt(value || `${defaultValue}`, 10);
|
|
90
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
91
|
+
return defaultValue;
|
|
92
|
+
}
|
|
93
|
+
return parsed;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function parseTimestamp(value, flagName) {
|
|
97
|
+
if (value === undefined || value === null || value === '') {
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
if (/^\d+$/.test(String(value))) {
|
|
101
|
+
return Number(value);
|
|
102
|
+
}
|
|
103
|
+
const normalized = String(value).trim().replace(/\//g, '-');
|
|
104
|
+
const parsed = Date.parse(normalized);
|
|
105
|
+
if (!Number.isFinite(parsed)) {
|
|
106
|
+
throw new Error(`${flagName} 不是有效时间:${value}`);
|
|
107
|
+
}
|
|
108
|
+
return parsed;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function parseRangeToken(token) {
|
|
112
|
+
const [appType, formUuid] = String(token).split(':').map(part => part && part.trim());
|
|
113
|
+
if (!appType || !formUuid) {
|
|
114
|
+
throw new Error(`代理范围格式必须是 appType:formUuid:${token}`);
|
|
115
|
+
}
|
|
116
|
+
return { appType, formUuid };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function parseRangeValue(options) {
|
|
120
|
+
if (options.range_file) {
|
|
121
|
+
return JSON.parse(fs.readFileSync(options.range_file, 'utf8'));
|
|
122
|
+
}
|
|
123
|
+
if (options.range_json) {
|
|
124
|
+
return JSON.parse(options.range_json);
|
|
125
|
+
}
|
|
126
|
+
const tokens = splitList(options.range_form || options.range_forms);
|
|
127
|
+
if (tokens.length > 0) {
|
|
128
|
+
return tokens.map(parseRangeToken);
|
|
129
|
+
}
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function firstOption(options, keys) {
|
|
134
|
+
for (const key of keys) {
|
|
135
|
+
if (options[key] !== undefined) {
|
|
136
|
+
return options[key];
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function buildMutationOptions(positionals, options) {
|
|
143
|
+
const typeFromPosition = ['normal', 'departure', 'depart', 'dismissed', 'NORMAL', 'DEPARTURE'].includes(positionals[0])
|
|
144
|
+
? positionals.shift()
|
|
145
|
+
: undefined;
|
|
146
|
+
const rangeValue = parseRangeValue(options);
|
|
147
|
+
const rangeType = firstOption(options, ['range', 'agent_range_type', 'range_type']) || (rangeValue ? 'part' : undefined);
|
|
148
|
+
return {
|
|
149
|
+
type: firstOption(options, ['type', 'agent_type']) || typeFromPosition || 'normal',
|
|
150
|
+
sourceUserId: firstOption(options, ['source_user', 'source_user_id', 'from_user', 'source']),
|
|
151
|
+
targetUserId: firstOption(options, ['target_user', 'target_user_id', 'to_user', 'target']),
|
|
152
|
+
start: parseTimestamp(firstOption(options, ['start', 'gmt_start_date']), '--start'),
|
|
153
|
+
end: parseTimestamp(firstOption(options, ['end', 'gmt_end_date']), '--end'),
|
|
154
|
+
category: firstOption(options, ['category', 'agent_category']),
|
|
155
|
+
notifySource: firstOption(options, ['notify_source', 'origin_is_view']),
|
|
156
|
+
rangeType,
|
|
157
|
+
rangeValue,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function printJson(payload) {
|
|
162
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async function runList(options) {
|
|
166
|
+
printJson(await listAgentTasks({
|
|
167
|
+
status: options.status,
|
|
168
|
+
keyword: options.keyword || options.keywords,
|
|
169
|
+
page: toPositiveInt(options.page || options.page_index, 1),
|
|
170
|
+
size: toPositiveInt(options.size || options.page_size, 10),
|
|
171
|
+
}));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async function runSearchUser(positionals, options) {
|
|
175
|
+
const keyword = positionals[0];
|
|
176
|
+
if (!keyword) {
|
|
177
|
+
fail('缺少搜索关键词');
|
|
178
|
+
}
|
|
179
|
+
printJson(await searchUsers({
|
|
180
|
+
keyword,
|
|
181
|
+
dept: options.dept || options.department,
|
|
182
|
+
size: toPositiveInt(options.size, 50),
|
|
183
|
+
}));
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async function runCreate(positionals, options) {
|
|
187
|
+
const mutation = buildMutationOptions(positionals, options);
|
|
188
|
+
printJson(await createAgentTask(mutation));
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async function runUpdate(positionals, options) {
|
|
192
|
+
const agentUuid = positionals.shift();
|
|
193
|
+
if (!agentUuid) {
|
|
194
|
+
fail('缺少 agentUuid');
|
|
195
|
+
}
|
|
196
|
+
const mutation = buildMutationOptions(positionals, options);
|
|
197
|
+
printJson(await updateAgentTask({
|
|
198
|
+
...mutation,
|
|
199
|
+
agentUuid,
|
|
200
|
+
}));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async function runCancel(positionals, options) {
|
|
204
|
+
const agentUuid = positionals[0];
|
|
205
|
+
if (!agentUuid) {
|
|
206
|
+
fail('缺少 agentUuid');
|
|
207
|
+
}
|
|
208
|
+
printJson(await cancelAgentTask({
|
|
209
|
+
agentUuid,
|
|
210
|
+
type: options.type || options.agent_type || positionals[1] || 'normal',
|
|
211
|
+
}));
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async function runRange(positionals) {
|
|
215
|
+
const agentUuid = positionals[0];
|
|
216
|
+
if (!agentUuid) {
|
|
217
|
+
fail('缺少 agentUuid');
|
|
218
|
+
}
|
|
219
|
+
printJson(await getAgentRange({ agentUuid }));
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async function run(args) {
|
|
223
|
+
const { positionals, options } = parseCliOptions(args);
|
|
224
|
+
const action = positionals.shift();
|
|
225
|
+
|
|
226
|
+
if (!action || action === '--help' || action === '-h') {
|
|
227
|
+
console.log(USAGE);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (action === 'list') {
|
|
232
|
+
await runList(options);
|
|
233
|
+
} else if (action === 'search-user') {
|
|
234
|
+
await runSearchUser(positionals, options);
|
|
235
|
+
} else if (action === 'create') {
|
|
236
|
+
await runCreate(positionals, options);
|
|
237
|
+
} else if (action === 'update') {
|
|
238
|
+
await runUpdate(positionals, options);
|
|
239
|
+
} else if (action === 'cancel' || action === 'revoke') {
|
|
240
|
+
await runCancel(positionals, options);
|
|
241
|
+
} else if (action === 'range') {
|
|
242
|
+
await runRange(positionals);
|
|
243
|
+
} else if (action === 'is-leader') {
|
|
244
|
+
printJson(await isLeaderShip());
|
|
245
|
+
} else if (action === 'last-departure') {
|
|
246
|
+
printJson(await getLastDepartureAgent());
|
|
247
|
+
} else {
|
|
248
|
+
fail(`未知 agent-center 子命令:${action}`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
module.exports = {
|
|
253
|
+
USAGE,
|
|
254
|
+
parseCliOptions,
|
|
255
|
+
splitList,
|
|
256
|
+
parseTimestamp,
|
|
257
|
+
parseRangeToken,
|
|
258
|
+
parseRangeValue,
|
|
259
|
+
buildMutationOptions,
|
|
260
|
+
run,
|
|
261
|
+
};
|