openyida 2026.5.13 → 2026.5.15-1

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 CHANGED
@@ -167,6 +167,7 @@ openyida/
167
167
  openyida create-app "CRM"
168
168
  openyida create-app --name "CRM" --desc "Customer management" --theme deepBlue
169
169
  openyida app-list --size 20
170
+ openyida corp-efficiency
170
171
  openyida create-form create APP_XXX "Customer" .cache/openyida/forms/customer-fields.json
171
172
  openyida create-form update APP_XXX FORM_XXX .cache/openyida/forms/customer-changes.json
172
173
  openyida get-schema APP_XXX FORM_XXX
@@ -254,9 +255,10 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
254
255
  | Command | Description |
255
256
  |---------|-------------|
256
257
  | `openyida env [--json]` | Detect the active AI tool environment and login state |
258
+ | `openyida env setup` | Choose a customer-friendly login environment preset: public, overseas, Alibaba intranet, or private deployment |
257
259
  | `openyida env <list\|show\|switch\|add\|remove>` | Manage public/private Yida environment profiles |
258
260
  | `openyida commands [--json]` | Emit the machine-readable command manifest |
259
- | `openyida login [--qr\|--agent-qr\|--codex\|--browser] [--corp-id <corpId>]` | Log in to Yida |
261
+ | `openyida login [--qr\|--agent-qr\|--codex\|--browser] [--env <name>\|--overseas] [--corp-id <corpId>]` | Log in to Yida |
260
262
  | `openyida logout` | Log out or switch account |
261
263
  | `openyida auth <status\|login\|refresh\|logout>` | Manage login status |
262
264
  | `openyida org list` | List accessible organizations |
@@ -267,6 +269,7 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
267
269
  | Command | Description |
268
270
  |---------|-------------|
269
271
  | `openyida app-list [--size N]` | List Yida applications |
272
+ | `openyida corp-efficiency [overview\|details\|detail\|groups\|notify] [options] [--open\|--no-open]` | Query enterprise efficiency metrics, detail report entries, and related notification actions |
270
273
  | `openyida create-app "<name>"\|--name <name> [options] [--open\|--no-open]` | Create an application and output `appType` |
271
274
  | `openyida update-app <appType> --name "..."` | Update application metadata |
272
275
  | `openyida export <appType> [output]` | Export an application migration package |
@@ -286,7 +289,7 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
286
289
  | `openyida build-page <sourceFile> [--output file\|--write]` | Build/fix Yida-compatible page source from OpenYida authoring JSX |
287
290
  | `openyida check-page <sourceFile> [--compat] [--json]` | Check page compatibility; `.oyd.jsx` is compatibility-built before linting |
288
291
  | `openyida compile <sourceFile> [--compat]` | Compile a custom page locally; `.oyd.jsx` sources are compatibility-built first |
289
- | `openyida publish <sourceFile> <appType> <formUuid> [--compat] [--health-check] [--open\|--no-open]` | Compile and publish a custom page |
292
+ | `openyida publish <sourceFile> <appType> <formUuid> [--compat] [--health-check] [--force] [--open\|--no-open]` | Compile and publish a custom display page; by default the target must be `formType=display` |
290
293
  | `openyida update-form-config <appType> <formUuid> <isRenderNav> <title>` | Update page/form display configuration |
291
294
 
292
295
  ### Data, Permissions, and Sharing
package/bin/yida.js CHANGED
@@ -284,6 +284,39 @@ function getArgValue(cliArgs, name) {
284
284
  return cliArgs[index + 1];
285
285
  }
286
286
 
287
+ function applyLoginEnvironmentFlags(cliArgs) {
288
+ const envFlagMap = {
289
+ '--public': 'public',
290
+ '--intl': 'intl',
291
+ '--overseas': 'intl',
292
+ '--international': 'intl',
293
+ '--global': 'intl',
294
+ '--alibaba': 'alibaba',
295
+ '--internal': 'alibaba',
296
+ '--intranet': 'alibaba',
297
+ };
298
+ const filteredArgs = [];
299
+
300
+ for (let index = 0; index < cliArgs.length; index++) {
301
+ const arg = cliArgs[index];
302
+ if (arg === '--env') {
303
+ const envName = cliArgs[index + 1];
304
+ if (envName && !envName.startsWith('--')) {
305
+ process.env.OPENYIDA_ENV = envName;
306
+ index++;
307
+ }
308
+ continue;
309
+ }
310
+ if (envFlagMap[arg]) {
311
+ process.env.OPENYIDA_ENV = envFlagMap[arg];
312
+ continue;
313
+ }
314
+ filteredArgs.push(arg);
315
+ }
316
+
317
+ return filteredArgs;
318
+ }
319
+
287
320
  // 解析全局 --quiet 开关:从 args 中剔除并设置 YIDA_QUIET=1,让 chalk.js
288
321
  // 的所有装饰输出(banner/step/info/...)变 no-op,AI 即可直接 `... --quiet | jq`。
289
322
  function applyQuietFlag() {
@@ -352,40 +385,41 @@ async function main() {
352
385
 
353
386
  case 'login': {
354
387
  const { checkLoginOnly } = require('../lib/auth/login');
355
- if (args.includes('--agent-poll') || args.includes('--codex-poll')) {
356
- const sessionFile = getArgValue(args, '--agent-poll') || getArgValue(args, '--codex-poll');
388
+ const loginArgs = applyLoginEnvironmentFlags(args);
389
+ if (loginArgs.includes('--agent-poll') || loginArgs.includes('--codex-poll')) {
390
+ const sessionFile = getArgValue(loginArgs, '--agent-poll') || getArgValue(loginArgs, '--codex-poll');
357
391
  const { pollCodexQrLogin } = require('../lib/auth/qr-login');
358
392
  const result = await pollCodexQrLogin(sessionFile, {
359
- corpId: getArgValue(args, '--corp-id'),
393
+ corpId: getArgValue(loginArgs, '--corp-id'),
360
394
  });
361
395
  printLoginResult(result);
362
- } else if (args.includes('--agent-select') || args.includes('--codex-select')) {
363
- const sessionFile = getArgValue(args, '--agent-select') || getArgValue(args, '--codex-select');
396
+ } else if (loginArgs.includes('--agent-select') || loginArgs.includes('--codex-select')) {
397
+ const sessionFile = getArgValue(loginArgs, '--agent-select') || getArgValue(loginArgs, '--codex-select');
364
398
  const { selectCodexQrCorp } = require('../lib/auth/qr-login');
365
399
  const result = await selectCodexQrCorp(sessionFile, {
366
- corpId: getArgValue(args, '--corp-id'),
400
+ corpId: getArgValue(loginArgs, '--corp-id'),
367
401
  });
368
402
  printLoginResult(result);
369
- } else if (args[0] === '--check-only') {
370
- const result = checkLoginOnly({ includeSecrets: args.includes('--with-cookies') });
403
+ } else if (loginArgs[0] === '--check-only') {
404
+ const result = checkLoginOnly({ includeSecrets: loginArgs.includes('--with-cookies') });
371
405
  console.log(JSON.stringify(result, null, 2));
372
- } else if (shouldUseCodexQrLogin(args)) {
406
+ } else if (shouldUseCodexQrLogin(loginArgs)) {
373
407
  const { startCodexQrLogin } = require('../lib/auth/qr-login');
374
- const result = await startCodexQrLogin({ corpId: getArgValue(args, '--corp-id') });
408
+ const result = await startCodexQrLogin({ corpId: getArgValue(loginArgs, '--corp-id') });
375
409
  printLoginResult(result);
376
- } else if (args.includes('--browser')) {
410
+ } else if (loginArgs.includes('--browser')) {
377
411
  const { interactiveLogin } = require('../lib/auth/login');
378
412
  const result = interactiveLogin({ force: true });
379
413
  printLoginResult(result);
380
- } else if (args.includes('--qoder') || args.includes('--wukong')) {
414
+ } else if (loginArgs.includes('--qoder') || loginArgs.includes('--wukong')) {
381
415
  const { codexLogin } = require('../lib/auth/codex-login');
382
- const result = await codexLogin({ tool: args.includes('--qoder') ? 'qoder' : 'wukong' });
416
+ const result = await codexLogin({ tool: loginArgs.includes('--qoder') ? 'qoder' : 'wukong' });
383
417
  printLoginResult(result);
384
- } else if (args.includes('--qr')) {
418
+ } else if (loginArgs.includes('--qr')) {
385
419
  const { qrLogin } = require('../lib/auth/qr-login');
386
- const result = await qrLogin({ corpId: getArgValue(args, '--corp-id') });
420
+ const result = await qrLogin({ corpId: getArgValue(loginArgs, '--corp-id') });
387
421
  console.log(JSON.stringify(result));
388
- } else if (shouldUseAgentLogin(args)) {
422
+ } else if (shouldUseAgentLogin(loginArgs)) {
389
423
  const cachedResult = checkLoginOnly({ includeSecrets: true });
390
424
  if (cachedResult.status === 'ok') {
391
425
  printLoginResult(cachedResult);
@@ -398,17 +432,17 @@ async function main() {
398
432
  printLoginResult(browserResult);
399
433
  } else {
400
434
  const { startCodexQrLogin } = require('../lib/auth/qr-login');
401
- const result = await startCodexQrLogin({ corpId: getArgValue(args, '--corp-id') });
435
+ const result = await startCodexQrLogin({ corpId: getArgValue(loginArgs, '--corp-id') });
402
436
  printLoginResult(result);
403
437
  }
404
438
  }
405
- } else if (shouldUseBrowserHandoffLogin(args)) {
439
+ } else if (shouldUseBrowserHandoffLogin(loginArgs)) {
406
440
  const cachedResult = checkLoginOnly({ includeSecrets: true });
407
441
  if (cachedResult.status === 'ok') {
408
442
  printLoginResult(cachedResult);
409
443
  } else {
410
444
  const { codexLogin } = require('../lib/auth/codex-login');
411
- const result = await codexLogin({ tool: args.includes('--codex') ? 'codex' : undefined });
445
+ const result = await codexLogin({ tool: loginArgs.includes('--codex') ? 'codex' : undefined });
412
446
  printLoginResult(result);
413
447
  }
414
448
  } else {
@@ -418,7 +452,7 @@ async function main() {
418
452
  break;
419
453
  }
420
454
  const { qrLogin } = require('../lib/auth/qr-login');
421
- const result = await qrLogin({ corpId: getArgValue(args, '--corp-id') });
455
+ const result = await qrLogin({ corpId: getArgValue(loginArgs, '--corp-id') });
422
456
  console.log(JSON.stringify(result));
423
457
  }
424
458
  break;
@@ -437,8 +471,9 @@ async function main() {
437
471
  if (subCommand === 'status') {
438
472
  authStatus();
439
473
  } else if (subCommand === 'login') {
440
- const loginType = shouldUseBrowserHandoffLogin(args) ? 'browser' : 'qrcode';
441
- await authLogin({ type: loginType, corpId: getArgValue(args, '--corp-id') });
474
+ const authArgs = [subCommand, ...applyLoginEnvironmentFlags(args.slice(1))];
475
+ const loginType = shouldUseBrowserHandoffLogin(authArgs) ? 'browser' : 'qrcode';
476
+ await authLogin({ type: loginType, corpId: getArgValue(authArgs, '--corp-id') });
442
477
  } else if (subCommand === 'refresh') {
443
478
  authRefresh();
444
479
  } else if (subCommand === 'logout') {
@@ -493,6 +528,12 @@ async function main() {
493
528
  break;
494
529
  }
495
530
 
531
+ case 'corp-efficiency': {
532
+ const { run } = require('../lib/corp-efficiency/corp-efficiency');
533
+ await run(args);
534
+ break;
535
+ }
536
+
496
537
  case 'create-app': {
497
538
  const { run } = require('../lib/app/create-app');
498
539
  await run(args);
@@ -570,7 +611,7 @@ async function main() {
570
611
  case 'publish': {
571
612
  // 参数顺序:<源文件路径> <appType> <formUuid>
572
613
  // publish.js 内部读取顺序:argv[2]=appType, argv[3]=formUuid, argv[4]=sourceFile
573
- const passThroughFlags = new Set(['--skip-lint', '--health-check', '--check', '--open', '--no-open', '--compat', '--modern']);
614
+ const passThroughFlags = new Set(['--skip-lint', '--health-check', '--check', '--open', '--no-open', '--compat', '--modern', '--force']);
574
615
  const forwardedFlags = args.filter(arg => passThroughFlags.has(arg));
575
616
  const filteredArgs = args.filter(arg => !passThroughFlags.has(arg));
576
617
  if (filteredArgs.length < 3) {
@@ -879,6 +920,9 @@ async function main() {
879
920
  } else if (subCommand === 'disable') {
880
921
  const { runDisable } = require('../lib/integration/integration-list');
881
922
  await runDisable(subArgs);
923
+ } else if (subCommand === 'check') {
924
+ const { run: runIntegrationCheck } = require('../lib/integration/integration-check');
925
+ await runIntegrationCheck(subArgs);
882
926
  } else {
883
927
  warn(t('cli.integration_unknown', subCommand));
884
928
  warn(t('cli.integration_help_hint'));
@@ -26,6 +26,7 @@ const { banner, step, label, success, fail, warn, info, error, result, usage, hi
26
26
  const { compileSource } = require('./page-compiler');
27
27
  const { runLintCheck } = require('./page-linter');
28
28
  const { buildPageFile, isAuthoringPath } = require('./page-compat');
29
+ const { fetchFormPageList } = require('./form-navigation');
29
30
  const { parseOpenOption, withBrowserHandoff } = require('../core/browser-handoff');
30
31
 
31
32
  // ── 配置读取 ──────────────────────────────────────────
@@ -43,7 +44,8 @@ function parseArgs() {
43
44
  const skipLint = args.includes('--skip-lint');
44
45
  const healthCheck = args.includes('--health-check') || args.includes('--check');
45
46
  const compat = args.includes('--compat') || args.includes('--modern');
46
- const filteredArgs = args.filter(arg => arg !== '--skip-lint' && arg !== '--health-check' && arg !== '--check' && arg !== '--compat' && arg !== '--modern');
47
+ const force = args.includes('--force');
48
+ const filteredArgs = args.filter(arg => arg !== '--skip-lint' && arg !== '--health-check' && arg !== '--check' && arg !== '--compat' && arg !== '--modern' && arg !== '--force');
47
49
 
48
50
  if (filteredArgs.length < 3) {
49
51
  usage(t('publish.usage'), t('publish.example'));
@@ -56,6 +58,7 @@ function parseArgs() {
56
58
  skipLint,
57
59
  healthCheck,
58
60
  compat,
61
+ force,
59
62
  browserOpenMode: openOption.mode,
60
63
  };
61
64
  }
@@ -522,6 +525,76 @@ function warnDuplicateSourceMismatches(sourcePath) {
522
525
  return mismatches;
523
526
  }
524
527
 
528
+ function normalizeFormType(formType) {
529
+ return String(formType || '').trim().toLowerCase();
530
+ }
531
+
532
+ function findPublishTarget(forms, formUuid) {
533
+ return (Array.isArray(forms) ? forms : []).find((form) => form && form.formUuid === formUuid) || null;
534
+ }
535
+
536
+ function isCustomPageTarget(form) {
537
+ return normalizeFormType(form && form.formType) === 'display';
538
+ }
539
+
540
+ async function verifyPublishTarget(appType, formUuid, authRef, options = {}) {
541
+ if (options.force) {
542
+ return { ok: true, skipped: true };
543
+ }
544
+
545
+ try {
546
+ const forms = await fetchFormPageList(appType, authRef);
547
+ const target = findPublishTarget(forms, formUuid);
548
+
549
+ if (!target) {
550
+ return { ok: false, reason: 'not_found' };
551
+ }
552
+
553
+ if (!isCustomPageTarget(target)) {
554
+ return { ok: false, reason: 'wrong_type', target };
555
+ }
556
+
557
+ return { ok: true, target };
558
+ } catch (targetError) {
559
+ return { ok: false, reason: 'fetch_failed', error: targetError };
560
+ }
561
+ }
562
+
563
+ async function ensurePublishTargetOrExit(appType, formUuid, authRef, options = {}) {
564
+ if (options.force) {
565
+ warn(t('publish.target_check_forced'));
566
+ return null;
567
+ }
568
+
569
+ info(t('publish.target_checking'));
570
+ const check = await verifyPublishTarget(appType, formUuid, authRef, options);
571
+
572
+ if (check.ok) {
573
+ const targetName = check.target.formName || formUuid;
574
+ const targetType = check.target.formType || 'display';
575
+ success(t('publish.target_check_ok', targetName, targetType));
576
+ return check.target;
577
+ }
578
+
579
+ if (check.reason === 'wrong_type') {
580
+ const target = check.target || {};
581
+ const targetName = target.formName || formUuid;
582
+ const targetType = target.formType || '-';
583
+ fail(t('publish.target_type_invalid', formUuid, targetType));
584
+ hint(t('publish.target_type_hint', targetName, targetType));
585
+ } else if (check.reason === 'not_found') {
586
+ fail(t('publish.target_not_found', formUuid));
587
+ } else {
588
+ const message = check.error && check.error.message ? check.error.message : t('common.unknown_error');
589
+ fail(t('publish.target_check_failed', message));
590
+ }
591
+
592
+ hint(t('publish.target_list_hint', appType));
593
+ hint(t('publish.target_force_hint'));
594
+ process.exit(1);
595
+ return null;
596
+ }
597
+
525
598
  function sendHealthCheckRequest(pageUrl, cookies) {
526
599
  return new Promise((resolve) => {
527
600
  const parsedUrl = new URL(pageUrl);
@@ -575,7 +648,7 @@ function sendHealthCheckRequest(pageUrl, cookies) {
575
648
  // ── 主流程 ────────────────────────────────────────────
576
649
 
577
650
  async function main() {
578
- const { appType, formUuid, sourceFile, skipLint, healthCheck, compat, browserOpenMode } = parseArgs();
651
+ const { appType, formUuid, sourceFile, skipLint, healthCheck, compat, force, browserOpenMode } = parseArgs();
579
652
 
580
653
  let sourcePath = path.resolve(sourceFile);
581
654
  if (!fs.existsSync(sourcePath)) {
@@ -625,6 +698,16 @@ async function main() {
625
698
  }
626
699
  let { csrf_token: csrfToken, cookies } = cookieData;
627
700
  let baseUrl = resolveBaseUrl(cookieData);
701
+ const authRef = {
702
+ csrfToken,
703
+ cookies,
704
+ baseUrl,
705
+ cookieData,
706
+ };
707
+ await ensurePublishTargetOrExit(appType, formUuid, authRef, { force });
708
+ csrfToken = authRef.csrfToken;
709
+ cookies = authRef.cookies;
710
+ baseUrl = authRef.baseUrl;
628
711
 
629
712
  banner(t('publish.title'));
630
713
  label('Base URL:', baseUrl);
@@ -744,4 +827,8 @@ if (require.main === module) {
744
827
  module.exports = main;
745
828
  module.exports.findDuplicateSourceMismatches = findDuplicateSourceMismatches;
746
829
  module.exports.sendHealthCheckRequest = sendHealthCheckRequest;
830
+ module.exports.normalizeFormType = normalizeFormType;
831
+ module.exports.findPublishTarget = findPublishTarget;
832
+ module.exports.isCustomPageTarget = isCustomPageTarget;
833
+ module.exports.verifyPublishTarget = verifyPublishTarget;
747
834
  }
@@ -24,7 +24,7 @@ const { saveCookieCache } = require('./login');
24
24
  const { t } = require('../core/i18n');
25
25
  const { warn } = require('../core/chalk');
26
26
 
27
- const { resolveLoginUrl, resolveEndpoint, deriveBaseUrlFromUrl } = require('../core/env-manager');
27
+ const { resolveLoginUrl, resolveEndpoint, deriveBaseUrlFromUrl, getCurrentEnvConfig } = require('../core/env-manager');
28
28
 
29
29
  function shellQuote(value) {
30
30
  return `'${String(value).replace(/'/g, "'\\''")}'`;
@@ -34,9 +34,11 @@ function getTargetCorpId(options = {}, session = {}) {
34
34
  return options.corpId || options.targetCorpId || session.targetCorpId || null;
35
35
  }
36
36
 
37
- function buildCodexPollCommand(sessionFile, targetCorpId) {
37
+ function buildCodexPollCommand(sessionFile, targetCorpId, envName) {
38
38
  const baseCommand = `openyida login --agent-poll ${shellQuote(sessionFile)}`;
39
- return targetCorpId ? `${baseCommand} --corp-id ${shellQuote(targetCorpId)}` : baseCommand;
39
+ const envArg = envName ? ` --env ${shellQuote(envName)}` : '';
40
+ const corpArg = targetCorpId ? ` --corp-id ${shellQuote(targetCorpId)}` : '';
41
+ return `${baseCommand}${envArg}${corpArg}`;
40
42
  }
41
43
 
42
44
  function buildQrImageMarkdown(qrImageFile) {
@@ -55,7 +57,7 @@ function buildAgentQrResponseMarkdown(result) {
55
57
  return lines.join('\n');
56
58
  }
57
59
 
58
- function buildNeedQrScanResult({ qrUrl, qrImageFile, sessionFile, targetCorpId }) {
60
+ function buildNeedQrScanResult({ qrUrl, qrImageFile, sessionFile, targetCorpId, envName }) {
59
61
  const qrImageMarkdown = buildQrImageMarkdown(qrImageFile);
60
62
  const result = {
61
63
  status: 'need_qr_scan',
@@ -65,7 +67,7 @@ function buildNeedQrScanResult({ qrUrl, qrImageFile, sessionFile, targetCorpId }
65
67
  qr_image_file: qrImageFile || null,
66
68
  qr_image_markdown: qrImageMarkdown,
67
69
  session_file: sessionFile,
68
- poll_command: buildCodexPollCommand(sessionFile, targetCorpId),
70
+ poll_command: buildCodexPollCommand(sessionFile, targetCorpId, envName),
69
71
  message: 'Scan the QR code with DingTalk, then run poll_command.',
70
72
  };
71
73
  result.agent_response_markdown = buildAgentQrResponseMarkdown(result);
@@ -366,8 +368,9 @@ async function writeQrCodeImage(url, filePath, options = {}) {
366
368
  function isDingtalkOAuthChallengeUrl(url) {
367
369
  try {
368
370
  const parsedUrl = new URL(url);
369
- return parsedUrl.hostname.endsWith('dingtalk.com') &&
370
- parsedUrl.pathname.startsWith('/oauth2/');
371
+ const hostname = parsedUrl.hostname;
372
+ const isDingtalkDomain = hostname.endsWith('dingtalk.com') || hostname.endsWith('dingtalk.io');
373
+ return isDingtalkDomain && parsedUrl.pathname.startsWith('/oauth2/');
371
374
  } catch {
372
375
  return false;
373
376
  }
@@ -1012,7 +1015,8 @@ function buildCodexCorpInteraction(corpList) {
1012
1015
  };
1013
1016
  }
1014
1017
 
1015
- function buildNeedCorpSelectionResult(sessionFile, corpList) {
1018
+ function buildNeedCorpSelectionResult(sessionFile, corpList, envName) {
1019
+ const envArg = envName ? ` --env ${shellQuote(envName)}` : '';
1016
1020
  return {
1017
1021
  status: 'need_corp_selection',
1018
1022
  handoff_type: 'codex_native_select',
@@ -1024,7 +1028,7 @@ function buildNeedCorpSelectionResult(sessionFile, corpList) {
1024
1028
  main_org: !!corp.mainOrg,
1025
1029
  })),
1026
1030
  interaction: buildCodexCorpInteraction(corpList),
1027
- select_command_template: `openyida login --codex-select ${shellQuote(sessionFile)} --corp-id <corpId>`,
1031
+ select_command_template: `openyida login --codex-select ${shellQuote(sessionFile)}${envArg} --corp-id <corpId>`,
1028
1032
  };
1029
1033
  }
1030
1034
 
@@ -1086,7 +1090,7 @@ async function maybeReturnCorpSelectionAfterExchange(session, sessionFile, optio
1086
1090
  stage: 'pending_corp_switch',
1087
1091
  updatedAt: new Date().toISOString(),
1088
1092
  });
1089
- return buildNeedCorpSelectionResult(sessionFile, corpList);
1093
+ return buildNeedCorpSelectionResult(sessionFile, corpList, session.currentEnvName);
1090
1094
  }
1091
1095
 
1092
1096
  if (!selectedCorp && corpList.length === 1) {
@@ -1100,6 +1104,7 @@ function buildFakeCodexQrLoginResult(options = {}) {
1100
1104
  const sessionId = 'test-session';
1101
1105
  const { sessionFile, qrImageFile } = getCodexQrSessionPaths(sessionId);
1102
1106
  const targetCorpId = getTargetCorpId(options);
1107
+ const currentEnvName = getCurrentEnvConfig().name;
1103
1108
  saveCodexQrSession(sessionFile, {
1104
1109
  schema_version: 1,
1105
1110
  mode: 'codex_qr_login',
@@ -1110,6 +1115,7 @@ function buildFakeCodexQrLoginResult(options = {}) {
1110
1115
  cookieHeader: '',
1111
1116
  context: { type: 'legacy' },
1112
1117
  targetCorpId,
1118
+ currentEnvName,
1113
1119
  createdAt: new Date().toISOString(),
1114
1120
  });
1115
1121
 
@@ -1118,6 +1124,7 @@ function buildFakeCodexQrLoginResult(options = {}) {
1118
1124
  qrImageFile,
1119
1125
  sessionFile,
1120
1126
  targetCorpId,
1127
+ envName: currentEnvName,
1121
1128
  });
1122
1129
  }
1123
1130
 
@@ -1128,6 +1135,7 @@ async function startCodexQrLogin(options = {}) {
1128
1135
 
1129
1136
  const baseUrl = (options.baseUrl || resolveEndpoint(null)).replace(/\/+$/, '');
1130
1137
  const targetCorpId = getTargetCorpId(options);
1138
+ const currentEnvName = getCurrentEnvConfig().name;
1131
1139
  const sessionId = options.sessionId || createCodexQrSessionId();
1132
1140
  const { sessionFile, qrImageFile } = getCodexQrSessionPaths(sessionId);
1133
1141
 
@@ -1157,6 +1165,7 @@ async function startCodexQrLogin(options = {}) {
1157
1165
  cookieHeader,
1158
1166
  context,
1159
1167
  targetCorpId,
1168
+ currentEnvName,
1160
1169
  createdAt: new Date().toISOString(),
1161
1170
  });
1162
1171
 
@@ -1165,6 +1174,7 @@ async function startCodexQrLogin(options = {}) {
1165
1174
  qrImageFile: imageWritten ? qrImageFile : null,
1166
1175
  sessionFile,
1167
1176
  targetCorpId,
1177
+ envName: currentEnvName,
1168
1178
  });
1169
1179
  }
1170
1180
 
@@ -1199,9 +1209,10 @@ async function pollCodexQrLogin(sessionFile, options = {}) {
1199
1209
  corpList,
1200
1210
  stage: 'pending_dingtalk_oauth_org',
1201
1211
  targetCorpId,
1212
+ currentEnvName: session.currentEnvName,
1202
1213
  updatedAt: new Date().toISOString(),
1203
1214
  });
1204
- return buildNeedCorpSelectionResult(sessionFile, corpList);
1215
+ return buildNeedCorpSelectionResult(sessionFile, corpList, session.currentEnvName);
1205
1216
  }
1206
1217
  }
1207
1218
 
@@ -1436,5 +1447,6 @@ module.exports = {
1436
1447
  buildNeedQrScanResult,
1437
1448
  getTargetCorpId,
1438
1449
  deriveAliworkBaseUrl,
1450
+ isDingtalkOAuthChallengeUrl,
1439
1451
  },
1440
1452
  };
@@ -20,7 +20,7 @@ const COMMAND_GROUPS = [
20
20
  id: 'auth',
21
21
  titleKey: 'help.group_auth',
22
22
  commands: [
23
- command('login', ['login'], 'login [--qr|--agent-qr|--codex|--browser] [--corp-id <corpId>]', 'help.cmd_login', {
23
+ command('login', ['login'], 'login [--qr|--agent-qr|--codex|--browser] [--env <name>|--overseas] [--corp-id <corpId>]', 'help.cmd_login', {
24
24
  requiresLogin: false,
25
25
  output: 'json',
26
26
  }),
@@ -31,7 +31,7 @@ const COMMAND_GROUPS = [
31
31
  requiresLogin: false,
32
32
  output: 'text|json',
33
33
  }),
34
- command('env-management', ['env'], 'env <list|show|switch|add|remove>', 'help.cmd_env_management', {
34
+ command('env-management', ['env'], 'env <setup|list|show|switch|add|remove>', 'help.cmd_env_management', {
35
35
  requiresLogin: false,
36
36
  }),
37
37
  ],
@@ -41,6 +41,9 @@ const COMMAND_GROUPS = [
41
41
  titleKey: 'help.group_app',
42
42
  commands: [
43
43
  command('app-list', ['app-list'], 'app-list [--size N]', 'help.cmd_app_list'),
44
+ command('corp-efficiency', ['corp-efficiency'], 'corp-efficiency [overview|details|detail|groups|notify] [options] [--open|--no-open]', 'help.cmd_corp_efficiency', {
45
+ output: 'json',
46
+ }),
44
47
  command('create-app', ['create-app'], 'create-app "<name>"|--name <name> [options] [--open|--no-open]', 'help.cmd_create_app'),
45
48
  command('update-app', ['update-app'], 'update-app <appType> --name "..."', 'help.cmd_update_app'),
46
49
  command('export', ['export'], 'export <appType> [output]', 'help.cmd_export'),
@@ -60,7 +63,7 @@ const COMMAND_GROUPS = [
60
63
  command('build-page', ['build-page'], 'build-page <sourceFile> [--output file|--write]', 'help.cmd_build_page', { requiresLogin: false }),
61
64
  command('check-page', ['check-page'], 'check-page <src> [--compat]', 'help.cmd_check_page', { output: 'text|json' }),
62
65
  command('compile', ['compile'], 'compile <src>', 'help.cmd_compile', { requiresLogin: false }),
63
- command('publish', ['publish'], 'publish <src> <appType> <formUuid> [--health-check] [--open|--no-open]', 'help.cmd_publish'),
66
+ command('publish', ['publish'], 'publish <src> <appType> <formUuid> [--health-check] [--force] [--open|--no-open]', 'help.cmd_publish'),
64
67
  command('update-form-config', ['update-form-config'], 'update-form-config <appType> ...', 'help.cmd_update_form_config'),
65
68
  ],
66
69
  },
@@ -128,6 +131,7 @@ const COMMAND_GROUPS = [
128
131
  titleKey: 'help.group_integration',
129
132
  commands: [
130
133
  command('integration.create', ['integration', 'create'], 'integration create <appType> ...', 'help.cmd_integration'),
134
+ command('integration.check', ['integration', 'check'], 'integration check <appType...>', 'help.cmd_integration_check'),
131
135
  command('dws', ['dws'], 'dws <command> [args]', 'help.cmd_dws'),
132
136
  command('dingtalk-link', ['dingtalk-link'], 'dingtalk-link <url> [--target fullScreen] [--legacy-scheme] [--json]', 'help.cmd_dingtalk_link', {
133
137
  requiresLogin: false,