yidaconnector 2026.6.11

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.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +383 -0
  3. package/bin/yida.js +670 -0
  4. package/lib/app/form-navigation.js +58 -0
  5. package/lib/app/get-schema.js +538 -0
  6. package/lib/auth/auth.js +294 -0
  7. package/lib/auth/cdp-browser-login.js +390 -0
  8. package/lib/auth/codex-login.js +71 -0
  9. package/lib/auth/login.js +475 -0
  10. package/lib/auth/org.js +363 -0
  11. package/lib/auth/qr-login.js +1563 -0
  12. package/lib/core/chalk.js +384 -0
  13. package/lib/core/check-update.js +82 -0
  14. package/lib/core/cli-error.js +39 -0
  15. package/lib/core/command-manifest.js +106 -0
  16. package/lib/core/env-cmd.js +545 -0
  17. package/lib/core/env-manager.js +601 -0
  18. package/lib/core/env.js +287 -0
  19. package/lib/core/i18n.js +177 -0
  20. package/lib/core/locales/ar.js +805 -0
  21. package/lib/core/locales/de.js +805 -0
  22. package/lib/core/locales/en.js +1623 -0
  23. package/lib/core/locales/es.js +805 -0
  24. package/lib/core/locales/fr.js +805 -0
  25. package/lib/core/locales/hi.js +805 -0
  26. package/lib/core/locales/ja.js +1197 -0
  27. package/lib/core/locales/ko.js +807 -0
  28. package/lib/core/locales/pt.js +805 -0
  29. package/lib/core/locales/vi.js +805 -0
  30. package/lib/core/locales/zh-HK.js +1233 -0
  31. package/lib/core/locales/zh.js +1584 -0
  32. package/lib/core/query-data.js +781 -0
  33. package/lib/core/redact.js +100 -0
  34. package/lib/core/utils.js +799 -0
  35. package/lib/core/yida-client.js +117 -0
  36. package/package.json +94 -0
  37. package/project/config.json +4 -0
  38. package/project/pages/src/demo-birthday-game.oyd.jsx +832 -0
  39. package/project/pages/src/demo-chip-insight.oyd.jsx +983 -0
  40. package/project/pages/src/demo-compat-smoke.oyd.jsx +58 -0
  41. package/project/pages/src/demo-crm-batch-entry.oyd.jsx +805 -0
  42. package/project/pages/src/demo-crm-dashboard.oyd.jsx +677 -0
  43. package/project/pages/src/demo-future-vision-2026.oyd.jsx +1102 -0
  44. package/project/pages/src/demo-ppt.oyd.jsx +1192 -0
  45. package/project/pages/src/demo-salary-calculator.oyd.jsx +904 -0
  46. package/project/pages/src/yidaconnector-knowledge-doc.oyd.jsx +1714 -0
  47. package/project/prd/demo-birthday-game.md +39 -0
  48. package/project/prd/demo-crm.md +463 -0
  49. package/project/prd/demo-dingtalk-ai-solution-center.md +425 -0
  50. package/project/prd/demo-future-vision-2026.md +78 -0
  51. package/project/prd/demo-salary-calculator.md +101 -0
  52. package/scripts/build-skills-package.js +406 -0
  53. package/scripts/check-syntax.js +59 -0
  54. package/scripts/demo-dws.sh +106 -0
  55. package/scripts/e2e-real/cleanup.js +67 -0
  56. package/scripts/e2e-real/fixtures/form-fields.json +18 -0
  57. package/scripts/e2e-real/full-runner.js +1566 -0
  58. package/scripts/e2e-real/runner.js +293 -0
  59. package/scripts/e2e-real/skill-coverage.js +115 -0
  60. package/scripts/generate-command-docs.js +109 -0
  61. package/scripts/nightly-smoke.js +134 -0
  62. package/scripts/postinstall.js +545 -0
  63. package/scripts/solution-center-runner.js +368 -0
  64. package/scripts/validate-ci.sh +50 -0
  65. package/scripts/validate-command-manifest.js +119 -0
  66. package/scripts/validate-package-size.js +78 -0
  67. package/scripts/validate-skills.js +247 -0
  68. package/scripts/validate-structure.js +66 -0
  69. package/yida-skills/SKILL.md +163 -0
  70. package/yida-skills/references/yida-api.md +1309 -0
  71. package/yida-skills/skills/large-file-write/SKILL.md +91 -0
  72. package/yida-skills/skills/large-file-write/references/write-patterns.md +149 -0
  73. package/yida-skills/skills/large-file-write/scripts/write.js +157 -0
  74. package/yida-skills/skills/yida-data-management/SKILL.md +252 -0
  75. package/yida-skills/skills/yida-data-management/references/api-matrix.md +49 -0
  76. package/yida-skills/skills/yida-data-management/references/data-format-guide.md +159 -0
  77. package/yida-skills/skills/yida-data-management/references/verified-endpoints.md +62 -0
  78. package/yida-skills/skills/yida-login/SKILL.md +159 -0
  79. package/yida-skills/skills/yida-logout/SKILL.md +67 -0
@@ -0,0 +1,384 @@
1
+ /**
2
+ * chalk.js - 公共终端样式工具模块
3
+ *
4
+ * 提供统一的 ANSI 颜色常量、图标、分隔线、spinner 动画、
5
+ * 表格渲染等终端输出工具,供所有 CLI 命令文件引用。
6
+ *
7
+ * 用法:
8
+ * const { c, icon, sep, banner, step, label, spinner, table } = require('./chalk');
9
+ */
10
+
11
+ 'use strict';
12
+
13
+ // ── 全局静默开关 ───────────────────────────────────────
14
+ //
15
+ // YIDA_QUIET=1 时所有装饰性输出(banner/step/label/info/hint/listItem/
16
+ // table/result/spinner/success/warn/commandGroup/usage)变为 no-op;
17
+ // fail/error 仍写入 stderr 但去除装饰,保证错误信息可见。
18
+ // console.log 由各 command 用于输出 JSON 结果,本模块不做处理。
19
+ function isQuiet() {
20
+ return process.env.YIDA_QUIET === '1';
21
+ }
22
+
23
+ // ── ANSI 颜色常量 ──────────────────────────────────────
24
+
25
+ const c = {
26
+ reset: '\x1b[0m',
27
+ bold: '\x1b[1m',
28
+ dim: '\x1b[2m',
29
+ italic: '\x1b[3m',
30
+ underline: '\x1b[4m',
31
+ red: '\x1b[31m',
32
+ green: '\x1b[32m',
33
+ yellow: '\x1b[33m',
34
+ blue: '\x1b[34m',
35
+ magenta: '\x1b[35m',
36
+ cyan: '\x1b[36m',
37
+ white: '\x1b[37m',
38
+ gray: '\x1b[90m',
39
+ bgBlue: '\x1b[44m',
40
+ bgCyan: '\x1b[46m',
41
+ };
42
+
43
+ // ── 图标常量 ───────────────────────────────────────────
44
+
45
+ const icon = {
46
+ success: `${c.green}✔${c.reset}`,
47
+ fail: `${c.red}✖${c.reset}`,
48
+ warn: `${c.yellow}⚠${c.reset}`,
49
+ info: `${c.cyan}ℹ${c.reset}`,
50
+ arrow: `${c.cyan}→${c.reset}`,
51
+ bullet: `${c.dim}•${c.reset}`,
52
+ star: `${c.yellow}★${c.reset}`,
53
+ check: `${c.green}✓${c.reset}`,
54
+ cross: `${c.red}✗${c.reset}`,
55
+ dot: `${c.dim}·${c.reset}`,
56
+ play: `${c.green}▶${c.reset}`,
57
+ folder: `${c.cyan}📁${c.reset}`,
58
+ file: `${c.dim}📄${c.reset}`,
59
+ link: `${c.blue}🔗${c.reset}`,
60
+ key: `${c.yellow}🔑${c.reset}`,
61
+ lock: `${c.red}🔒${c.reset}`,
62
+ unlock: `${c.green}🔓${c.reset}`,
63
+ rocket: '🚀',
64
+ package: '📦',
65
+ gear: '⚙️',
66
+ sparkle: '✨',
67
+ };
68
+
69
+ // ── 分隔线 ─────────────────────────────────────────────
70
+
71
+ /**
72
+ * 生成分隔线。
73
+ * @param {number} [width=60] - 分隔线宽度
74
+ * @returns {string}
75
+ */
76
+ function sep(width = 60) {
77
+ return `${c.dim}${'─'.repeat(width)}${c.reset}`;
78
+ }
79
+
80
+ // ── Banner 标题 ────────────────────────────────────────
81
+
82
+ /**
83
+ * 打印命令标题 banner(替代旧的 '='.repeat(55) 风格)。
84
+ * @param {string} title - 标题文字
85
+ * @param {object} [options]
86
+ * @param {string} [options.subtitle] - 副标题
87
+ * @param {boolean} [options.stderr=true] - 是否输出到 stderr
88
+ */
89
+ function banner(title, options = {}) {
90
+ if (isQuiet()) {return;}
91
+ const { subtitle, stderr = true } = options;
92
+ const out = stderr ? process.stderr : process.stdout;
93
+ out.write('\n');
94
+ out.write(` ${c.bold}${c.cyan}${title}${c.reset}\n`);
95
+ if (subtitle) {
96
+ out.write(` ${c.dim}${subtitle}${c.reset}\n`);
97
+ }
98
+ out.write(` ${sep()}\n`);
99
+ }
100
+
101
+ // ── 步骤输出 ───────────────────────────────────────────
102
+
103
+ /**
104
+ * 打印步骤信息。
105
+ * @param {number} stepNumber - 步骤编号
106
+ * @param {string} message - 步骤描述
107
+ * @param {boolean} [stderr=true] - 是否输出到 stderr
108
+ */
109
+ function step(stepNumber, message, stderr = true) {
110
+ if (isQuiet()) {return;}
111
+ const out = stderr ? process.stderr : process.stdout;
112
+ out.write(`\n ${c.cyan}[${stepNumber}]${c.reset} ${c.bold}${message}${c.reset}\n`);
113
+ }
114
+
115
+ // ── 标签值对输出 ───────────────────────────────────────
116
+
117
+ /**
118
+ * 打印标签-值对(如 " 地址:https://...")。
119
+ * @param {string} labelText - 标签文字
120
+ * @param {string} value - 值
121
+ * @param {object} [options]
122
+ * @param {string} [options.indent=' '] - 缩进
123
+ * @param {boolean} [options.stderr=true] - 是否输出到 stderr
124
+ */
125
+ function label(labelText, value, options = {}) {
126
+ if (isQuiet()) {return;}
127
+ const { indent = ' ', stderr = true } = options;
128
+ const out = stderr ? process.stderr : process.stdout;
129
+ out.write(`${indent}${c.dim}${labelText}${c.reset} ${value}\n`);
130
+ }
131
+
132
+ // ── 状态消息 ───────────────────────────────────────────
133
+
134
+ /**
135
+ * 打印成功消息。
136
+ * @param {string} message
137
+ * @param {boolean} [stderr=true]
138
+ */
139
+ function success(message, stderr = true) {
140
+ if (isQuiet()) {return;}
141
+ if (stderr) {
142
+ console.error(` ${icon.success} ${message}`);
143
+ } else {
144
+ process.stdout.write(` ${icon.success} ${message}\n`);
145
+ }
146
+ }
147
+
148
+ /**
149
+ * 打印失败消息。
150
+ * @param {string} message
151
+ * @param {boolean} [stderr=true]
152
+ */
153
+ function fail(message, stderr = true) {
154
+ // fail 在 quiet 模式下仍写 stderr,但去除装饰,保证错误可见
155
+ if (isQuiet()) {
156
+ process.stderr.write(`${message}\n`);
157
+ return;
158
+ }
159
+ if (stderr) {
160
+ console.error(` ${icon.fail} ${c.red}${message}${c.reset}`);
161
+ } else {
162
+ process.stdout.write(` ${icon.fail} ${c.red}${message}${c.reset}\n`);
163
+ }
164
+ }
165
+
166
+ /**
167
+ * 打印警告消息。
168
+ * @param {string} message
169
+ * @param {boolean} [stderr=true]
170
+ */
171
+ function warn(message, stderr = true) {
172
+ if (isQuiet()) {return;}
173
+ if (stderr) {
174
+ console.error(` ${icon.warn} ${c.yellow}${message}${c.reset}`);
175
+ } else {
176
+ process.stdout.write(` ${icon.warn} ${c.yellow}${message}${c.reset}\n`);
177
+ }
178
+ }
179
+
180
+ /**
181
+ * 打印信息消息。
182
+ * @param {string} message
183
+ * @param {boolean} [stderr=true]
184
+ */
185
+ function info(message, stderr = true) {
186
+ if (isQuiet()) {return;}
187
+ if (stderr) {
188
+ console.error(` ${icon.info} ${message}`);
189
+ } else {
190
+ process.stdout.write(` ${icon.info} ${message}\n`);
191
+ }
192
+ }
193
+
194
+ /**
195
+ * 打印暗淡的提示文字。
196
+ * @param {string} message
197
+ * @param {boolean} [stderr=true]
198
+ */
199
+ function hint(message, stderr = true) {
200
+ if (isQuiet()) {return;}
201
+ if (stderr) {
202
+ console.error(` ${c.dim}${message}${c.reset}`);
203
+ } else {
204
+ process.stdout.write(` ${c.dim}${message}${c.reset}\n`);
205
+ }
206
+ }
207
+
208
+ // ── Spinner 动画 ───────────────────────────────────────
209
+
210
+ const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
211
+
212
+ /**
213
+ * 创建 spinner 动画。
214
+ * @param {string} message - 加载提示文字
215
+ * @returns {{ succeed: function, fail: function, update: function }}
216
+ */
217
+ function spinner(message) {
218
+ if (isQuiet()) {
219
+ return { succeed() {}, fail() {}, update() {} };
220
+ }
221
+ let frameIndex = 0;
222
+ const timer = setInterval(() => {
223
+ process.stderr.write(`\r ${c.cyan}${SPINNER_FRAMES[frameIndex]}${c.reset} ${message}`);
224
+ frameIndex = (frameIndex + 1) % SPINNER_FRAMES.length;
225
+ }, 80);
226
+
227
+ return {
228
+ succeed(text) {
229
+ clearInterval(timer);
230
+ process.stderr.write(`\r ${icon.success} ${text}\n`);
231
+ },
232
+ fail(text) {
233
+ clearInterval(timer);
234
+ process.stderr.write(`\r ${icon.fail} ${c.red}${text}${c.reset}\n`);
235
+ },
236
+ update(text) {
237
+ message = text;
238
+ },
239
+ };
240
+ }
241
+
242
+ // ── 表格渲染 ───────────────────────────────────────────
243
+
244
+ /**
245
+ * 渲染键值对表格(仿 openclaw 风格)。
246
+ * @param {Array<[string, string]>} rows - [标签, 值] 数组
247
+ * @param {object} [options]
248
+ * @param {boolean} [options.stderr=true]
249
+ * @param {string} [options.indent=' ']
250
+ */
251
+ function table(rows, options = {}) {
252
+ if (isQuiet()) {return;}
253
+ const { stderr = true, indent = ' ' } = options;
254
+ const out = stderr ? process.stderr : process.stdout;
255
+ const labelWidth = Math.max(...rows.map(([labelText]) => labelText.length)) + 2;
256
+
257
+ for (const [labelText, value] of rows) {
258
+ out.write(`${indent}${c.dim}${labelText.padEnd(labelWidth)}${c.reset}${value}\n`);
259
+ }
260
+ }
261
+
262
+ /**
263
+ * 渲染命令分组列表(用于 help 输出)。
264
+ * @param {string} groupTitle - 分组标题
265
+ * @param {Array<[string, string]>} commands - [命令, 描述] 数组
266
+ * @param {boolean} [stderr=false]
267
+ */
268
+ function commandGroup(groupTitle, commands, stderr = false) {
269
+ if (isQuiet()) {return;}
270
+ const out = stderr ? process.stderr : process.stdout;
271
+ out.write(`\n ${c.bold}${c.cyan}${groupTitle}${c.reset}\n`);
272
+ const maxCmdLen = Math.max(...commands.map(([cmd]) => cmd.length));
273
+ const padWidth = Math.min(maxCmdLen + 2, 50);
274
+ for (const [cmd, desc] of commands) {
275
+ out.write(` ${c.green}${cmd.padEnd(padWidth)}${c.reset}${c.dim}${desc}${c.reset}\n`);
276
+ }
277
+ }
278
+
279
+ // ── 列表项输出 ─────────────────────────────────────────
280
+
281
+ /**
282
+ * 打印列表项。
283
+ * @param {string} text - 列表项文字
284
+ * @param {object} [options]
285
+ * @param {string} [options.indent=' '] - 缩进
286
+ * @param {string} [options.marker] - 自定义标记(默认使用 bullet)
287
+ * @param {boolean} [options.stderr=true]
288
+ */
289
+ function listItem(text, options = {}) {
290
+ if (isQuiet()) {return;}
291
+ const { indent = ' ', marker = icon.bullet, stderr = true } = options;
292
+ const out = stderr ? process.stderr : process.stdout;
293
+ out.write(`${indent}${marker} ${text}\n`);
294
+ }
295
+
296
+ // ── 错误输出 ───────────────────────────────────────────
297
+
298
+ /**
299
+ * 打印错误信息并退出。
300
+ * @param {string} message - 错误消息
301
+ * @param {object} [options]
302
+ * @param {string} [options.hint] - 提示信息
303
+ * @param {boolean} [options.exit=true] - 是否退出进程
304
+ */
305
+ function error(message, options = {}) {
306
+ const { hint: hintText, exit: shouldExit = true } = options;
307
+ // error 在 quiet 模式下仍输出,但去除装饰,保证错误可见
308
+ if (isQuiet()) {
309
+ process.stderr.write(`${message}\n`);
310
+ if (hintText) {
311
+ process.stderr.write(`${hintText}\n`);
312
+ }
313
+ } else {
314
+ process.stderr.write(`\n ${icon.fail} ${c.red}${message}${c.reset}\n`);
315
+ if (hintText) {
316
+ process.stderr.write(` ${c.dim}${hintText}${c.reset}\n`);
317
+ }
318
+ }
319
+ if (shouldExit) {
320
+ process.exit(1);
321
+ }
322
+ }
323
+
324
+ // ── 用法提示 ───────────────────────────────────────────
325
+
326
+ /**
327
+ * 打印命令用法提示。
328
+ * @param {string} usage - 用法字符串
329
+ * @param {string} [example] - 示例
330
+ */
331
+ function usage(usageText, example) {
332
+ if (isQuiet()) {return;}
333
+ process.stderr.write(`\n ${c.yellow}用法:${c.reset} ${usageText}\n`);
334
+ if (example) {
335
+ process.stderr.write(` ${c.dim}示例:${c.reset} ${example}\n`);
336
+ }
337
+ }
338
+
339
+ // ── 结果摘要 ───────────────────────────────────────────
340
+
341
+ /**
342
+ * 打印操作结果摘要框。
343
+ * @param {boolean} isSuccess - 是否成功
344
+ * @param {string} title - 标题
345
+ * @param {Array<[string, string]>} [details] - 详情键值对
346
+ * @param {boolean} [stderr=true]
347
+ */
348
+ function result(isSuccess, title, details, stderr = true) {
349
+ if (isQuiet()) {return;}
350
+ const out = stderr ? process.stderr : process.stdout;
351
+ out.write('\n');
352
+ out.write(` ${sep()}\n`);
353
+ if (isSuccess) {
354
+ out.write(` ${icon.success} ${c.green}${c.bold}${title}${c.reset}\n`);
355
+ } else {
356
+ out.write(` ${icon.fail} ${c.red}${c.bold}${title}${c.reset}\n`);
357
+ }
358
+ if (details && details.length > 0) {
359
+ out.write('\n');
360
+ table(details, { stderr, indent: ' ' });
361
+ }
362
+ out.write(` ${sep()}\n\n`);
363
+ }
364
+
365
+ module.exports = {
366
+ c,
367
+ icon,
368
+ sep,
369
+ banner,
370
+ step,
371
+ label,
372
+ success,
373
+ fail,
374
+ warn,
375
+ info,
376
+ hint,
377
+ spinner,
378
+ table,
379
+ commandGroup,
380
+ listItem,
381
+ error,
382
+ usage,
383
+ result,
384
+ };
@@ -0,0 +1,82 @@
1
+ /**
2
+ * check-update.js - yidaconnector 版本更新检查
3
+ *
4
+ * 向 npm registry 查询最新版本,有新版本时打印提示。
5
+ * 全程异步,不阻塞主命令流程。
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ const https = require('https');
11
+ const { t } = require('./i18n');
12
+
13
+ const REGISTRY_URL = 'https://registry.npmjs.org/yidaconnector/latest';
14
+
15
+ /**
16
+ * 从 npm registry 获取最新版本号。
17
+ * @returns {Promise<string|null>}
18
+ */
19
+ function fetchLatestVersion() {
20
+ return new Promise((resolve) => {
21
+ const req = https.get(REGISTRY_URL, { timeout: 5000 }, (res) => {
22
+ let data = '';
23
+ res.on('data', (chunk) => { data += chunk; });
24
+ res.on('end', () => {
25
+ try {
26
+ const parsed = JSON.parse(data);
27
+ resolve(parsed.version || null);
28
+ } catch {
29
+ resolve(null);
30
+ }
31
+ });
32
+ });
33
+ req.on('error', () => resolve(null));
34
+ req.on('timeout', () => { req.destroy(); resolve(null); });
35
+ req.on('socket', (socket) => {
36
+ if (socket && typeof socket.unref === 'function') {
37
+ socket.unref();
38
+ }
39
+ });
40
+ if (typeof req.unref === 'function') {
41
+ req.unref();
42
+ }
43
+ });
44
+ }
45
+
46
+ /**
47
+ * 比较版本号,返回 latestVersion 是否比 currentVersion 更新。
48
+ * 支持 semver 格式(major.minor.patch),pre-release 标签(如 -beta.1)会被忽略,
49
+ * 仅比较数字部分。
50
+ */
51
+ function isNewer(currentVersion, latestVersion) {
52
+ // 截取 '-' 前的纯数字版本部分,兼容 pre-release 格式(如 1.2.3-beta.1)
53
+ const parseStableVersion = (v) => (v || '').split('-')[0];
54
+ const parseParts = (v) => parseStableVersion(v).split('.').map((n) => parseInt(n, 10) || 0);
55
+ const [cMajor, cMinor, cPatch] = parseParts(currentVersion);
56
+ const [lMajor, lMinor, lPatch] = parseParts(latestVersion);
57
+
58
+ if (lMajor !== cMajor) {return lMajor > cMajor;}
59
+ if (lMinor !== cMinor) {return lMinor > cMinor;}
60
+ return lPatch > cPatch;
61
+ }
62
+
63
+ /**
64
+ * 检查是否有新版本,有则打印提示。
65
+ * @param {string} currentVersion - 当前版本号(来自 package.json)
66
+ */
67
+ async function checkUpdate(currentVersion) {
68
+ try {
69
+ const latestVersion = await fetchLatestVersion();
70
+
71
+ if (latestVersion && isNewer(currentVersion, latestVersion)) {
72
+ process.nextTick(() => {
73
+ const { c } = require('./chalk');
74
+ process.stderr.write(`\n ${c.yellow}⚠${c.reset} ${t('check_update.new_version', latestVersion, currentVersion)}\n`);
75
+ });
76
+ }
77
+ } catch {
78
+ // 版本检查失败静默忽略,不影响主流程
79
+ }
80
+ }
81
+
82
+ module.exports = { checkUpdate, isNewer, fetchLatestVersion };
@@ -0,0 +1,39 @@
1
+ 'use strict';
2
+
3
+ const { redactSensitive } = require('./redact');
4
+
5
+ class CliError extends Error {
6
+ constructor(message, options = {}) {
7
+ super(message);
8
+ this.name = 'CliError';
9
+ this.code = options.code || 'CLI_ERROR';
10
+ this.exitCode = options.exitCode || 1;
11
+ this.details = options.details;
12
+ this.usage = options.usage;
13
+ this.isCliError = true;
14
+ }
15
+ }
16
+
17
+ function isCliError(error) {
18
+ return !!(error && error.isCliError);
19
+ }
20
+
21
+ function toErrorPayload(error) {
22
+ const payload = {
23
+ success: false,
24
+ errorCode: isCliError(error) ? error.code : 'UNEXPECTED_ERROR',
25
+ errorMsg: error && error.message ? error.message : String(error),
26
+ };
27
+
28
+ if (isCliError(error) && error.details !== undefined) {
29
+ payload.details = redactSensitive(error.details);
30
+ }
31
+
32
+ return payload;
33
+ }
34
+
35
+ module.exports = {
36
+ CliError,
37
+ isCliError,
38
+ toErrorPayload,
39
+ };
@@ -0,0 +1,106 @@
1
+ 'use strict';
2
+
3
+ function command(id, path, usage, descriptionKey, options = {}) {
4
+ return {
5
+ id,
6
+ path,
7
+ command: path[0],
8
+ name: path.join(' '),
9
+ usage,
10
+ descriptionKey,
11
+ requiresLogin: options.requiresLogin !== false,
12
+ output: options.output || 'text',
13
+ aliases: options.aliases || [],
14
+ examples: options.examples || [],
15
+ hidden: options.hidden === true,
16
+ };
17
+ }
18
+
19
+ const COMMAND_GROUPS = [
20
+ {
21
+ id: 'auth',
22
+ titleKey: 'help.group_auth',
23
+ commands: [
24
+ command('login', ['login'], 'login [target-url] [--qr|--agent-qr|--codex|--browser] [--env <name>|--intl|--overseas|--global|--yidaapps|--alibaba] [--corp-id <corpId>]', 'help.cmd_login', {
25
+ requiresLogin: false,
26
+ output: 'json',
27
+ }),
28
+ command('logout', ['logout'], 'logout', 'help.cmd_logout', { requiresLogin: false }),
29
+ command('auth', ['auth'], 'auth <status|login|refresh|logout>', 'help.cmd_auth', { requiresLogin: false }),
30
+ command('org', ['org'], 'org <list|switch>', 'help.cmd_org'),
31
+ command('env', ['env'], 'env [--json]', 'help.cmd_env', {
32
+ requiresLogin: false,
33
+ output: 'text|json',
34
+ }),
35
+ command('env-management', ['env'], 'env <setup|list|show|switch|add|remove>', 'help.cmd_env_management', {
36
+ requiresLogin: false,
37
+ }),
38
+ ],
39
+ },
40
+ {
41
+ id: 'data',
42
+ titleKey: 'help.group_data',
43
+ commands: [
44
+ command('data', ['data'], 'data <action> <resource> [args]', 'help.cmd_data'),
45
+ ],
46
+ },
47
+ {
48
+ id: 'utility',
49
+ titleKey: 'help.group_utility',
50
+ commands: [
51
+ command('commands', ['commands'], 'commands [--json]', 'help.cmd_commands', {
52
+ requiresLogin: false,
53
+ output: 'json',
54
+ }),
55
+ ],
56
+ },
57
+ ];
58
+
59
+ function flattenCommandManifest(groups = COMMAND_GROUPS) {
60
+ return groups.flatMap(group => group.commands.map(entry => ({ ...entry, group: group.id })));
61
+ }
62
+
63
+ function localizeCommand(entry, translate) {
64
+ return {
65
+ id: entry.id,
66
+ name: entry.name,
67
+ path: entry.path,
68
+ command: entry.command,
69
+ usage: `yidaconnector ${entry.usage}`,
70
+ raw_usage: entry.usage,
71
+ description: translate(entry.descriptionKey),
72
+ description_key: entry.descriptionKey,
73
+ group: entry.group,
74
+ requires_login: entry.requiresLogin,
75
+ output: entry.output,
76
+ aliases: entry.aliases,
77
+ examples: entry.examples,
78
+ hidden: entry.hidden,
79
+ };
80
+ }
81
+
82
+ function buildCommandManifest(options = {}) {
83
+ const translate = typeof options.t === 'function' ? options.t : key => key;
84
+ const commands = flattenCommandManifest();
85
+
86
+ return {
87
+ schema_version: 1,
88
+ name: 'yidaconnector',
89
+ version: options.version || null,
90
+ aliases: ['yida'],
91
+ command_prefix: 'yidaconnector',
92
+ groups: COMMAND_GROUPS.map(group => ({
93
+ id: group.id,
94
+ title: translate(group.titleKey),
95
+ title_key: group.titleKey,
96
+ commands: group.commands.map(entry => entry.id),
97
+ })),
98
+ commands: commands.map(entry => localizeCommand(entry, translate)),
99
+ };
100
+ }
101
+
102
+ module.exports = {
103
+ COMMAND_GROUPS,
104
+ buildCommandManifest,
105
+ flattenCommandManifest,
106
+ };