openyida 2026.7.13 → 2026.7.14-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 +72 -220
- package/lib/agent-center/api.js +2 -2
- package/lib/aggregate-table/aggregate-table.js +2 -2
- package/lib/ai/ai.js +7 -12
- package/lib/app/canvas-compile.js +2 -2
- package/lib/app/create-app.js +5 -19
- package/lib/app/create-form.js +54 -76
- package/lib/app/create-page.js +4 -19
- package/lib/app/er.js +11 -8
- package/lib/app/export-app.js +2 -2
- package/lib/app/externalize-form.js +12 -10
- package/lib/app/get-schema.js +12 -10
- package/lib/app/import-app.js +6 -22
- package/lib/app/list-forms.js +3 -19
- package/lib/app/nav-group.js +6 -19
- package/lib/app/publish.js +60 -198
- package/lib/app/update-app.js +4 -18
- package/lib/app/update-form-config.js +20 -113
- package/lib/app-permission/app-permission.js +2 -2
- package/lib/auth/oauth-loopback.js +156 -0
- package/lib/auth/org.js +169 -322
- package/lib/auth/token-auth.js +346 -0
- package/lib/auth/token-store.js +174 -0
- package/lib/basic-info/basic-info.js +11 -12
- package/lib/bridge/bridge.js +29 -27
- package/lib/connector/api.js +4 -4
- package/lib/core/agent-capabilities.js +92 -8
- package/lib/core/batch.js +8 -8
- package/lib/core/check-data.js +2 -2
- 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 +30 -72
- 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 +2 -2
- package/lib/core/task-center.js +2 -2
- package/lib/core/utils.js +156 -400
- package/lib/core/yida-client.js +57 -22
- package/lib/corp-efficiency/corp-efficiency.js +3 -3
- package/lib/corp-manager/api.js +2 -2
- package/lib/db/db-seq-fix.js +20 -25
- package/lib/flash-note/flash-to-prd.js +2 -2
- package/lib/i18n-management/i18n-management.js +2 -2
- package/lib/integration/integration-check.js +10 -7
- package/lib/integration/integration-create.js +11 -8
- package/lib/integration/integration-list.js +11 -8
- package/lib/mcp/server.js +5 -54
- package/lib/page-config/get-page-config.js +2 -2
- package/lib/page-config/save-share-config.js +2 -2
- package/lib/page-config/verify-short-url.js +2 -2
- package/lib/permission/get-permission.js +2 -2
- package/lib/permission/save-permission.js +2 -2
- package/lib/process/ai-form-setting.js +2 -2
- package/lib/process/create-process.js +2 -2
- package/lib/process/preview-process.js +2 -2
- package/lib/report/append.js +3 -3
- 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,38 @@ 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
|
+
'ai_app_user_auth_token',
|
|
220
|
+
'aiAppUserAuthToken',
|
|
221
|
+
'tianshu_csrf_token',
|
|
222
|
+
'tianshuCsrfToken',
|
|
223
|
+
'csrf_token',
|
|
224
|
+
'csrfToken',
|
|
225
|
+
]);
|
|
226
|
+
|
|
227
|
+
function maskSensitiveAuthOutput(value) {
|
|
228
|
+
if (!value || typeof value !== 'object') {
|
|
229
|
+
return value;
|
|
230
|
+
}
|
|
231
|
+
const { maskToken } = require('../lib/auth/token-store');
|
|
232
|
+
if (Array.isArray(value)) {
|
|
233
|
+
return value.map((item) => maskSensitiveAuthOutput(item));
|
|
234
|
+
}
|
|
235
|
+
const output = {};
|
|
236
|
+
Object.entries(value).forEach(([key, item]) => {
|
|
237
|
+
if (TOKEN_OUTPUT_SECRET_KEYS.has(key)) {
|
|
238
|
+
output[key] = maskToken(item);
|
|
239
|
+
} else {
|
|
240
|
+
output[key] = maskSensitiveAuthOutput(item);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
return output;
|
|
244
|
+
}
|
|
245
|
+
|
|
214
246
|
function printLoginResult(result) {
|
|
215
247
|
noteLoginCommandResult(result);
|
|
216
248
|
|
|
@@ -224,49 +256,21 @@ function printLoginResult(result) {
|
|
|
224
256
|
return;
|
|
225
257
|
}
|
|
226
258
|
|
|
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
|
-
|
|
259
|
+
const tokenUsable = result.can_auto_use !== false && !!result.access_token;
|
|
263
260
|
const summary = {
|
|
264
|
-
ok:
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
261
|
+
ok: tokenUsable,
|
|
262
|
+
status: result.status || (tokenUsable ? 'ok' : 'token_not_issued'),
|
|
263
|
+
auth_mode: 'token',
|
|
264
|
+
can_auto_use: tokenUsable,
|
|
265
|
+
token_type: result.token_type || 'Bearer',
|
|
266
|
+
access_token: maskSensitiveAuthOutput({ access_token: result.access_token }).access_token,
|
|
267
|
+
expires_at: result.expires_at ? new Date(result.expires_at).toISOString() : undefined,
|
|
268
|
+
base_url: result.base_url,
|
|
269
|
+
corp_id: result.corp_id,
|
|
270
|
+
user_id: result.user_id,
|
|
271
|
+
user_name: result.user_name,
|
|
272
|
+
message: result.message,
|
|
273
|
+
raw: tokenUsable ? undefined : result.raw,
|
|
270
274
|
};
|
|
271
275
|
console.log(JSON.stringify(summary));
|
|
272
276
|
}
|
|
@@ -277,15 +281,11 @@ function noteLoginCommandResult(result) {
|
|
|
277
281
|
let status = 'failed';
|
|
278
282
|
let reason = 'login_failed';
|
|
279
283
|
|
|
280
|
-
|
|
284
|
+
const tokenLoginOk = result && result.auth_mode === 'token' &&
|
|
285
|
+
(result.access_token || (result.status === 'ok' && result.can_auto_use));
|
|
286
|
+
if (result && (tokenLoginOk || (result.status === 'ok' && result.can_auto_use))) {
|
|
281
287
|
status = 'success';
|
|
282
288
|
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
289
|
} else if (result && result.status === 'need_corp_selection') {
|
|
290
290
|
status = 'success';
|
|
291
291
|
reason = 'need_corp_selection';
|
|
@@ -306,40 +306,6 @@ function noteLoginCommandResult(result) {
|
|
|
306
306
|
}
|
|
307
307
|
}
|
|
308
308
|
|
|
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
309
|
function getArgValue(cliArgs, name) {
|
|
344
310
|
const index = cliArgs.indexOf(name);
|
|
345
311
|
if (index === -1 || !cliArgs[index + 1] || cliArgs[index + 1].startsWith('--')) {
|
|
@@ -414,11 +380,9 @@ function applyLoginEnvironmentFlags(cliArgs, options = {}) {
|
|
|
414
380
|
'--intranet': 'alibaba',
|
|
415
381
|
};
|
|
416
382
|
const valuePassthroughFlags = new Set([
|
|
417
|
-
'--agent-poll',
|
|
418
|
-
'--codex-poll',
|
|
419
|
-
'--agent-select',
|
|
420
|
-
'--codex-select',
|
|
421
383
|
'--corp-id',
|
|
384
|
+
'--client-id',
|
|
385
|
+
'--user-id',
|
|
422
386
|
]);
|
|
423
387
|
const targetUrlFlags = new Set([
|
|
424
388
|
'--endpoint',
|
|
@@ -563,129 +527,42 @@ async function main() {
|
|
|
563
527
|
}
|
|
564
528
|
|
|
565
529
|
case 'login': {
|
|
566
|
-
const { checkLoginOnly } = require('../lib/auth/login');
|
|
567
530
|
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
|
-
}
|
|
531
|
+
const { tokenLogin, tokenStatus } = require('../lib/auth/token-auth');
|
|
532
|
+
if (loginArgs.includes('--check-only')) {
|
|
533
|
+
console.log(JSON.stringify(tokenStatus(), null, 2));
|
|
632
534
|
} 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') });
|
|
535
|
+
const result = await tokenLogin({
|
|
536
|
+
clientId: getArgValue(loginArgs, '--client-id'),
|
|
537
|
+
quiet: loginArgs.includes('--quiet'),
|
|
538
|
+
});
|
|
648
539
|
printLoginResult(result);
|
|
649
540
|
}
|
|
650
541
|
break;
|
|
651
542
|
}
|
|
652
543
|
|
|
653
544
|
case 'logout': {
|
|
654
|
-
const {
|
|
655
|
-
|
|
545
|
+
const { tokenLogout } = require('../lib/auth/token-auth');
|
|
546
|
+
console.log(JSON.stringify(await tokenLogout(), null, 2));
|
|
656
547
|
break;
|
|
657
548
|
}
|
|
658
549
|
|
|
659
550
|
case 'auth': {
|
|
660
551
|
const subCommand = args[0];
|
|
661
|
-
const
|
|
662
|
-
|
|
552
|
+
const authArgs = applyLoginEnvironmentFlags(args.slice(1), { inferTargetUrl: true });
|
|
553
|
+
const { tokenLogin, tokenLogout, tokenRefresh, tokenStatus } = require('../lib/auth/token-auth');
|
|
663
554
|
if (subCommand === 'status') {
|
|
664
|
-
|
|
555
|
+
console.log(JSON.stringify(tokenStatus(), null, 2));
|
|
665
556
|
} 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'),
|
|
557
|
+
const result = await tokenLogin({
|
|
558
|
+
clientId: getArgValue(authArgs, '--client-id'),
|
|
559
|
+
quiet: authArgs.includes('--quiet'),
|
|
681
560
|
});
|
|
682
|
-
|
|
683
|
-
printLoginResult(result);
|
|
684
|
-
}
|
|
561
|
+
printLoginResult(result);
|
|
685
562
|
} else if (subCommand === 'refresh') {
|
|
686
|
-
|
|
563
|
+
console.log(JSON.stringify(maskSensitiveAuthOutput(await tokenRefresh()), null, 2));
|
|
687
564
|
} else if (subCommand === 'logout') {
|
|
688
|
-
|
|
565
|
+
console.log(JSON.stringify(await tokenLogout(), null, 2));
|
|
689
566
|
} else {
|
|
690
567
|
throwCliUsage(t('cli.auth_usage'), t('cli.auth_example'));
|
|
691
568
|
}
|
|
@@ -693,34 +570,9 @@ async function main() {
|
|
|
693
570
|
}
|
|
694
571
|
|
|
695
572
|
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
|
-
}
|
|
573
|
+
const orgArgs = applyLoginEnvironmentFlags(args, { inferTargetUrl: true });
|
|
574
|
+
const { run } = require('../lib/auth/org');
|
|
575
|
+
await run(orgArgs);
|
|
724
576
|
break;
|
|
725
577
|
}
|
|
726
578
|
|
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,7 +70,7 @@ const AGENT_RANGE_ALIASES = {
|
|
|
70
70
|
|
|
71
71
|
function getAuthRef() {
|
|
72
72
|
const authRef = createAuthRef();
|
|
73
|
-
if (!authRef
|
|
73
|
+
if (!isAuthRefReady(authRef)) {
|
|
74
74
|
throw new Error('无法获取有效登录态或 CSRF Token');
|
|
75
75
|
}
|
|
76
76
|
return authRef;
|
|
@@ -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');
|
|
@@ -97,7 +97,7 @@ 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;
|
package/lib/ai/ai.js
CHANGED
|
@@ -15,7 +15,7 @@ const {
|
|
|
15
15
|
findProjectRoot,
|
|
16
16
|
} = require('../core/utils');
|
|
17
17
|
const { CliError } = require('../core/cli-error');
|
|
18
|
-
const { createAuthRef, createYidaClient } = require('../core/yida-client');
|
|
18
|
+
const { createAuthRef, createYidaClient, isAuthRefReady } = require('../core/yida-client');
|
|
19
19
|
|
|
20
20
|
const DEFAULT_MAX_TOKENS = 3000;
|
|
21
21
|
const DEFAULT_IMAGE_CONNECTOR = {
|
|
@@ -46,7 +46,7 @@ function printHelp() {
|
|
|
46
46
|
image 上传本地图片并调用识图连接器;也可直接传入 --image-url
|
|
47
47
|
|
|
48
48
|
image 选项:
|
|
49
|
-
--app-type <APP_XXX> 上传图片使用的宜搭应用 ID;未传时尝试读取当前 project/config.json
|
|
49
|
+
--app-type <APP_XXX> 上传图片使用的宜搭应用 ID;未传时尝试读取当前 project/config.json
|
|
50
50
|
--form-uuid <FORM_XXX> 可选,上传回调关联的表单 ID
|
|
51
51
|
--connector-id <id> 识图 HTTP 连接器 ID,默认使用 HAR 中的植物识别连接器
|
|
52
52
|
--action-id <id> 识图动作 ID,默认 flowerrecognize
|
|
@@ -146,7 +146,7 @@ function getAuthRef(options = {}) {
|
|
|
146
146
|
if (options.baseUrl) {
|
|
147
147
|
authRef.baseUrl = options.baseUrl;
|
|
148
148
|
}
|
|
149
|
-
if (!authRef
|
|
149
|
+
if (!isAuthRefReady(authRef)) {
|
|
150
150
|
throw new CliError('未获取到有效宜搭登录态,请先执行 openyida login', {
|
|
151
151
|
code: 'NEED_LOGIN',
|
|
152
152
|
});
|
|
@@ -154,12 +154,7 @@ function getAuthRef(options = {}) {
|
|
|
154
154
|
return authRef;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
function
|
|
158
|
-
const matched = (authRef.cookies || []).filter(cookie => cookie.name === name);
|
|
159
|
-
return matched.length ? matched[0].value : '';
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function inferAppType(options, authRef) {
|
|
157
|
+
function inferAppType(options) {
|
|
163
158
|
if (options.appType) {
|
|
164
159
|
return options.appType;
|
|
165
160
|
}
|
|
@@ -173,11 +168,11 @@ function inferAppType(options, authRef) {
|
|
|
173
168
|
return config.appType;
|
|
174
169
|
}
|
|
175
170
|
} catch {
|
|
176
|
-
// ignore invalid local config and continue with
|
|
171
|
+
// ignore invalid local config and continue with explicit appType validation
|
|
177
172
|
}
|
|
178
173
|
}
|
|
179
174
|
|
|
180
|
-
return
|
|
175
|
+
return '';
|
|
181
176
|
}
|
|
182
177
|
|
|
183
178
|
function getSuccessContent(response, fallbackMessage, code = 'AI_REQUEST_FAILED') {
|
|
@@ -334,7 +329,7 @@ async function uploadImageForAI(filePath, options, authRef) {
|
|
|
334
329
|
});
|
|
335
330
|
}
|
|
336
331
|
|
|
337
|
-
const appType = inferAppType(options
|
|
332
|
+
const appType = inferAppType(options);
|
|
338
333
|
if (!appType) {
|
|
339
334
|
throw new CliError('上传图片需要 appType,请传入 --app-type APP_XXX', {
|
|
340
335
|
code: 'AI_IMAGE_APP_TYPE_REQUIRED',
|
|
@@ -273,8 +273,8 @@ function compileCanvasLocal(source) {
|
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
/**
|
|
276
|
-
*
|
|
277
|
-
* 本地编译不需要
|
|
276
|
+
* 兼容既有调用方传入 options 的异步入口。
|
|
277
|
+
* 本地编译不需要 endpoint,options 保留但忽略。
|
|
278
278
|
* @param {string} source
|
|
279
279
|
* @param {object} [options] 兼容占位,未使用
|
|
280
280
|
* @returns {Promise<{ runtimeCode: string, importedModules: string }>}
|
package/lib/app/create-app.js
CHANGED
|
@@ -10,12 +10,10 @@ const fs = require('fs');
|
|
|
10
10
|
const path = require('path');
|
|
11
11
|
const querystring = require('querystring');
|
|
12
12
|
const {
|
|
13
|
-
loadCookieData,
|
|
14
|
-
triggerLogin,
|
|
15
|
-
resolveBaseUrl,
|
|
16
13
|
httpPost,
|
|
17
14
|
requestWithAutoLogin,
|
|
18
15
|
} = require('../core/utils');
|
|
16
|
+
const { createAuthRef } = require('../core/yida-client');
|
|
19
17
|
const { t } = require('../core/i18n');
|
|
20
18
|
const { buildYidaI18n, normalizeYidaLocale, resolveContentLocale } = require('../core/yida-i18n');
|
|
21
19
|
const { parseOpenOption, withBrowserHandoff } = require('../core/browser-handoff');
|
|
@@ -232,18 +230,7 @@ async function run(args) {
|
|
|
232
230
|
|
|
233
231
|
// Step 1: 读取登录态
|
|
234
232
|
step(1, t('common.step_login', 1));
|
|
235
|
-
|
|
236
|
-
if (!cookieData) {
|
|
237
|
-
info(t('common.login_no_cache'));
|
|
238
|
-
cookieData = triggerLogin();
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
const authRef = {
|
|
242
|
-
csrfToken: cookieData.csrf_token,
|
|
243
|
-
cookies: cookieData.cookies,
|
|
244
|
-
baseUrl: resolveBaseUrl(cookieData),
|
|
245
|
-
cookieData,
|
|
246
|
-
};
|
|
233
|
+
const authRef = createAuthRef();
|
|
247
234
|
chalkSuccess(t('common.login_ready', authRef.baseUrl));
|
|
248
235
|
|
|
249
236
|
const contentLocale = resolveContentLocale({ locale: params.locale, baseUrl: authRef.baseUrl });
|
|
@@ -260,8 +247,7 @@ async function run(args) {
|
|
|
260
247
|
const corpConfig = await httpPost(
|
|
261
248
|
authRef.baseUrl,
|
|
262
249
|
`/query/exclusive/queryCorpAppConfig.json?_api=Global.queryCorpAppConfig&_mock=false&_csrf_token=${authRef.csrfToken}&_locale_time_zone_offset=28800000&_stamp=${Date.now()}`,
|
|
263
|
-
''
|
|
264
|
-
authRef.cookies
|
|
250
|
+
''
|
|
265
251
|
);
|
|
266
252
|
if (corpConfig && corpConfig.content) {
|
|
267
253
|
if (corpConfig.content.forceExclusiveDb === 'y') {openExclusive = 'y';}
|
|
@@ -289,14 +275,14 @@ async function run(args) {
|
|
|
289
275
|
openExclusiveUnit: 'n',
|
|
290
276
|
group: 'ALL',
|
|
291
277
|
});
|
|
292
|
-
return httpPost(auth.baseUrl, '/query/app/registerApp.json', postData
|
|
278
|
+
return httpPost(auth.baseUrl, '/query/app/registerApp.json', postData);
|
|
293
279
|
}, authRef);
|
|
294
280
|
|
|
295
281
|
// 输出结果
|
|
296
282
|
if (response && response.success && response.content) {
|
|
297
283
|
const appType = response.content;
|
|
298
284
|
const appUrl = `${authRef.baseUrl}/${appType}/admin`;
|
|
299
|
-
const corpId = authRef.
|
|
285
|
+
const corpId = authRef.corpId || (authRef.authData && authRef.authData.corp_id) || '';
|
|
300
286
|
|
|
301
287
|
chalkResult(true, t('create_app.success'), [
|
|
302
288
|
['appType', appType],
|