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 +5 -2
- package/bin/yida.js +67 -23
- package/lib/app/publish.js +89 -2
- package/lib/auth/qr-login.js +23 -11
- package/lib/core/command-manifest.js +7 -3
- package/lib/core/env-cmd.js +171 -18
- package/lib/core/env-manager.js +78 -1
- package/lib/core/locales/ar.js +48 -0
- package/lib/core/locales/de.js +48 -0
- package/lib/core/locales/en.js +50 -1
- package/lib/core/locales/es.js +48 -0
- package/lib/core/locales/fr.js +48 -0
- package/lib/core/locales/hi.js +48 -0
- package/lib/core/locales/ja.js +48 -0
- package/lib/core/locales/ko.js +48 -0
- package/lib/core/locales/pt.js +48 -0
- package/lib/core/locales/vi.js +48 -0
- package/lib/core/locales/zh-HK.js +48 -0
- package/lib/core/locales/zh.js +50 -1
- package/lib/core/utils.js +8 -4
- package/lib/corp-efficiency/corp-efficiency.js +672 -0
- package/lib/integration/integration-api.js +149 -2
- package/lib/integration/integration-check.js +703 -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/sls-log-workbench/SKILL.md +637 -0
- package/yida-skills/skills/sls-log-workbench/sls-query.js +322 -0
- package/yida-skills/skills/yida-corp-efficiency/SKILL.md +100 -0
- package/yida-skills/skills/yida-integration/SKILL.md +14 -0
- package/yida-skills/skills/yida-integration/references/integration-node-schemas.md +21 -1
- package/yida-skills/skills/yida-publish-page/SKILL.md +14 -2
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
|
-
|
|
356
|
-
|
|
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(
|
|
393
|
+
corpId: getArgValue(loginArgs, '--corp-id'),
|
|
360
394
|
});
|
|
361
395
|
printLoginResult(result);
|
|
362
|
-
} else if (
|
|
363
|
-
const sessionFile = getArgValue(
|
|
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(
|
|
400
|
+
corpId: getArgValue(loginArgs, '--corp-id'),
|
|
367
401
|
});
|
|
368
402
|
printLoginResult(result);
|
|
369
|
-
} else if (
|
|
370
|
-
const result = checkLoginOnly({ includeSecrets:
|
|
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(
|
|
406
|
+
} else if (shouldUseCodexQrLogin(loginArgs)) {
|
|
373
407
|
const { startCodexQrLogin } = require('../lib/auth/qr-login');
|
|
374
|
-
const result = await startCodexQrLogin({ corpId: getArgValue(
|
|
408
|
+
const result = await startCodexQrLogin({ corpId: getArgValue(loginArgs, '--corp-id') });
|
|
375
409
|
printLoginResult(result);
|
|
376
|
-
} else if (
|
|
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 (
|
|
414
|
+
} else if (loginArgs.includes('--qoder') || loginArgs.includes('--wukong')) {
|
|
381
415
|
const { codexLogin } = require('../lib/auth/codex-login');
|
|
382
|
-
const result = await codexLogin({ tool:
|
|
416
|
+
const result = await codexLogin({ tool: loginArgs.includes('--qoder') ? 'qoder' : 'wukong' });
|
|
383
417
|
printLoginResult(result);
|
|
384
|
-
} else if (
|
|
418
|
+
} else if (loginArgs.includes('--qr')) {
|
|
385
419
|
const { qrLogin } = require('../lib/auth/qr-login');
|
|
386
|
-
const result = await qrLogin({ corpId: getArgValue(
|
|
420
|
+
const result = await qrLogin({ corpId: getArgValue(loginArgs, '--corp-id') });
|
|
387
421
|
console.log(JSON.stringify(result));
|
|
388
|
-
} else if (shouldUseAgentLogin(
|
|
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(
|
|
435
|
+
const result = await startCodexQrLogin({ corpId: getArgValue(loginArgs, '--corp-id') });
|
|
402
436
|
printLoginResult(result);
|
|
403
437
|
}
|
|
404
438
|
}
|
|
405
|
-
} else if (shouldUseBrowserHandoffLogin(
|
|
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:
|
|
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(
|
|
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
|
|
441
|
-
|
|
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'));
|
package/lib/app/publish.js
CHANGED
|
@@ -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
|
|
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
|
}
|
package/lib/auth/qr-login.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
370
|
-
|
|
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,
|