openyida 2026.5.6-beta.2 → 2026.5.6-beta.3

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
@@ -206,7 +206,7 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
206
206
  | `openyida env [--json]` | Detect the active AI tool environment and login state |
207
207
  | `openyida env <list\|show\|switch\|add\|remove>` | Manage public/private Yida environment profiles |
208
208
  | `openyida commands [--json]` | Emit the machine-readable command manifest |
209
- | `openyida login [--qr\|--browser] [--corp-id <corpId>]` | Log in to Yida |
209
+ | `openyida login [--qr\|--browser\|--import-cookies <file>] [--corp-id <corpId>]` | Log in to Yida |
210
210
  | `openyida logout` | Log out or switch account |
211
211
  | `openyida auth <status\|login\|refresh\|logout>` | Manage login status |
212
212
  | `openyida org list` | List accessible organizations |
package/bin/yida.js CHANGED
@@ -207,9 +207,16 @@ function printLoginResult(result) {
207
207
  console.log(JSON.stringify({
208
208
  status: result.status,
209
209
  handoff_type: result.handoff_type || 'browser',
210
+ handoff_version: result.handoff_version,
210
211
  can_auto_use: false,
211
212
  browser: result.browser,
212
213
  login_url: result.login_url,
214
+ cookie_file: result.cookie_file,
215
+ cookie_import_command: result.cookie_import_command,
216
+ post_login_check_command: result.post_login_check_command,
217
+ cookie_domains: result.cookie_domains,
218
+ required_cookie_names: result.required_cookie_names,
219
+ cookie_export_format: result.cookie_export_format,
213
220
  message: result.message,
214
221
  }));
215
222
  return;
@@ -222,6 +229,7 @@ function printLoginResult(result) {
222
229
  user_id: result && result.user_id,
223
230
  csrf_token: result && result.csrf_token ? `${result.csrf_token.slice(0, 16)}...` : undefined,
224
231
  cookies_count: Array.isArray(result && result.cookies) ? result.cookies.length : 0,
232
+ cookie_file: result && result.cookie_file,
225
233
  };
226
234
  console.log(JSON.stringify(summary));
227
235
  }
@@ -289,10 +297,21 @@ async function main() {
289
297
  }
290
298
 
291
299
  case 'login': {
292
- const { checkLoginOnly } = require('../lib/auth/login');
300
+ const { checkLoginOnly, importCookieCache } = require('../lib/auth/login');
293
301
  if (args[0] === '--check-only') {
294
302
  const result = checkLoginOnly({ includeSecrets: args.includes('--with-cookies') });
295
303
  console.log(JSON.stringify(result, null, 2));
304
+ } else if (args.includes('--import-cookies')) {
305
+ const cookieJsonPath = getArgValue(args, '--import-cookies');
306
+ if (!cookieJsonPath) {
307
+ throw new Error('Usage: openyida login --import-cookies <cookies.json> [--base-url <url>]');
308
+ }
309
+ const fs = require('fs');
310
+ const path = require('path');
311
+ const resolvedPath = path.resolve(process.cwd(), cookieJsonPath);
312
+ const payload = JSON.parse(fs.readFileSync(resolvedPath, 'utf8'));
313
+ const result = importCookieCache(payload, { baseUrl: getArgValue(args, '--base-url') });
314
+ printLoginResult(result);
296
315
  } else if (args.includes('--browser') || args.includes('--codex') || args.includes('--qoder') || args.includes('--wukong')) {
297
316
  const { codexLogin } = require('../lib/auth/codex-login');
298
317
  const result = await codexLogin();
@@ -7,13 +7,35 @@
7
7
 
8
8
  'use strict';
9
9
 
10
- const { detectActiveTool } = require('../core/utils');
11
- const { resolveLoginUrl } = require('../core/env-manager');
10
+ const { detectActiveTool, findProjectRoot } = require('../core/utils');
11
+ const { getCookieFilePath, resolveLoginUrl } = require('../core/env-manager');
12
12
  const { t } = require('../core/i18n');
13
13
 
14
14
  /** 支持内置浏览器 handoff 的工具列表 */
15
15
  const BROWSER_HANDOFF_TOOLS = ['codex', 'qoder', 'wukong'];
16
16
 
17
+ function resolveUrlOrigin(url) {
18
+ try {
19
+ return new URL(url).origin;
20
+ } catch {
21
+ return null;
22
+ }
23
+ }
24
+
25
+ function buildCookieDomains(loginUrl) {
26
+ const domains = ['.aliwork.com', 'www.aliwork.com'];
27
+ const origin = resolveUrlOrigin(loginUrl);
28
+ if (!origin) {
29
+ return domains;
30
+ }
31
+
32
+ const hostname = new URL(origin).hostname;
33
+ if (!domains.includes(hostname)) {
34
+ domains.push(hostname);
35
+ }
36
+ return domains;
37
+ }
38
+
17
39
  /**
18
40
  * 内置浏览器登录入口:不依赖 Playwright,也不走终端二维码接口。
19
41
  * 支持 Codex、Qoder 和悟空环境。
@@ -32,10 +54,19 @@ async function codexLogin(options = {}) {
32
54
  }
33
55
 
34
56
  const loginUrl = options.loginUrl || resolveLoginUrl();
57
+ const projectRoot = findProjectRoot();
58
+ const cookieFile = getCookieFilePath(projectRoot);
59
+ const loginOrigin = resolveUrlOrigin(loginUrl);
60
+ const cookieImportCommand = [
61
+ 'openyida login --import-cookies <cookies.json>',
62
+ loginOrigin ? `--base-url ${loginOrigin}` : null,
63
+ ].filter(Boolean).join(' ');
35
64
 
36
65
  info(t('codex_login.no_playwright'));
37
66
  info(t('codex_login.using_browser'));
38
67
  label('URL', loginUrl);
68
+ label('Cookie file', cookieFile);
69
+ label('Import command', cookieImportCommand);
39
70
  hint(t('codex_login.browser_handoff_hint'));
40
71
 
41
72
  const browserName = toolName && BROWSER_HANDOFF_TOOLS.includes(toolName) ? toolName : 'codex';
@@ -43,9 +74,16 @@ async function codexLogin(options = {}) {
43
74
  return {
44
75
  status: 'need_codex_browser_login',
45
76
  handoff_type: 'browser',
77
+ handoff_version: 2,
46
78
  can_auto_use: false,
47
79
  login_url: loginUrl,
48
80
  browser: browserName,
81
+ cookie_file: cookieFile,
82
+ cookie_import_command: cookieImportCommand,
83
+ post_login_check_command: 'openyida login --check-only --json',
84
+ cookie_domains: buildCookieDomains(loginUrl),
85
+ required_cookie_names: ['tianshu_csrf_token'],
86
+ cookie_export_format: 'browser_context_cookies_json',
49
87
  message: t('codex_login.handoff_message'),
50
88
  };
51
89
  }
package/lib/auth/login.js CHANGED
@@ -11,6 +11,7 @@
11
11
  * refreshCsrfFromCache() - 从缓存 Cookie 重新提取 csrf_token
12
12
  * interactiveLogin() - 打开浏览器扫码登录(需要用户自行安装 playwright)
13
13
  * saveCookieCache() - 保存 Cookie 到本地缓存(供 qr-login.js 使用)
14
+ * importCookieCache() - 从浏览器导出的 Cookie JSON 导入本地缓存
14
15
  * logout() - 退出登录,清空 Cookie 缓存
15
16
  */
16
17
 
@@ -51,6 +52,122 @@ function saveCookieCache(cookies, baseUrl) {
51
52
  fs.writeFileSync(cookieFile, JSON.stringify({ cookies, base_url: baseUrl }, null, 2), 'utf-8');
52
53
  const { c } = require('../core/chalk');
53
54
  process.stderr.write(` ${c.green}✔${c.reset} Cookie saved to ${c.dim}${cookieFile}${c.reset}\n`);
55
+
56
+ return {
57
+ cookie_file: cookieFile,
58
+ base_url: baseUrl,
59
+ cookies_count: Array.isArray(cookies) ? cookies.length : 0,
60
+ };
61
+ }
62
+
63
+ function normalizeBaseUrl(value) {
64
+ if (!value) {
65
+ return null;
66
+ }
67
+ try {
68
+ return new URL(value).origin.replace(/\/+$/, '');
69
+ } catch {
70
+ throw new Error(`Invalid base URL: ${value}`);
71
+ }
72
+ }
73
+
74
+ function baseUrlFromCookieDomain(domain) {
75
+ if (!domain || typeof domain !== 'string') {
76
+ return null;
77
+ }
78
+
79
+ const host = domain.replace(/^\./, '').trim();
80
+ if (!host) {
81
+ return null;
82
+ }
83
+ if (host === 'aliwork.com') {
84
+ return DEFAULT_BASE_URL;
85
+ }
86
+ return `https://${host}`;
87
+ }
88
+
89
+ function inferBaseUrlFromCookies(cookies, fallbackBaseUrl) {
90
+ const fallback = normalizeBaseUrl(fallbackBaseUrl || DEFAULT_BASE_URL);
91
+ if (!Array.isArray(cookies) || cookies.length === 0) {
92
+ return fallback;
93
+ }
94
+
95
+ const preferredNames = ['yida_user_cookie', 'tianshu_csrf_token'];
96
+ for (const name of preferredNames) {
97
+ const cookie = cookies.find(item => item && item.name === name && item.domain);
98
+ const baseUrl = cookie ? baseUrlFromCookieDomain(cookie.domain) : null;
99
+ if (baseUrl) {
100
+ return normalizeBaseUrl(baseUrl);
101
+ }
102
+ }
103
+
104
+ const domainCookie = cookies.find(item => item && item.domain);
105
+ const domainBaseUrl = domainCookie ? baseUrlFromCookieDomain(domainCookie.domain) : null;
106
+ return domainBaseUrl ? normalizeBaseUrl(domainBaseUrl) : fallback;
107
+ }
108
+
109
+ function normalizeBrowserCookiePayload(payload) {
110
+ let source = null;
111
+ if (payload && Array.isArray(payload.cookies)) {
112
+ source = payload;
113
+ } else if (payload && payload.storageState && Array.isArray(payload.storageState.cookies)) {
114
+ source = payload.storageState;
115
+ }
116
+
117
+ let cookies = null;
118
+ if (Array.isArray(payload)) {
119
+ cookies = payload;
120
+ } else if (source) {
121
+ cookies = source.cookies;
122
+ }
123
+
124
+ if (!cookies) {
125
+ throw new Error('Cookie JSON must be a browser cookies array or an object with a cookies array.');
126
+ }
127
+ if (cookies.length === 0) {
128
+ throw new Error('Cookie JSON is empty.');
129
+ }
130
+
131
+ for (const cookie of cookies) {
132
+ if (!cookie || typeof cookie.name !== 'string' || typeof cookie.value !== 'string') {
133
+ throw new Error('Each cookie must contain string name and value fields.');
134
+ }
135
+ }
136
+
137
+ const baseUrl = source
138
+ ? source.base_url || source.baseUrl || source.origin || source.url
139
+ : null;
140
+
141
+ return { cookies, baseUrl };
142
+ }
143
+
144
+ function importCookieCache(payload, options = {}) {
145
+ const normalized = normalizeBrowserCookiePayload(payload);
146
+ let baseUrl;
147
+ if (options.baseUrl) {
148
+ baseUrl = normalizeBaseUrl(options.baseUrl);
149
+ } else if (normalized.baseUrl) {
150
+ baseUrl = normalizeBaseUrl(normalized.baseUrl);
151
+ } else {
152
+ baseUrl = inferBaseUrlFromCookies(normalized.cookies, DEFAULT_BASE_URL);
153
+ }
154
+ const { csrfToken, corpId, userId } = extractInfoFromCookies(normalized.cookies);
155
+
156
+ if (!csrfToken) {
157
+ throw new Error('No tianshu_csrf_token found in browser cookies. Please finish Yida login in the browser and export cookies again.');
158
+ }
159
+
160
+ const saveResult = saveCookieCache(normalized.cookies, baseUrl);
161
+ return {
162
+ ok: true,
163
+ csrf_token: csrfToken,
164
+ corp_id: corpId,
165
+ user_id: userId,
166
+ base_url: baseUrl,
167
+ cookies: normalized.cookies,
168
+ cookies_count: normalized.cookies.length,
169
+ cookie_file: saveResult.cookie_file,
170
+ };
54
171
  }
55
172
 
56
173
  // ── 仅检查登录态 ──────────────────────────────────────
@@ -191,7 +308,7 @@ function ensureLogin() {
191
308
  if (cookieData && cookieData.cookies) {
192
309
  const { csrfToken, corpId, userId } = extractInfoFromCookies(cookieData.cookies);
193
310
  if (csrfToken) {
194
- const { c: cc, success: chalkSuccess2, label: chalkLabel } = require('../core/chalk');
311
+ const { success: chalkSuccess2, label: chalkLabel } = require('../core/chalk');
195
312
  chalkSuccess2(t('login.using_cache'));
196
313
  chalkLabel('CSRF', `${csrfToken.slice(0, 16)}…`);
197
314
  if (corpId) {chalkLabel('Corp ID', corpId);}
@@ -270,7 +387,7 @@ function interactiveLogin() {
270
387
  return null;
271
388
  }
272
389
 
273
- const { c: lc, info: chalkInfo, label: chalkLabel2 } = require('../core/chalk');
390
+ const { info: chalkInfo, label: chalkLabel2 } = require('../core/chalk');
274
391
  chalkInfo(t('login.browser_opening'));
275
392
  chalkLabel2('URL', loginUrl);
276
393
 
@@ -422,5 +539,8 @@ module.exports = {
422
539
  refreshCsrfFromCache,
423
540
  interactiveLogin,
424
541
  saveCookieCache,
542
+ importCookieCache,
543
+ normalizeBrowserCookiePayload,
544
+ inferBaseUrlFromCookies,
425
545
  logout,
426
546
  };
@@ -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|--browser] [--corp-id <corpId>]', 'help.cmd_login', {
23
+ command('login', ['login'], 'login [--qr|--browser|--import-cookies <file>] [--corp-id <corpId>]', 'help.cmd_login', {
24
24
  requiresLogin: false,
25
25
  output: 'json',
26
26
  }),
@@ -586,12 +586,12 @@ module.exports = {
586
586
  },
587
587
  },
588
588
  codex_login: {
589
- title: ' openyida login --codex - Codex Login Mode',
590
- not_codex: 'Current environment is not detected as Codex; returning a Codex browser login handoff only.',
591
- no_playwright: 'Codex mode does not require Playwright or a separate Chromium install.',
592
- using_browser: 'Use the Codex in-app browser to open the Yida login page and scan with DingTalk.',
593
- browser_handoff_hint: 'After browser login succeeds, the Codex session is logged in. CLI Cookie export requires a Codex browser bridge.',
594
- handoff_message: 'Open login_url in the Codex in-app browser and scan with DingTalk.',
589
+ title: ' openyida login --browser - In-app Browser Login Mode',
590
+ not_codex: 'Current environment is not detected as Codex/Qoder/Wukong; returning a browser login handoff only.',
591
+ no_playwright: 'In-app browser login does not require Playwright or a separate Chromium install.',
592
+ using_browser: 'Use the current in-app browser to open the Yida login page and scan with DingTalk.',
593
+ browser_handoff_hint: 'After browser login succeeds, export browser context cookies and run cookie_import_command to persist CLI login.',
594
+ handoff_message: 'Open login_url in the in-app browser, scan with DingTalk, then export cookies and run cookie_import_command.',
595
595
  cache_available: 'Existing CLI Cookie cache is available; no browser login needed.',
596
596
  },
597
597
  };
@@ -586,12 +586,12 @@ module.exports = {
586
586
  },
587
587
  },
588
588
  codex_login: {
589
- title: ' openyida login --codex - Codex Login Mode',
590
- not_codex: 'Current environment is not detected as Codex; returning a Codex browser login handoff only.',
591
- no_playwright: 'Codex mode does not require Playwright or a separate Chromium install.',
592
- using_browser: 'Use the Codex in-app browser to open the Yida login page and scan with DingTalk.',
593
- browser_handoff_hint: 'After browser login succeeds, the Codex session is logged in. CLI Cookie export requires a Codex browser bridge.',
594
- handoff_message: 'Open login_url in the Codex in-app browser and scan with DingTalk.',
589
+ title: ' openyida login --browser - In-app Browser Login Mode',
590
+ not_codex: 'Current environment is not detected as Codex/Qoder/Wukong; returning a browser login handoff only.',
591
+ no_playwright: 'In-app browser login does not require Playwright or a separate Chromium install.',
592
+ using_browser: 'Use the current in-app browser to open the Yida login page and scan with DingTalk.',
593
+ browser_handoff_hint: 'After browser login succeeds, export browser context cookies and run cookie_import_command to persist CLI login.',
594
+ handoff_message: 'Open login_url in the in-app browser, scan with DingTalk, then export cookies and run cookie_import_command.',
595
595
  cache_available: 'Existing CLI Cookie cache is available; no browser login needed.',
596
596
  },
597
597
  };
@@ -1330,12 +1330,12 @@ Options:
1330
1330
  example2: ' openyida create-process "APP_XXX" --formUuid FORM-YYY process-definition.json',
1331
1331
  },
1332
1332
  codex_login: {
1333
- title: ' openyida login --codex - Codex Login Mode',
1334
- not_codex: 'Current environment is not detected as Codex; returning a Codex browser login handoff only.',
1335
- no_playwright: 'Codex mode does not require Playwright or a separate Chromium install.',
1336
- using_browser: 'Use the Codex in-app browser to open the Yida login page and scan with DingTalk.',
1337
- browser_handoff_hint: 'After browser login succeeds, the Codex session is logged in. CLI Cookie export requires a Codex browser bridge.',
1338
- handoff_message: 'Open login_url in the Codex in-app browser and scan with DingTalk.',
1333
+ title: ' openyida login --browser - In-app Browser Login Mode',
1334
+ not_codex: 'Current environment is not detected as Codex/Qoder/Wukong; returning a browser login handoff only.',
1335
+ no_playwright: 'In-app browser login does not require Playwright or a separate Chromium install.',
1336
+ using_browser: 'Use the current in-app browser to open the Yida login page and scan with DingTalk.',
1337
+ browser_handoff_hint: 'After browser login succeeds, export browser context cookies and run cookie_import_command to persist CLI login.',
1338
+ handoff_message: 'Open login_url in the in-app browser, scan with DingTalk, then export cookies and run cookie_import_command.',
1339
1339
  cache_available: 'Existing CLI Cookie cache is available; no browser login needed.',
1340
1340
  },
1341
1341
  };
@@ -586,12 +586,12 @@ module.exports = {
586
586
  },
587
587
  },
588
588
  codex_login: {
589
- title: ' openyida login --codex - Codex Login Mode',
590
- not_codex: 'Current environment is not detected as Codex; returning a Codex browser login handoff only.',
591
- no_playwright: 'Codex mode does not require Playwright or a separate Chromium install.',
592
- using_browser: 'Use the Codex in-app browser to open the Yida login page and scan with DingTalk.',
593
- browser_handoff_hint: 'After browser login succeeds, the Codex session is logged in. CLI Cookie export requires a Codex browser bridge.',
594
- handoff_message: 'Open login_url in the Codex in-app browser and scan with DingTalk.',
589
+ title: ' openyida login --browser - In-app Browser Login Mode',
590
+ not_codex: 'Current environment is not detected as Codex/Qoder/Wukong; returning a browser login handoff only.',
591
+ no_playwright: 'In-app browser login does not require Playwright or a separate Chromium install.',
592
+ using_browser: 'Use the current in-app browser to open the Yida login page and scan with DingTalk.',
593
+ browser_handoff_hint: 'After browser login succeeds, export browser context cookies and run cookie_import_command to persist CLI login.',
594
+ handoff_message: 'Open login_url in the in-app browser, scan with DingTalk, then export cookies and run cookie_import_command.',
595
595
  cache_available: 'Existing CLI Cookie cache is available; no browser login needed.',
596
596
  },
597
597
  };
@@ -586,12 +586,12 @@ module.exports = {
586
586
  },
587
587
  },
588
588
  codex_login: {
589
- title: ' openyida login --codex - Codex Login Mode',
590
- not_codex: 'Current environment is not detected as Codex; returning a Codex browser login handoff only.',
591
- no_playwright: 'Codex mode does not require Playwright or a separate Chromium install.',
592
- using_browser: 'Use the Codex in-app browser to open the Yida login page and scan with DingTalk.',
593
- browser_handoff_hint: 'After browser login succeeds, the Codex session is logged in. CLI Cookie export requires a Codex browser bridge.',
594
- handoff_message: 'Open login_url in the Codex in-app browser and scan with DingTalk.',
589
+ title: ' openyida login --browser - In-app Browser Login Mode',
590
+ not_codex: 'Current environment is not detected as Codex/Qoder/Wukong; returning a browser login handoff only.',
591
+ no_playwright: 'In-app browser login does not require Playwright or a separate Chromium install.',
592
+ using_browser: 'Use the current in-app browser to open the Yida login page and scan with DingTalk.',
593
+ browser_handoff_hint: 'After browser login succeeds, export browser context cookies and run cookie_import_command to persist CLI login.',
594
+ handoff_message: 'Open login_url in the in-app browser, scan with DingTalk, then export cookies and run cookie_import_command.',
595
595
  cache_available: 'Existing CLI Cookie cache is available; no browser login needed.',
596
596
  },
597
597
  };
@@ -586,12 +586,12 @@ module.exports = {
586
586
  },
587
587
  },
588
588
  codex_login: {
589
- title: ' openyida login --codex - Codex Login Mode',
590
- not_codex: 'Current environment is not detected as Codex; returning a Codex browser login handoff only.',
591
- no_playwright: 'Codex mode does not require Playwright or a separate Chromium install.',
592
- using_browser: 'Use the Codex in-app browser to open the Yida login page and scan with DingTalk.',
593
- browser_handoff_hint: 'After browser login succeeds, the Codex session is logged in. CLI Cookie export requires a Codex browser bridge.',
594
- handoff_message: 'Open login_url in the Codex in-app browser and scan with DingTalk.',
589
+ title: ' openyida login --browser - In-app Browser Login Mode',
590
+ not_codex: 'Current environment is not detected as Codex/Qoder/Wukong; returning a browser login handoff only.',
591
+ no_playwright: 'In-app browser login does not require Playwright or a separate Chromium install.',
592
+ using_browser: 'Use the current in-app browser to open the Yida login page and scan with DingTalk.',
593
+ browser_handoff_hint: 'After browser login succeeds, export browser context cookies and run cookie_import_command to persist CLI login.',
594
+ handoff_message: 'Open login_url in the in-app browser, scan with DingTalk, then export cookies and run cookie_import_command.',
595
595
  cache_available: 'Existing CLI Cookie cache is available; no browser login needed.',
596
596
  },
597
597
  };
@@ -980,12 +980,12 @@ openyida - Yida CLI ツール
980
980
  },
981
981
  },
982
982
  codex_login: {
983
- title: ' openyida login --codex - Codex Login Mode',
984
- not_codex: 'Current environment is not detected as Codex; returning a Codex browser login handoff only.',
985
- no_playwright: 'Codex mode does not require Playwright or a separate Chromium install.',
986
- using_browser: 'Use the Codex in-app browser to open the Yida login page and scan with DingTalk.',
987
- browser_handoff_hint: 'After browser login succeeds, the Codex session is logged in. CLI Cookie export requires a Codex browser bridge.',
988
- handoff_message: 'Open login_url in the Codex in-app browser and scan with DingTalk.',
983
+ title: ' openyida login --browser - In-app Browser Login Mode',
984
+ not_codex: 'Current environment is not detected as Codex/Qoder/Wukong; returning a browser login handoff only.',
985
+ no_playwright: 'In-app browser login does not require Playwright or a separate Chromium install.',
986
+ using_browser: 'Use the current in-app browser to open the Yida login page and scan with DingTalk.',
987
+ browser_handoff_hint: 'After browser login succeeds, export browser context cookies and run cookie_import_command to persist CLI login.',
988
+ handoff_message: 'Open login_url in the in-app browser, scan with DingTalk, then export cookies and run cookie_import_command.',
989
989
  cache_available: 'Existing CLI Cookie cache is available; no browser login needed.',
990
990
  },
991
991
  };
@@ -589,12 +589,12 @@ module.exports = {
589
589
  },
590
590
  },
591
591
  codex_login: {
592
- title: ' openyida login --codex - Codex Login Mode',
593
- not_codex: 'Current environment is not detected as Codex; returning a Codex browser login handoff only.',
594
- no_playwright: 'Codex mode does not require Playwright or a separate Chromium install.',
595
- using_browser: 'Use the Codex in-app browser to open the Yida login page and scan with DingTalk.',
596
- browser_handoff_hint: 'After browser login succeeds, the Codex session is logged in. CLI Cookie export requires a Codex browser bridge.',
597
- handoff_message: 'Open login_url in the Codex in-app browser and scan with DingTalk.',
592
+ title: ' openyida login --browser - In-app Browser Login Mode',
593
+ not_codex: 'Current environment is not detected as Codex/Qoder/Wukong; returning a browser login handoff only.',
594
+ no_playwright: 'In-app browser login does not require Playwright or a separate Chromium install.',
595
+ using_browser: 'Use the current in-app browser to open the Yida login page and scan with DingTalk.',
596
+ browser_handoff_hint: 'After browser login succeeds, export browser context cookies and run cookie_import_command to persist CLI login.',
597
+ handoff_message: 'Open login_url in the in-app browser, scan with DingTalk, then export cookies and run cookie_import_command.',
598
598
  cache_available: 'Existing CLI Cookie cache is available; no browser login needed.',
599
599
  },
600
600
  };
@@ -586,12 +586,12 @@ module.exports = {
586
586
  },
587
587
  },
588
588
  codex_login: {
589
- title: ' openyida login --codex - Codex Login Mode',
590
- not_codex: 'Current environment is not detected as Codex; returning a Codex browser login handoff only.',
591
- no_playwright: 'Codex mode does not require Playwright or a separate Chromium install.',
592
- using_browser: 'Use the Codex in-app browser to open the Yida login page and scan with DingTalk.',
593
- browser_handoff_hint: 'After browser login succeeds, the Codex session is logged in. CLI Cookie export requires a Codex browser bridge.',
594
- handoff_message: 'Open login_url in the Codex in-app browser and scan with DingTalk.',
589
+ title: ' openyida login --browser - In-app Browser Login Mode',
590
+ not_codex: 'Current environment is not detected as Codex/Qoder/Wukong; returning a browser login handoff only.',
591
+ no_playwright: 'In-app browser login does not require Playwright or a separate Chromium install.',
592
+ using_browser: 'Use the current in-app browser to open the Yida login page and scan with DingTalk.',
593
+ browser_handoff_hint: 'After browser login succeeds, export browser context cookies and run cookie_import_command to persist CLI login.',
594
+ handoff_message: 'Open login_url in the in-app browser, scan with DingTalk, then export cookies and run cookie_import_command.',
595
595
  cache_available: 'Existing CLI Cookie cache is available; no browser login needed.',
596
596
  },
597
597
  };
@@ -586,12 +586,12 @@ module.exports = {
586
586
  },
587
587
  },
588
588
  codex_login: {
589
- title: ' openyida login --codex - Codex Login Mode',
590
- not_codex: 'Current environment is not detected as Codex; returning a Codex browser login handoff only.',
591
- no_playwright: 'Codex mode does not require Playwright or a separate Chromium install.',
592
- using_browser: 'Use the Codex in-app browser to open the Yida login page and scan with DingTalk.',
593
- browser_handoff_hint: 'After browser login succeeds, the Codex session is logged in. CLI Cookie export requires a Codex browser bridge.',
594
- handoff_message: 'Open login_url in the Codex in-app browser and scan with DingTalk.',
589
+ title: ' openyida login --browser - In-app Browser Login Mode',
590
+ not_codex: 'Current environment is not detected as Codex/Qoder/Wukong; returning a browser login handoff only.',
591
+ no_playwright: 'In-app browser login does not require Playwright or a separate Chromium install.',
592
+ using_browser: 'Use the current in-app browser to open the Yida login page and scan with DingTalk.',
593
+ browser_handoff_hint: 'After browser login succeeds, export browser context cookies and run cookie_import_command to persist CLI login.',
594
+ handoff_message: 'Open login_url in the in-app browser, scan with DingTalk, then export cookies and run cookie_import_command.',
595
595
  cache_available: 'Existing CLI Cookie cache is available; no browser login needed.',
596
596
  },
597
597
  };
@@ -1016,12 +1016,12 @@ openyida - 宜搭命令列工具
1016
1016
  node_approval: '審批節點',
1017
1017
  },
1018
1018
  codex_login: {
1019
- title: ' openyida login --codex - Codex 登入模式',
1020
- not_codex: '目前環境未偵測為 Codex,僅返回 Codex 瀏覽器登入 handoff。',
1021
- no_playwright: 'Codex 登入模式不需要安裝 Playwright 或額外 Chromium。',
1022
- using_browser: '請使用 Codex 內建瀏覽器開啟宜搭登入頁,並用釘釘掃碼。',
1023
- browser_handoff_hint: '瀏覽器登入成功後,Codex 會話已登入;CLI Cookie 匯出需要 Codex 瀏覽器橋接能力。',
1024
- handoff_message: '請在 Codex 內建瀏覽器開啟 login_url,並使用釘釘掃碼登入。',
1019
+ title: ' openyida login --browser - 內建瀏覽器登入模式',
1020
+ not_codex: '目前環境未偵測為 Codex/Qoder/悟空,僅返回瀏覽器登入 handoff。',
1021
+ no_playwright: '內建瀏覽器登入模式不需要安裝 Playwright 或額外 Chromium。',
1022
+ using_browser: '請使用目前宿主的內建瀏覽器開啟宜搭登入頁,並用釘釘掃碼。',
1023
+ browser_handoff_hint: '瀏覽器登入成功後,匯出目前 browser context cookies,並執行 cookie_import_command 寫入 CLI 登入快取。',
1024
+ handoff_message: '請在內建瀏覽器開啟 login_url,用釘釘掃碼登入,然後匯出 Cookie 並執行 cookie_import_command。',
1025
1025
  cache_available: '已存在可用的 CLI Cookie 緩存,無需重新開啟瀏覽器登入。',
1026
1026
  },
1027
1027
  };
@@ -1291,12 +1291,12 @@ openyida - 宜搭命令行工具
1291
1291
  summary_ok: '所有 Sequence 状态正常',
1292
1292
  },
1293
1293
  codex_login: {
1294
- title: ' openyida login --codex - Codex 登录模式',
1295
- not_codex: '当前环境未检测为 Codex,仅返回 Codex 浏览器登录 handoff。',
1296
- no_playwright: 'Codex 登录模式不需要安装 Playwright 或额外 Chromium。',
1297
- using_browser: '请使用 Codex 内置浏览器打开宜搭登录页,并用钉钉扫码。',
1298
- browser_handoff_hint: '浏览器登录成功后,Codex 会话已登录;CLI Cookie 导出需要 Codex 浏览器桥接能力。',
1299
- handoff_message: '请在 Codex 内置浏览器打开 login_url,并使用钉钉扫码登录。',
1294
+ title: ' openyida login --browser - 内置浏览器登录模式',
1295
+ not_codex: '当前环境未检测为 Codex/Qoder/悟空,仅返回浏览器登录 handoff。',
1296
+ no_playwright: '内置浏览器登录模式不需要安装 Playwright 或额外 Chromium。',
1297
+ using_browser: '请使用当前宿主的内置浏览器打开宜搭登录页,并用钉钉扫码。',
1298
+ browser_handoff_hint: '浏览器登录成功后,导出当前 browser context cookies,并执行 cookie_import_command 写入 CLI 登录缓存。',
1299
+ handoff_message: '请在内置浏览器打开 login_url,用钉钉扫码登录,然后导出 Cookie 并执行 cookie_import_command。',
1300
1300
  cache_available: '已存在可用的 CLI Cookie 缓存,无需重新打开浏览器登录。',
1301
1301
  },
1302
1302
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openyida",
3
- "version": "2026.5.6-beta.2",
3
+ "version": "2026.5.6-beta.3",
4
4
  "description": "OpenYida CLI - 宜搭低代码 AI 开发工具(安装即用,零配置)",
5
5
  "bin": {
6
6
  "openyida": "bin/yida.js",
@@ -13,7 +13,7 @@ compatibility:
13
13
  metadata:
14
14
  audience: developers
15
15
  workflow: yida-development
16
- version: 2026.5.6-beta.2
16
+ version: 3.0.0
17
17
  tags:
18
18
  - yida
19
19
  - low-code
@@ -58,7 +58,24 @@ openyida login --qoder
58
58
  openyida login --wukong
59
59
  ```
60
60
 
61
- 这些命令返回 `login_url` handoff。收到 handoff 后,用当前宿主的 in-app browser 打开 `login_url`,让用户用钉钉扫码并等待跳转到宜搭工作台。若后续 CLI 仍缺少 `.cache/cookies*.json`,说明当前环境缺少浏览器 Cookie 导出桥接能力,不要手动编造或写入 Cookie。
61
+ 这些命令返回 `login_url` handoff,并包含 `cookie_import_command`、`cookie_file`、`post_login_check_command` 等字段。收到 handoff 后:
62
+
63
+ 1. 用当前宿主的 in-app browser 打开 `login_url`
64
+ 2. 让用户用钉钉扫码并等待跳转到宜搭工作台
65
+ 3. 使用宿主浏览器能力导出当前 browser context cookies 为 JSON 文件(格式为 cookies 数组,或 `{ "cookies": [...] }`)
66
+ 4. 执行 handoff 返回的 `cookie_import_command`,将 cookies 写入 `.cache/cookies*.json`
67
+ 5. 执行 `post_login_check_command`,确认 `can_auto_use: true`
68
+
69
+ 如果当前宿主没有任何浏览器 Cookie 导出能力,不要手动编造或写入 Cookie;改用 `openyida login --qr` 完成登录。
70
+
71
+ ### 导入浏览器 Cookie
72
+
73
+ ```bash
74
+ openyida login --import-cookies /path/to/cookies.json --base-url https://www.aliwork.com
75
+ openyida login --check-only --json
76
+ ```
77
+
78
+ `--import-cookies` 只接受真实浏览器导出的 Cookie JSON,必须包含 `tianshu_csrf_token`。导入成功后 CLI 会写入当前环境对应的 `.cache/cookies*.json`。
62
79
 
63
80
  ## 输出
64
81