openyida 2026.6.3-beta.0 → 2026.6.11-beta.0

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
@@ -71,6 +71,13 @@ openyida login
71
71
 
72
72
  In Codex, QoderWork, Qoder, Wukong, Claude Code, OpenCode, Cursor, and other detected AI tools, OpenYida first tries local Chrome/Edge/Chromium CDP when no valid cached login exists. If local CDP is unavailable, it falls back to an AI-dialog QR handoff. The agent should render `qr_image_markdown` or paste `agent_response_markdown` directly in the conversation so the QR code is visible, then run `poll_command` after the user scans it with DingTalk. If image rendering is unavailable, fall back to `qr_url`. The explicit `openyida login --browser` command still prefers CDP first and uses Playwright as an optional browser fallback.
73
73
 
74
+ When the user names a target Yida entry URL, pass it to the login command so OpenYida can select the matching environment and cookie file. For example, Alibaba intranet Yida uses `cookies-alibaba.json`:
75
+
76
+ ```bash
77
+ openyida login https://yida-group.alibaba-inc.com/
78
+ openyida login --alibaba
79
+ ```
80
+
74
81
  The explicit QR polling command remains available:
75
82
 
76
83
  ```bash
@@ -279,7 +286,7 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
279
286
 
280
287
  | Command | Description |
281
288
  |---------|-------------|
282
- | `openyida login [--qr\|--agent-qr\|--codex\|--browser] [--env <name>\|--intl\|--overseas\|--global\|--yidaapps] [--corp-id <corpId>]` | Login (cache first, --browser or --agent-qr when needed) |
289
+ | `openyida login [target-url] [--qr\|--agent-qr\|--codex\|--browser] [--env <name>\|--intl\|--overseas\|--global\|--yidaapps\|--alibaba] [--corp-id <corpId>]` | Login (cache first, --browser or --agent-qr when needed) |
283
290
  | `openyida logout` | Logout / switch account |
284
291
  | `openyida auth <status\|login\|refresh\|logout>` | Login state management |
285
292
  | `openyida org <list\|switch>` | Organization management (list / switch) |
package/bin/yida.js CHANGED
@@ -329,7 +329,60 @@ function getArgValue(cliArgs, name) {
329
329
  return cliArgs[index + 1];
330
330
  }
331
331
 
332
- function applyLoginEnvironmentFlags(cliArgs) {
332
+ function parseLoginTargetArg(value) {
333
+ const raw = String(value || '').trim();
334
+ if (!raw) {return null;}
335
+
336
+ const hasProtocol = /^[a-z][a-z0-9+.-]*:\/\//i.test(raw);
337
+ if (!hasProtocol) {
338
+ if (raw.startsWith('/') || raw.startsWith('.') || raw.includes('\\')) {return null;}
339
+ const hostPart = raw.split('/')[0];
340
+ if (!hostPart.includes('.') && hostPart !== 'localhost') {return null;}
341
+ }
342
+
343
+ try {
344
+ return new URL(hasProtocol ? raw : `https://${raw}`);
345
+ } catch {
346
+ return null;
347
+ }
348
+ }
349
+
350
+ function applyLoginTargetUrl(value) {
351
+ const parsedUrl = parseLoginTargetArg(value);
352
+ if (!parsedUrl) {return false;}
353
+
354
+ const {
355
+ deriveBaseUrlFromDingtalkOAuthUrl,
356
+ inferEnvironmentNameFromUrl,
357
+ inferLoginUrlForBaseUrl,
358
+ normalizeBaseUrl,
359
+ normalizeHostname,
360
+ } = require('../lib/core/env-manager');
361
+
362
+ const targetHref = parsedUrl.href;
363
+ const redirectBaseUrl = deriveBaseUrlFromDingtalkOAuthUrl(targetHref, null);
364
+ const endpoint = normalizeBaseUrl(redirectBaseUrl || parsedUrl.origin, null);
365
+ const inferredEnv = inferEnvironmentNameFromUrl(redirectBaseUrl || targetHref);
366
+
367
+ if (inferredEnv) {
368
+ process.env.OPENYIDA_ENV = inferredEnv;
369
+ }
370
+ if (endpoint) {
371
+ process.env.OPENYIDA_ENDPOINT = endpoint;
372
+ }
373
+
374
+ const host = normalizeHostname(targetHref);
375
+ const isDingtalkLoginHost = host.endsWith('dingtalk.com') || host.endsWith('dingtalk.io');
376
+ const normalizedPath = parsedUrl.pathname.replace(/\/+$/, '') || '/';
377
+ const hasCustomLoginPath = normalizedPath !== '/' && normalizedPath !== '/workPlatform';
378
+ process.env.OPENYIDA_LOGIN_URL = isDingtalkLoginHost || hasCustomLoginPath
379
+ ? targetHref
380
+ : inferLoginUrlForBaseUrl(endpoint || parsedUrl.origin);
381
+
382
+ return true;
383
+ }
384
+
385
+ function applyLoginEnvironmentFlags(cliArgs, options = {}) {
333
386
  const envFlagMap = {
334
387
  '--public': 'public',
335
388
  '--intl': 'intl',
@@ -341,6 +394,19 @@ function applyLoginEnvironmentFlags(cliArgs) {
341
394
  '--internal': 'alibaba',
342
395
  '--intranet': 'alibaba',
343
396
  };
397
+ const valuePassthroughFlags = new Set([
398
+ '--agent-poll',
399
+ '--codex-poll',
400
+ '--agent-select',
401
+ '--codex-select',
402
+ '--corp-id',
403
+ ]);
404
+ const targetUrlFlags = new Set([
405
+ '--endpoint',
406
+ '--base-url',
407
+ '--login-url',
408
+ ]);
409
+ const inferTargetUrl = !!options.inferTargetUrl;
344
410
  const filteredArgs = [];
345
411
 
346
412
  for (let index = 0; index < cliArgs.length; index++) {
@@ -353,10 +419,28 @@ function applyLoginEnvironmentFlags(cliArgs) {
353
419
  }
354
420
  continue;
355
421
  }
422
+ if (inferTargetUrl && targetUrlFlags.has(arg)) {
423
+ const targetUrl = cliArgs[index + 1];
424
+ if (targetUrl && !targetUrl.startsWith('--') && applyLoginTargetUrl(targetUrl)) {
425
+ index++;
426
+ continue;
427
+ }
428
+ }
429
+ if (valuePassthroughFlags.has(arg)) {
430
+ filteredArgs.push(arg);
431
+ if (cliArgs[index + 1] && !cliArgs[index + 1].startsWith('--')) {
432
+ filteredArgs.push(cliArgs[index + 1]);
433
+ index++;
434
+ }
435
+ continue;
436
+ }
356
437
  if (envFlagMap[arg]) {
357
438
  process.env.OPENYIDA_ENV = envFlagMap[arg];
358
439
  continue;
359
440
  }
441
+ if (inferTargetUrl && !arg.startsWith('--') && applyLoginTargetUrl(arg)) {
442
+ continue;
443
+ }
360
444
  filteredArgs.push(arg);
361
445
  }
362
446
 
@@ -455,7 +539,7 @@ async function main() {
455
539
 
456
540
  case 'login': {
457
541
  const { checkLoginOnly } = require('../lib/auth/login');
458
- const loginArgs = applyLoginEnvironmentFlags(args);
542
+ const loginArgs = applyLoginEnvironmentFlags(args, { inferTargetUrl: true });
459
543
  if (loginArgs.includes('--agent-poll') || loginArgs.includes('--codex-poll')) {
460
544
  const sessionFile = getArgValue(loginArgs, '--agent-poll') || getArgValue(loginArgs, '--codex-poll');
461
545
  const { pollCodexQrLogin } = require('../lib/auth/qr-login');
@@ -559,7 +643,7 @@ async function main() {
559
643
  if (subCommand === 'status') {
560
644
  authStatus();
561
645
  } else if (subCommand === 'login') {
562
- const authArgs = applyLoginEnvironmentFlags(args.slice(1));
646
+ const authArgs = applyLoginEnvironmentFlags(args.slice(1), { inferTargetUrl: true });
563
647
  let loginType = 'qrcode';
564
648
  if (authArgs.includes('--codex')) {
565
649
  loginType = 'codex';
@@ -21,7 +21,7 @@ const COMMAND_GROUPS = [
21
21
  id: 'auth',
22
22
  titleKey: 'help.group_auth',
23
23
  commands: [
24
- command('login', ['login'], 'login [--qr|--agent-qr|--codex|--browser] [--env <name>|--intl|--overseas|--global|--yidaapps] [--corp-id <corpId>]', 'help.cmd_login', {
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
25
  requiresLogin: false,
26
26
  output: 'json',
27
27
  }),
@@ -265,6 +265,34 @@ function isYidaAppsHost(hostname) {
265
265
  return host === 'yidaapps.com' || host.endsWith('.yidaapps.com');
266
266
  }
267
267
 
268
+ function inferEnvironmentNameFromUrl(value) {
269
+ const redirectBaseUrl = deriveBaseUrlFromDingtalkOAuthUrl(value, null);
270
+ if (redirectBaseUrl) {
271
+ return inferEnvironmentNameFromUrl(redirectBaseUrl);
272
+ }
273
+
274
+ const host = normalizeHostname(value);
275
+ if (!host) { return null; }
276
+
277
+ if (host === 'login.dingtalk.io' || host.endsWith('.dingtalk.io')) {
278
+ return 'intl';
279
+ }
280
+ if (host === 'yidaapps.com' || host.endsWith('.yidaapps.com')) {
281
+ return 'intl';
282
+ }
283
+ if (host === 'aliwork.com' || host.endsWith('.aliwork.com')) {
284
+ return 'public';
285
+ }
286
+ if (host === 'yida-group.alibaba-inc.com') {
287
+ return 'alibaba';
288
+ }
289
+ if (host.endsWith('.alibaba-inc.com') && isYidaServiceHost(host)) {
290
+ return 'alibaba';
291
+ }
292
+
293
+ return null;
294
+ }
295
+
268
296
  function isDefaultWorkPlatformLoginUrl(loginUrl, baseUrl) {
269
297
  const loginOrigin = normalizeBaseUrl(loginUrl, null);
270
298
  const baseOrigin = normalizeBaseUrl(baseUrl, null);
@@ -564,6 +592,7 @@ module.exports = {
564
592
  normalizeHostname,
565
593
  isYidaServiceHost,
566
594
  isYidaAppsHost,
595
+ inferEnvironmentNameFromUrl,
567
596
  inferLoginUrlForBaseUrl,
568
597
  deriveBaseUrlFromDingtalkOAuthUrl,
569
598
  deriveBaseUrlFromCookies,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openyida",
3
- "version": "2026.6.3-beta.0",
3
+ "version": "2026.6.11-beta.0",
4
4
  "description": "OpenYida CLI - 宜搭低代码 AI 开发工具(安装即用,零配置)",
5
5
  "bin": {
6
6
  "openyida": "bin/yida.js",
@@ -67,6 +67,8 @@ openyida login --check-only --json
67
67
 
68
68
  `openyida env --json` 用于确认当前 AI 工具、项目根目录、配置文件和登录态拆解项;`openyida login --check-only --json` 只读取本地登录缓存,不触发登录、不打开浏览器、不创建任何资源。
69
69
 
70
+ 若用户明确要求登录某个宜搭入口 URL,登录命令必须携带该 URL 或对应环境 flag。例如 `https://yida-group.alibaba-inc.com/` 是阿里内网宜搭,应执行 `openyida login https://yida-group.alibaba-inc.com/` 或 `openyida login --alibaba`,不要退化成裸 `openyida login`,否则会落到默认公有云 `www.aliwork.com` / `cookies-public.json`。
71
+
70
72
  **悟空(Wukong)降级规则**:如果在悟空环境中本地命令执行入口连续失败,不要继续重试,也不要判断为 OpenYida 登录失败。进入人工协同诊断模式,请用户在可用终端执行以下低风险命令并贴回输出:
71
73
 
72
74
  ```bash
@@ -48,6 +48,15 @@ openyida login
48
48
 
49
49
  默认登录路径不需要 Playwright:优先复用缓存;Codex、Qoder、悟空、Claude Code、OpenCode、Cursor 等可检测到的 AI 工具先尝试本地 Chrome/Edge/Chromium CDP 登录,CDP 不可用时再使用二维码 handoff;其他终端环境使用二维码登录。`openyida login --browser` 优先使用本地 Chrome/Edge/Chromium CDP,CDP 不可用时才用 Playwright 兜底。
50
50
 
51
+ 若用户明确给出宜搭入口 URL,必须把该 URL 传给登录命令,或使用对应环境 flag;不要退化成裸 `openyida login`:
52
+
53
+ ```bash
54
+ openyida login https://yida-group.alibaba-inc.com/
55
+ openyida login --alibaba
56
+ ```
57
+
58
+ `https://yida-group.alibaba-inc.com/` 属于阿里内网宜搭,登录态应写入 `cookies-alibaba.json`;`www.aliwork.com`/`cookies-public.json` 表示走了默认公有云环境。
59
+
51
60
  ### AI 工具二维码登录模式
52
61
 
53
62
  在 AI 对话框环境中没有有效缓存,且本地 CDP 浏览器登录不可用时,`openyida login` 返回 `need_qr_scan` JSON,包含 `qr_image_markdown`、`agent_response_markdown`、`qr_image_file`、`qr_url`、`poll_command` 和 `session_file`。