openyida 2026.7.14 → 2026.7.17-2
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 +15 -22
- package/bin/yida.js +66 -226
- package/lib/agent-center/api.js +4 -5
- package/lib/aggregate-table/aggregate-table.js +8 -10
- package/lib/ai/ai.js +17 -27
- package/lib/app/app-list.js +4 -6
- package/lib/app/canvas-compile.js +2 -2
- package/lib/app/create-app.js +6 -21
- package/lib/app/create-form.js +54 -80
- package/lib/app/create-page.js +5 -22
- package/lib/app/er.js +10 -8
- package/lib/app/export-app.js +2 -2
- package/lib/app/externalize-form.js +12 -11
- package/lib/app/get-schema.js +12 -11
- package/lib/app/import-app.js +8 -28
- package/lib/app/list-forms.js +3 -19
- package/lib/app/nav-group.js +7 -21
- package/lib/app/publish.js +55 -203
- package/lib/app/update-app.js +4 -19
- package/lib/app/update-form-config.js +21 -116
- package/lib/app-permission/app-permission.js +3 -4
- package/lib/auth/oauth-loopback.js +156 -0
- package/lib/auth/org.js +169 -322
- package/lib/auth/token-auth.js +460 -0
- package/lib/auth/token-store.js +216 -0
- package/lib/basic-info/basic-info.js +11 -19
- package/lib/bridge/bridge.js +30 -28
- package/lib/connector/api.js +4 -7
- package/lib/core/agent-capabilities.js +92 -8
- package/lib/core/batch.js +8 -8
- package/lib/core/check-data.js +3 -4
- package/lib/core/command-manifest.js +3 -3
- package/lib/core/doctor.js +19 -22
- package/lib/core/env-cmd.js +1 -3
- package/lib/core/env-manager.js +8 -121
- package/lib/core/env.js +29 -73
- package/lib/core/locales/ar.js +5 -5
- package/lib/core/locales/de.js +5 -5
- package/lib/core/locales/en.js +26 -26
- package/lib/core/locales/es.js +5 -5
- package/lib/core/locales/fr.js +5 -5
- package/lib/core/locales/hi.js +5 -5
- package/lib/core/locales/ja.js +14 -14
- package/lib/core/locales/ko.js +5 -5
- package/lib/core/locales/pt.js +5 -5
- package/lib/core/locales/vi.js +5 -5
- package/lib/core/locales/zh-HK.js +15 -15
- package/lib/core/locales/zh.js +26 -26
- package/lib/core/query-data.js +4 -5
- package/lib/core/task-center.js +6 -7
- package/lib/core/utils.js +160 -445
- package/lib/core/yida-client.js +57 -24
- package/lib/corp-efficiency/corp-efficiency.js +5 -6
- package/lib/corp-manager/api.js +3 -4
- package/lib/db/db-seq-fix.js +20 -32
- package/lib/flash-note/flash-to-prd.js +4 -5
- package/lib/i18n-management/i18n-management.js +3 -4
- package/lib/integration/integration-api.js +9 -15
- package/lib/integration/integration-check.js +9 -7
- package/lib/integration/integration-create.js +10 -8
- package/lib/integration/integration-list.js +10 -8
- package/lib/mcp/server.js +5 -55
- package/lib/page-config/get-page-config.js +5 -6
- package/lib/page-config/save-share-config.js +5 -6
- package/lib/page-config/verify-short-url.js +4 -5
- package/lib/permission/get-permission.js +4 -5
- package/lib/permission/save-permission.js +5 -7
- package/lib/process/ai-form-setting.js +9 -10
- package/lib/process/configure-process.js +11 -17
- package/lib/process/create-process.js +6 -8
- package/lib/process/preview-process.js +2 -2
- package/lib/report/append.js +5 -6
- package/lib/report/http.js +4 -6
- package/lib/report/index.js +3 -3
- package/package.json +1 -1
- package/scripts/check-syntax.js +6 -0
- package/scripts/e2e-real/full-runner.js +2 -10
- package/scripts/e2e-real/runner.js +0 -31
- package/scripts/eval/screenshot.js +27 -69
- package/scripts/nightly-smoke.js +16 -34
- package/scripts/postinstall.js +6 -2
- package/yida-skills/SKILL.md +10 -6
- package/yida-skills/references/development-rules.md +2 -2
- package/yida-skills/references/setup-and-env.md +10 -9
- package/yida-skills/skills/sls-log-workbench/SKILL.md +2 -2
- package/yida-skills/skills/sls-log-workbench/sls-query.js +27 -54
- package/yida-skills/skills/yida-flash-note-to-prd/SKILL.md +1 -1
- package/yida-skills/skills/yida-integration/SKILL.md +3 -3
- package/yida-skills/skills/yida-login/SKILL.md +56 -74
- package/yida-skills/skills/yida-logout/SKILL.md +13 -12
- package/yida-skills/skills/yida-process-rule/SKILL.md +1 -1
- package/yida-skills/skills/yida-publish-page/SKILL.md +1 -1
- package/yida-skills/skills/yida-report/references/report-api-guide.md +4 -20
- package/yida-skills/skills-index.json +4 -4
- package/lib/auth/auth.js +0 -313
- package/lib/auth/cdp-browser-login.js +0 -390
- package/lib/auth/codex-login.js +0 -71
- package/lib/auth/login.js +0 -550
- package/lib/auth/qr-login.js +0 -1575
package/README.md
CHANGED
|
@@ -55,10 +55,10 @@ If Codex is already installed, OpenYida also imports a local Codex plugin during
|
|
|
55
55
|
Run this from the AI coding workspace where you want OpenYida to operate:
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
|
-
openyida agent-capabilities --json
|
|
58
|
+
openyida agent-capabilities --summary-json
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
OpenYida
|
|
61
|
+
OpenYida returns a compact machine-readable summary with the version, login state, workspace/cache paths, and command manifest digest. `openyida agent-capabilities --json` is the full diagnostic snapshot, where compact `workdir` maps to `active.projectRoot` and `workdir_exists` maps to `active.projectRootExists`. `openyida commands --json` remains available when an agent only needs the command manifest.
|
|
62
62
|
|
|
63
63
|
### 3. Log In
|
|
64
64
|
|
|
@@ -66,27 +66,20 @@ OpenYida detects the active agent environment, workspace path, login state, orga
|
|
|
66
66
|
openyida login
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
OpenYida login defaults to OAuth token mode. It opens the DingTalk OAuth authorization page, receives the local loopback callback, exchanges `code` / `authCode` with the Yida server, and stores `access_token` / `refresh_token` in the current project cache.
|
|
70
70
|
|
|
71
|
-
When the user names a target Yida entry URL, pass it to the login command so OpenYida can select the matching environment and
|
|
71
|
+
When the user names a target Yida entry URL, pass it to the login command so OpenYida can select the matching environment and token session file. For example, Alibaba intranet Yida uses `auth-token-alibaba.json`:
|
|
72
72
|
|
|
73
73
|
```bash
|
|
74
74
|
openyida login https://yida-group.alibaba-inc.com/
|
|
75
75
|
openyida login --alibaba
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
For token status checks, use:
|
|
79
79
|
|
|
80
80
|
```bash
|
|
81
|
-
openyida login --agent-qr
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
For terminal QR login, use:
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
openyida login --qr
|
|
88
|
-
openyida login --qr --corp-id dingxxxxxxxx
|
|
89
81
|
openyida login --check-only --json
|
|
82
|
+
openyida auth status
|
|
90
83
|
```
|
|
91
84
|
|
|
92
85
|
OpenYida does not install Playwright by default.
|
|
@@ -239,7 +232,7 @@ OPENYIDA_E2E=1 OPENYIDA_E2E_FULL_STAGES=auth,app,form,process npm run test:e2e:r
|
|
|
239
232
|
npm run test:e2e:real:skills
|
|
240
233
|
```
|
|
241
234
|
|
|
242
|
-
The runner creates a disposable app, form, and custom page with an `OY_E2E_*` prefix, then verifies login, app listing, schema fetch, data query, and page publish. It writes a registry to `project/.cache/e2e-real/` so created resources can be audited later.
|
|
235
|
+
The runner creates a disposable app, form, and custom page with an `OY_E2E_*` prefix, then verifies token login, app listing, schema fetch, data query, and page publish. It writes a registry to `project/.cache/e2e-real/` so created resources can be audited later. Run `openyida login` for the target environment before starting the real E2E runner.
|
|
243
236
|
|
|
244
237
|
`test:e2e:real:full` extends the smoke path into a broad deterministic feature matrix: auth/env, app update, form update and option mutation, page build/compile/generate/publish, data create/get/update/query, permission read, page config and short URL check, report create/append, dashboard skill verification, export/import, batch, task-center, formula/doctor/sample/CDN config, and local connector parsing/template generation. AI-backed commands such as `flash-to-prd` are available as the optional `ai` stage because they depend on remote model availability. Workflow mutation is available as the opt-in `process` stage; it creates and republishes a workflow on the disposable E2E form and records advanced official-node fixtures for review.
|
|
245
238
|
|
|
@@ -339,11 +332,11 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
|
|
|
339
332
|
|
|
340
333
|
| Command | Description |
|
|
341
334
|
|---------|-------------|
|
|
342
|
-
| `openyida login [target-url] [--
|
|
343
|
-
| `openyida logout` | Logout /
|
|
344
|
-
| `openyida auth <status\|login\|refresh\|logout>` |
|
|
345
|
-
| `openyida org <list\|switch
|
|
346
|
-
| `openyida env [--json\|setup\|list\|show\|switch\|add\|remove] [options]` | Detect AI tool environment & login state |
|
|
335
|
+
| `openyida login [target-url] [--env <name>\|--intl\|--overseas\|--global\|--yidaapps\|--alibaba] [--client-id <clientId>] [--endpoint <url>]` | Login with OAuth token mode |
|
|
336
|
+
| `openyida logout` | Logout / clear token |
|
|
337
|
+
| `openyida auth <status\|login\|refresh\|logout>` | Token login state management |
|
|
338
|
+
| `openyida org <list\|switch> [--json] [--corp-id <corpId>]` | Organization management (list / switch by OAuth re-login) |
|
|
339
|
+
| `openyida env [--json\|setup\|list\|show\|switch\|add\|remove] [options]` | Detect AI tool environment & token login state |
|
|
347
340
|
|
|
348
341
|
### App Management
|
|
349
342
|
|
|
@@ -457,7 +450,7 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
|
|
|
457
450
|
| Command | Description |
|
|
458
451
|
|---------|-------------|
|
|
459
452
|
| `openyida commands [--json]` | Output machine-readable command manifest |
|
|
460
|
-
| `openyida agent-capabilities [--json]` | Output one-shot agent capability snapshot |
|
|
453
|
+
| `openyida agent-capabilities [--json] [--summary-json\|--compact]` | Output one-shot agent capability snapshot |
|
|
461
454
|
| `openyida a2a <serve\|agent-card> [options]` | Start local read-only A2A adapter or print Agent Card |
|
|
462
455
|
| `openyida bridge start [--token <pair-token>] [--port 6736] [--origin https://demo.aliwork.com] [--open\|--no-open]` | Start OpenYida local web bridge service |
|
|
463
456
|
| `openyida copy [--force]` | Copy project working directory |
|
|
@@ -585,9 +578,9 @@ When adding new CLI commands, register the route in `bin/yida.js`, add it to `li
|
|
|
585
578
|
|
|
586
579
|
## Security and Configuration
|
|
587
580
|
|
|
588
|
-
-
|
|
581
|
+
- OAuth token sessions are cached locally and should never be hard-coded into source files.
|
|
589
582
|
- Private deployment environments are managed through `lib/core/env-manager.js`.
|
|
590
|
-
- Yida API requests should use the active environment base URL and
|
|
583
|
+
- Yida API requests should use the active environment base URL and Bearer token auth.
|
|
591
584
|
- For multi-organization accounts, prefer explicit `--corp-id` values in non-interactive automation.
|
|
592
585
|
|
|
593
586
|
## Community
|
package/bin/yida.js
CHANGED
|
@@ -211,6 +211,32 @@ function handleFirstRunGuide() {
|
|
|
211
211
|
console.log('');
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
+
const TOKEN_OUTPUT_SECRET_KEYS = new Set([
|
|
215
|
+
'access_token',
|
|
216
|
+
'accessToken',
|
|
217
|
+
'refresh_token',
|
|
218
|
+
'refreshToken',
|
|
219
|
+
]);
|
|
220
|
+
|
|
221
|
+
function maskSensitiveAuthOutput(value) {
|
|
222
|
+
if (!value || typeof value !== 'object') {
|
|
223
|
+
return value;
|
|
224
|
+
}
|
|
225
|
+
const { maskToken } = require('../lib/auth/token-store');
|
|
226
|
+
if (Array.isArray(value)) {
|
|
227
|
+
return value.map((item) => maskSensitiveAuthOutput(item));
|
|
228
|
+
}
|
|
229
|
+
const output = {};
|
|
230
|
+
Object.entries(value).forEach(([key, item]) => {
|
|
231
|
+
if (TOKEN_OUTPUT_SECRET_KEYS.has(key)) {
|
|
232
|
+
output[key] = maskToken(item);
|
|
233
|
+
} else {
|
|
234
|
+
output[key] = maskSensitiveAuthOutput(item);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
return output;
|
|
238
|
+
}
|
|
239
|
+
|
|
214
240
|
function printLoginResult(result) {
|
|
215
241
|
noteLoginCommandResult(result);
|
|
216
242
|
|
|
@@ -224,49 +250,21 @@ function printLoginResult(result) {
|
|
|
224
250
|
return;
|
|
225
251
|
}
|
|
226
252
|
|
|
227
|
-
|
|
228
|
-
console.log(JSON.stringify(result));
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
if (result && result.status === 'need_codex_browser_login') {
|
|
233
|
-
const handoff = {
|
|
234
|
-
status: result.status,
|
|
235
|
-
handoff_type: result.handoff_type || 'browser',
|
|
236
|
-
can_auto_use: false,
|
|
237
|
-
browser: result.browser,
|
|
238
|
-
login_url: result.login_url,
|
|
239
|
-
message: result.message,
|
|
240
|
-
};
|
|
241
|
-
[
|
|
242
|
-
'agent_action',
|
|
243
|
-
'browser_open_strategy',
|
|
244
|
-
'browser_use_local_redirect_fallback',
|
|
245
|
-
'required_agent_tool',
|
|
246
|
-
'required_runtime_tool',
|
|
247
|
-
'cookie_export_file',
|
|
248
|
-
'cookie_file',
|
|
249
|
-
'post_login_check_command',
|
|
250
|
-
'fallback_command',
|
|
251
|
-
].forEach((key) => {
|
|
252
|
-
if (result[key]) {handoff[key] = result[key];}
|
|
253
|
-
});
|
|
254
|
-
console.log(JSON.stringify(handoff));
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
if (result.status && result.status !== 'ok' && !result.csrf_token) {
|
|
259
|
-
console.log(JSON.stringify(result));
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
|
-
|
|
253
|
+
const tokenUsable = result.can_auto_use !== false && !!result.access_token;
|
|
263
254
|
const summary = {
|
|
264
|
-
ok:
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
255
|
+
ok: tokenUsable,
|
|
256
|
+
status: result.status || (tokenUsable ? 'ok' : 'token_not_issued'),
|
|
257
|
+
auth_mode: 'token',
|
|
258
|
+
can_auto_use: tokenUsable,
|
|
259
|
+
token_type: result.token_type || 'Bearer',
|
|
260
|
+
access_token: maskSensitiveAuthOutput({ access_token: result.access_token }).access_token,
|
|
261
|
+
expires_at: result.expires_at ? new Date(result.expires_at).toISOString() : undefined,
|
|
262
|
+
base_url: result.base_url,
|
|
263
|
+
corp_id: result.corp_id,
|
|
264
|
+
user_id: result.user_id,
|
|
265
|
+
user_name: result.user_name,
|
|
266
|
+
message: result.message,
|
|
267
|
+
raw: tokenUsable ? undefined : result.raw,
|
|
270
268
|
};
|
|
271
269
|
console.log(JSON.stringify(summary));
|
|
272
270
|
}
|
|
@@ -277,15 +275,11 @@ function noteLoginCommandResult(result) {
|
|
|
277
275
|
let status = 'failed';
|
|
278
276
|
let reason = 'login_failed';
|
|
279
277
|
|
|
280
|
-
|
|
278
|
+
const tokenLoginOk = result && result.auth_mode === 'token' &&
|
|
279
|
+
(result.access_token || (result.status === 'ok' && result.can_auto_use));
|
|
280
|
+
if (result && (tokenLoginOk || (result.status === 'ok' && result.can_auto_use))) {
|
|
281
281
|
status = 'success';
|
|
282
282
|
reason = 'login_ok';
|
|
283
|
-
} else if (result && result.status === 'need_qr_scan') {
|
|
284
|
-
status = 'need_qr_scan';
|
|
285
|
-
reason = 'need_qr_scan';
|
|
286
|
-
} else if (result && result.status === 'need_codex_browser_login') {
|
|
287
|
-
status = 'need_browser_login';
|
|
288
|
-
reason = 'need_browser_login';
|
|
289
283
|
} else if (result && result.status === 'need_corp_selection') {
|
|
290
284
|
status = 'success';
|
|
291
285
|
reason = 'need_corp_selection';
|
|
@@ -306,40 +300,6 @@ function noteLoginCommandResult(result) {
|
|
|
306
300
|
}
|
|
307
301
|
}
|
|
308
302
|
|
|
309
|
-
function isAgentConversationEnvironment() {
|
|
310
|
-
const { detectActiveTool } = require('../lib/core/utils');
|
|
311
|
-
return !!detectActiveTool() || process.env.OPENYIDA_AGENT_MODE === '1';
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
function shouldUseBrowserHandoffLogin(cliArgs) {
|
|
315
|
-
if (cliArgs.includes('--qr') || cliArgs.includes('--codex-qr') || cliArgs.includes('--agent-qr')) {return false;}
|
|
316
|
-
if (cliArgs.includes('--browser') || cliArgs.includes('--codex') || cliArgs.includes('--qoder') || cliArgs.includes('--wukong')) {return true;}
|
|
317
|
-
return false;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
function shouldUseAgentLogin(cliArgs) {
|
|
321
|
-
if (cliArgs.includes('--qr') || cliArgs.includes('--codex-qr') || cliArgs.includes('--agent-qr')) {return false;}
|
|
322
|
-
if (shouldUseBrowserHandoffLogin(cliArgs)) {return false;}
|
|
323
|
-
return isAgentConversationEnvironment();
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
function shouldUsePlaywrightFallbackInAgentLogin() {
|
|
327
|
-
const { hasDesktopEnvironment } = require('../lib/core/utils');
|
|
328
|
-
return hasDesktopEnvironment() || process.env.OPENYIDA_AGENT_PLAYWRIGHT_FALLBACK === '1';
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
function shouldUseLocalBrowserLogin(options = {}) {
|
|
332
|
-
const { hasLocalBrowserLoginCapability } = require('../lib/auth/login');
|
|
333
|
-
return hasLocalBrowserLoginCapability({
|
|
334
|
-
playwrightFallback: options.playwrightFallback,
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
function shouldUseCodexQrLogin(cliArgs) {
|
|
339
|
-
if (cliArgs.includes('--codex-qr') || cliArgs.includes('--agent-qr')) {return true;}
|
|
340
|
-
return false;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
303
|
function getArgValue(cliArgs, name) {
|
|
344
304
|
const index = cliArgs.indexOf(name);
|
|
345
305
|
if (index === -1 || !cliArgs[index + 1] || cliArgs[index + 1].startsWith('--')) {
|
|
@@ -414,11 +374,9 @@ function applyLoginEnvironmentFlags(cliArgs, options = {}) {
|
|
|
414
374
|
'--intranet': 'alibaba',
|
|
415
375
|
};
|
|
416
376
|
const valuePassthroughFlags = new Set([
|
|
417
|
-
'--agent-poll',
|
|
418
|
-
'--codex-poll',
|
|
419
|
-
'--agent-select',
|
|
420
|
-
'--codex-select',
|
|
421
377
|
'--corp-id',
|
|
378
|
+
'--client-id',
|
|
379
|
+
'--user-id',
|
|
422
380
|
]);
|
|
423
381
|
const targetUrlFlags = new Set([
|
|
424
382
|
'--endpoint',
|
|
@@ -487,12 +445,6 @@ function throwCliUsage(...lines) {
|
|
|
487
445
|
});
|
|
488
446
|
}
|
|
489
447
|
|
|
490
|
-
function throwNeedLogin(message) {
|
|
491
|
-
throw new CliError(message, {
|
|
492
|
-
code: 'NEED_LOGIN',
|
|
493
|
-
});
|
|
494
|
-
}
|
|
495
|
-
|
|
496
448
|
async function main() {
|
|
497
449
|
applyQuietFlag();
|
|
498
450
|
applyGlobalEnvironmentFlags();
|
|
@@ -563,129 +515,42 @@ async function main() {
|
|
|
563
515
|
}
|
|
564
516
|
|
|
565
517
|
case 'login': {
|
|
566
|
-
const { checkLoginOnly } = require('../lib/auth/login');
|
|
567
518
|
const loginArgs = applyLoginEnvironmentFlags(args, { inferTargetUrl: true });
|
|
568
|
-
const {
|
|
569
|
-
if (loginArgs.includes('--
|
|
570
|
-
|
|
571
|
-
const { pollCodexQrLogin } = require('../lib/auth/qr-login');
|
|
572
|
-
const result = await pollCodexQrLogin(sessionFile, {
|
|
573
|
-
corpId: getArgValue(loginArgs, '--corp-id'),
|
|
574
|
-
});
|
|
575
|
-
printLoginResult(result);
|
|
576
|
-
} else if (loginArgs.includes('--agent-select') || loginArgs.includes('--codex-select')) {
|
|
577
|
-
const sessionFile = getArgValue(loginArgs, '--agent-select') || getArgValue(loginArgs, '--codex-select');
|
|
578
|
-
const { selectCodexQrCorp } = require('../lib/auth/qr-login');
|
|
579
|
-
const result = await selectCodexQrCorp(sessionFile, {
|
|
580
|
-
corpId: getArgValue(loginArgs, '--corp-id'),
|
|
581
|
-
});
|
|
582
|
-
printLoginResult(result);
|
|
583
|
-
} else if (loginArgs.includes('--check-only')) {
|
|
584
|
-
const result = checkLoginOnly({ includeSecrets: loginArgs.includes('--with-cookies') });
|
|
585
|
-
console.log(JSON.stringify(result, null, 2));
|
|
586
|
-
} else if (isEnvAuthMode()) {
|
|
587
|
-
const result = checkLoginOnly({ includeSecrets: true });
|
|
588
|
-
printLoginResult(result);
|
|
589
|
-
} else if (shouldUseCodexQrLogin(loginArgs)) {
|
|
590
|
-
const { startCodexQrLogin } = require('../lib/auth/qr-login');
|
|
591
|
-
const result = await startCodexQrLogin({ corpId: getArgValue(loginArgs, '--corp-id') });
|
|
592
|
-
printLoginResult(result);
|
|
593
|
-
} else if (loginArgs.includes('--browser')) {
|
|
594
|
-
const { interactiveLogin } = require('../lib/auth/login');
|
|
595
|
-
const result = interactiveLogin({ force: true });
|
|
596
|
-
printLoginResult(result);
|
|
597
|
-
} else if (loginArgs.includes('--qoder') || loginArgs.includes('--wukong')) {
|
|
598
|
-
const { codexLogin } = require('../lib/auth/codex-login');
|
|
599
|
-
const result = await codexLogin({ tool: loginArgs.includes('--qoder') ? 'qoder' : 'wukong' });
|
|
600
|
-
printLoginResult(result);
|
|
601
|
-
} else if (loginArgs.includes('--qr')) {
|
|
602
|
-
const { qrLogin } = require('../lib/auth/qr-login');
|
|
603
|
-
const result = await qrLogin({ corpId: getArgValue(loginArgs, '--corp-id') });
|
|
604
|
-
printLoginResult(result);
|
|
605
|
-
} else if (shouldUseAgentLogin(loginArgs)) {
|
|
606
|
-
const cachedResult = checkLoginOnly({ includeSecrets: true });
|
|
607
|
-
if (cachedResult.status === 'ok') {
|
|
608
|
-
printLoginResult(cachedResult);
|
|
609
|
-
} else {
|
|
610
|
-
const { interactiveLogin } = require('../lib/auth/login');
|
|
611
|
-
const playwrightFallback = shouldUsePlaywrightFallbackInAgentLogin();
|
|
612
|
-
const browserResult = shouldUseLocalBrowserLogin({ playwrightFallback })
|
|
613
|
-
? interactiveLogin({ playwrightFallback })
|
|
614
|
-
: null;
|
|
615
|
-
if (browserResult) {
|
|
616
|
-
printLoginResult(browserResult);
|
|
617
|
-
} else {
|
|
618
|
-
const { startCodexQrLogin } = require('../lib/auth/qr-login');
|
|
619
|
-
const result = await startCodexQrLogin({ corpId: getArgValue(loginArgs, '--corp-id') });
|
|
620
|
-
printLoginResult(result);
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
} else if (shouldUseBrowserHandoffLogin(loginArgs)) {
|
|
624
|
-
const cachedResult = checkLoginOnly({ includeSecrets: true });
|
|
625
|
-
if (cachedResult.status === 'ok') {
|
|
626
|
-
printLoginResult(cachedResult);
|
|
627
|
-
} else {
|
|
628
|
-
const { codexLogin } = require('../lib/auth/codex-login');
|
|
629
|
-
const result = await codexLogin({ tool: loginArgs.includes('--codex') ? 'codex' : undefined });
|
|
630
|
-
printLoginResult(result);
|
|
631
|
-
}
|
|
519
|
+
const { tokenLogin, tokenStatus } = require('../lib/auth/token-auth');
|
|
520
|
+
if (loginArgs.includes('--check-only')) {
|
|
521
|
+
console.log(JSON.stringify(tokenStatus(), null, 2));
|
|
632
522
|
} else {
|
|
633
|
-
const
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
}
|
|
638
|
-
if (shouldUseLocalBrowserLogin({ playwrightFallback: true })) {
|
|
639
|
-
const { interactiveLogin } = require('../lib/auth/login');
|
|
640
|
-
const browserResult = interactiveLogin({ playwrightFallback: true });
|
|
641
|
-
if (browserResult) {
|
|
642
|
-
printLoginResult(browserResult);
|
|
643
|
-
break;
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
const { qrLogin } = require('../lib/auth/qr-login');
|
|
647
|
-
const result = await qrLogin({ corpId: getArgValue(loginArgs, '--corp-id') });
|
|
523
|
+
const result = await tokenLogin({
|
|
524
|
+
clientId: getArgValue(loginArgs, '--client-id'),
|
|
525
|
+
quiet: loginArgs.includes('--quiet'),
|
|
526
|
+
});
|
|
648
527
|
printLoginResult(result);
|
|
649
528
|
}
|
|
650
529
|
break;
|
|
651
530
|
}
|
|
652
531
|
|
|
653
532
|
case 'logout': {
|
|
654
|
-
const {
|
|
655
|
-
|
|
533
|
+
const { tokenLogout } = require('../lib/auth/token-auth');
|
|
534
|
+
console.log(JSON.stringify(await tokenLogout(), null, 2));
|
|
656
535
|
break;
|
|
657
536
|
}
|
|
658
537
|
|
|
659
538
|
case 'auth': {
|
|
660
539
|
const subCommand = args[0];
|
|
661
|
-
const
|
|
662
|
-
|
|
540
|
+
const authArgs = applyLoginEnvironmentFlags(args.slice(1), { inferTargetUrl: true });
|
|
541
|
+
const { tokenLogin, tokenLogout, tokenRefresh, tokenStatus } = require('../lib/auth/token-auth');
|
|
663
542
|
if (subCommand === 'status') {
|
|
664
|
-
|
|
543
|
+
console.log(JSON.stringify(tokenStatus(), null, 2));
|
|
665
544
|
} else if (subCommand === 'login') {
|
|
666
|
-
const
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
loginType = 'codex';
|
|
670
|
-
} else if (authArgs.includes('--qoder')) {
|
|
671
|
-
loginType = 'qoder';
|
|
672
|
-
} else if (authArgs.includes('--wukong')) {
|
|
673
|
-
loginType = 'wukong';
|
|
674
|
-
} else if (authArgs.includes('--browser')) {
|
|
675
|
-
loginType = 'browser';
|
|
676
|
-
}
|
|
677
|
-
const result = await authLogin({
|
|
678
|
-
type: loginType,
|
|
679
|
-
corpId: getArgValue(authArgs, '--corp-id'),
|
|
680
|
-
forceTerminalQr: authArgs.includes('--qr'),
|
|
545
|
+
const result = await tokenLogin({
|
|
546
|
+
clientId: getArgValue(authArgs, '--client-id'),
|
|
547
|
+
quiet: authArgs.includes('--quiet'),
|
|
681
548
|
});
|
|
682
|
-
|
|
683
|
-
printLoginResult(result);
|
|
684
|
-
}
|
|
549
|
+
printLoginResult(result);
|
|
685
550
|
} else if (subCommand === 'refresh') {
|
|
686
|
-
|
|
551
|
+
console.log(JSON.stringify(maskSensitiveAuthOutput(await tokenRefresh()), null, 2));
|
|
687
552
|
} else if (subCommand === 'logout') {
|
|
688
|
-
|
|
553
|
+
console.log(JSON.stringify(await tokenLogout(), null, 2));
|
|
689
554
|
} else {
|
|
690
555
|
throwCliUsage(t('cli.auth_usage'), t('cli.auth_example'));
|
|
691
556
|
}
|
|
@@ -693,34 +558,9 @@ async function main() {
|
|
|
693
558
|
}
|
|
694
559
|
|
|
695
560
|
case 'org': {
|
|
696
|
-
const
|
|
697
|
-
const {
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
if (subCommand === 'list') {
|
|
701
|
-
const cookieData = loadCookieData();
|
|
702
|
-
if (!cookieData || !cookieData.cookies) {
|
|
703
|
-
throwNeedLogin(t('org.no_login'));
|
|
704
|
-
}
|
|
705
|
-
await listOrganizations(cookieData);
|
|
706
|
-
} else if (subCommand === 'switch') {
|
|
707
|
-
const cookieData = loadCookieData();
|
|
708
|
-
if (!cookieData || !cookieData.cookies) {
|
|
709
|
-
throwNeedLogin(t('org.no_login'));
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
// 解析 --corp-id 参数
|
|
713
|
-
const corpIdIndex = args.indexOf('--corp-id');
|
|
714
|
-
if (corpIdIndex !== -1 && args[corpIdIndex + 1]) {
|
|
715
|
-
const targetCorpId = args[corpIdIndex + 1];
|
|
716
|
-
await switchOrganization(targetCorpId, cookieData);
|
|
717
|
-
} else {
|
|
718
|
-
// 交互式选择
|
|
719
|
-
await interactiveSwitch(cookieData);
|
|
720
|
-
}
|
|
721
|
-
} else {
|
|
722
|
-
throwCliUsage(t('cli.org_usage'), t('cli.org_example'));
|
|
723
|
-
}
|
|
561
|
+
const orgArgs = applyLoginEnvironmentFlags(args, { inferTargetUrl: true });
|
|
562
|
+
const { run } = require('../lib/auth/org');
|
|
563
|
+
await run(orgArgs);
|
|
724
564
|
break;
|
|
725
565
|
}
|
|
726
566
|
|
package/lib/agent-center/api.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { createAuthRef, createYidaClient } = require('../core/yida-client');
|
|
3
|
+
const { createAuthRef, createYidaClient, isAuthRefReady } = require('../core/yida-client');
|
|
4
4
|
|
|
5
5
|
const AGENT_TYPE_ALIASES = {
|
|
6
6
|
normal: 'NORMAL',
|
|
@@ -70,8 +70,8 @@ const AGENT_RANGE_ALIASES = {
|
|
|
70
70
|
|
|
71
71
|
function getAuthRef() {
|
|
72
72
|
const authRef = createAuthRef();
|
|
73
|
-
if (!authRef
|
|
74
|
-
throw new Error('
|
|
73
|
+
if (!isAuthRefReady(authRef)) {
|
|
74
|
+
throw new Error('无法获取有效 token 登录态');
|
|
75
75
|
}
|
|
76
76
|
return authRef;
|
|
77
77
|
}
|
|
@@ -128,7 +128,6 @@ function normalizeYesNo(value, defaultValue = 'n') {
|
|
|
128
128
|
function buildCommonParams(authRef, apiName, params = {}) {
|
|
129
129
|
const base = {
|
|
130
130
|
_mock: 'false',
|
|
131
|
-
_csrf_token: authRef.csrfToken,
|
|
132
131
|
_locale_time_zone_offset: '28800000',
|
|
133
132
|
_stamp: String(Date.now()),
|
|
134
133
|
};
|
|
@@ -150,7 +149,7 @@ async function agentPost(path, apiName, params = {}, authRef = getAuthRef()) {
|
|
|
150
149
|
}
|
|
151
150
|
|
|
152
151
|
function assertSuccess(result, action) {
|
|
153
|
-
if (result && result.success !== false && !result.__needLogin
|
|
152
|
+
if (result && result.success !== false && !result.__needLogin) {
|
|
154
153
|
return result;
|
|
155
154
|
}
|
|
156
155
|
const message = result && (result.errorMsg || result.message || result.errorCode);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const querystring = require('querystring');
|
|
5
5
|
|
|
6
|
-
const { createAuthRef: createCoreAuthRef, createYidaClient } = require('../core/yida-client');
|
|
6
|
+
const { createAuthRef: createCoreAuthRef, createYidaClient, isAuthRefReady } = require('../core/yida-client');
|
|
7
7
|
const { t } = require('../core/i18n');
|
|
8
8
|
const { buildYidaTitleI18n, normalizeYidaLocale, resolveContentLocale } = require('../core/yida-i18n');
|
|
9
9
|
const { parseOpenOption, withBrowserHandoff } = require('../core/browser-handoff');
|
|
@@ -86,7 +86,7 @@ function unwrapContent(result) {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
function assertSuccess(result, action) {
|
|
89
|
-
if (!result || result.success === false || result.__needLogin
|
|
89
|
+
if (!result || result.success === false || result.__needLogin) {
|
|
90
90
|
const message = result
|
|
91
91
|
? result.errorMsg || result.error || result.message || t('common.unknown_error')
|
|
92
92
|
: t('common.request_failed');
|
|
@@ -97,15 +97,14 @@ function assertSuccess(result, action) {
|
|
|
97
97
|
|
|
98
98
|
async function createAuthRef() {
|
|
99
99
|
const authRef = createCoreAuthRef();
|
|
100
|
-
if (!authRef
|
|
100
|
+
if (!isAuthRefReady(authRef)) {
|
|
101
101
|
throw new Error(t('aggregate_table.no_login'));
|
|
102
102
|
}
|
|
103
103
|
return authRef;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
function buildCreateEmptyPostData(
|
|
106
|
+
function buildCreateEmptyPostData(title) {
|
|
107
107
|
return querystring.stringify({
|
|
108
|
-
_csrf_token: csrfToken,
|
|
109
108
|
formType: 'receipt',
|
|
110
109
|
isVirtualView: 'y',
|
|
111
110
|
title: JSON.stringify(buildYidaTitleI18n(title, {
|
|
@@ -115,9 +114,8 @@ function buildCreateEmptyPostData(csrfToken, title) {
|
|
|
115
114
|
});
|
|
116
115
|
}
|
|
117
116
|
|
|
118
|
-
function buildDesignPostData(
|
|
117
|
+
function buildDesignPostData(formUuid, designInfo, gmtModified) {
|
|
119
118
|
const payload = {
|
|
120
|
-
_csrf_token: csrfToken,
|
|
121
119
|
formUuid,
|
|
122
120
|
designInfo: JSON.stringify(designInfo),
|
|
123
121
|
};
|
|
@@ -130,14 +128,14 @@ function buildDesignPostData(csrfToken, formUuid, designInfo, gmtModified) {
|
|
|
130
128
|
async function checkVirtualViewFeature(authRef, appType) {
|
|
131
129
|
return createYidaClient({ authRef }).postForm(
|
|
132
130
|
`/dingtalk/web/${appType}/query/virtualview/show.json`,
|
|
133
|
-
|
|
131
|
+
{}
|
|
134
132
|
);
|
|
135
133
|
}
|
|
136
134
|
|
|
137
135
|
async function createEmptyVirtualView(authRef, appType, title) {
|
|
138
136
|
return createYidaClient({ authRef }).postForm(
|
|
139
137
|
`/dingtalk/web/${appType}/query/formdesign/saveFormSchemaInfo.json`,
|
|
140
|
-
|
|
138
|
+
buildCreateEmptyPostData(title)
|
|
141
139
|
);
|
|
142
140
|
}
|
|
143
141
|
|
|
@@ -161,7 +159,7 @@ async function postVirtualViewDesign(authRef, appType, formUuid, designInfo, act
|
|
|
161
159
|
|
|
162
160
|
return createYidaClient({ authRef }).postForm(
|
|
163
161
|
`/alibaba/web/${appType}/query/virtualview/${endpoint}`,
|
|
164
|
-
|
|
162
|
+
buildDesignPostData(formUuid, designInfo, gmtModified)
|
|
165
163
|
);
|
|
166
164
|
}
|
|
167
165
|
|