openyida 2026.8.16-beta.0 → 2026.8.17

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.
Files changed (84) hide show
  1. package/README.md +5 -8
  2. package/bin/yida.js +4 -30
  3. package/lib/app/publish.js +78 -65
  4. package/lib/auth/oauth-loopback.js +3 -15
  5. package/lib/auth/token-auth.js +7 -28
  6. package/lib/auth/token-store.js +61 -600
  7. package/lib/core/agent-capabilities.js +16 -210
  8. package/lib/core/command-manifest.js +1 -8
  9. package/lib/core/copy.js +20 -55
  10. package/lib/core/env.js +2 -33
  11. package/lib/core/locales/en.js +10 -24
  12. package/lib/core/locales/zh.js +10 -24
  13. package/lib/core/utils.js +73 -629
  14. package/lib/core/yida-client.js +0 -4
  15. package/lib/samples/yida-create-app/ipd-app-template.js +5 -9
  16. package/package.json +1 -1
  17. package/scripts/postinstall.js +14 -30
  18. package/yida-skills/SKILL.md +12 -13
  19. package/yida-skills/references/official-example-schema-patterns.md +3 -3
  20. package/yida-skills/references/setup-and-env.md +1 -4
  21. package/yida-skills/references/task-retrospective.md +2 -2
  22. package/yida-skills/skills/yida-app/SKILL.md +5 -5
  23. package/yida-skills/skills/yida-app/references/common-issues.md +1 -1
  24. package/yida-skills/skills/yida-app/workflow/step-7-page-code.md +7 -9
  25. package/yida-skills/skills/yida-app/workflow/step-9-output-finish.md +2 -28
  26. package/yida-skills/skills/yida-canvas-custom-page/SKILL.md +36 -37
  27. package/yida-skills/skills/yida-canvas-custom-page/references/canvas-authoring-examples.md +2 -2
  28. package/yida-skills/skills/yida-canvas-custom-page/references/canvas-style-implementation-guide.md +12 -12
  29. package/yida-skills/skills/yida-canvas-custom-page/references/component-library-guide.md +4 -4
  30. package/yida-skills/skills/yida-canvas-custom-page/references/data-bridge-guide.md +7 -7
  31. package/yida-skills/skills/yida-canvas-custom-page/references/dependencies-and-cdn.md +3 -3
  32. package/yida-skills/skills/yida-canvas-custom-page/references/employeefield-verification.md +6 -6
  33. package/yida-skills/skills/yida-canvas-custom-page/references/native-components-bridge.md +4 -4
  34. package/yida-skills/skills/yida-canvas-custom-page/references/navigation-and-entry-guide.md +2 -2
  35. package/yida-skills/skills/yida-canvas-custom-page/references/page-generation-guide.md +9 -9
  36. package/yida-skills/skills/yida-canvas-custom-page/references/theme-runtime-helpers.md +3 -3
  37. package/yida-skills/skills/yida-canvas-data-binding/SKILL.md +11 -11
  38. package/yida-skills/skills/yida-canvas-table-form/SKILL.md +10 -10
  39. package/yida-skills/skills/yida-canvas-upgrade/SKILL.md +25 -25
  40. package/yida-skills/skills/yida-canvas-upgrade/references/migration-examples.md +3 -3
  41. package/yida-skills/skills/yida-chart/SKILL.md +2 -2
  42. package/yida-skills/skills/yida-chart/references/examples.md +1 -1
  43. package/yida-skills/skills/yida-create-app/SKILL.md +2 -2
  44. package/yida-skills/skills/yida-create-form-page/SKILL.md +1 -1
  45. package/yida-skills/skills/yida-create-page/SKILL.md +2 -5
  46. package/yida-skills/skills/yida-custom-page/SKILL.md +37 -21
  47. package/yida-skills/skills/yida-custom-page/references/assets-guide.md +2 -2
  48. package/yida-skills/skills/yida-custom-page/references/coding-guide.md +3 -9
  49. package/yida-skills/skills/yida-custom-page/references/component-jsx-guide.md +2 -65
  50. package/yida-skills/skills/yida-custom-page/references/design-system.md +2 -2
  51. package/yida-skills/skills/yida-dashboard/SKILL.md +23 -28
  52. package/yida-skills/skills/yida-dashboard/references/interaction-patterns.md +2 -2
  53. package/yida-skills/skills/yida-dashboard/references/pitfalls.md +1 -1
  54. package/yida-skills/skills/yida-dashboard/references/structure-and-layout.md +4 -4
  55. package/yida-skills/skills/yida-dashboard/references/theme-presets.md +1 -1
  56. package/yida-skills/skills/yida-data-source-connectors/SKILL.md +28 -28
  57. package/yida-skills/skills/yida-density/SKILL.md +7 -7
  58. package/yida-skills/skills/yida-design/SKILL.md +3 -4
  59. package/yida-skills/skills/yida-design/references/page-quality-gates.md +1 -1
  60. package/yida-skills/skills/yida-design/references/style-design-selection.md +1 -1
  61. package/yida-skills/skills/yida-design/references/style-designs/_design-md-template.md +1 -1
  62. package/yida-skills/skills/yida-design/references/style-designs/soft-blue-grid-analytic-dashboard.md +1 -1
  63. package/yida-skills/skills/yida-design/references/visual-decision-engine.md +1 -1
  64. package/yida-skills/skills/yida-design/sub_skill/page-design/SKILL.md +2 -2
  65. package/yida-skills/skills/yida-design/workflow/output-design.md +9 -8
  66. package/yida-skills/skills/yida-design/workflow/output-prd.md +1 -1
  67. package/yida-skills/skills/yida-design/workflow/step-3-information-architecture.md +3 -3
  68. package/yida-skills/skills/yida-design/workflow/step-6-handoff.md +1 -1
  69. package/yida-skills/skills/yida-form-detail/references/injection-guide.md +1 -1
  70. package/yida-skills/skills/yida-get-schema/SKILL.md +2 -2
  71. package/yida-skills/skills/yida-login/SKILL.md +3 -6
  72. package/yida-skills/skills/yida-nav-shell/SKILL.md +8 -15
  73. package/yida-skills/skills/yida-nav-shell/references/nav-shell-patterns.md +11 -11
  74. package/yida-skills/skills/yida-ppt-slider/SKILL.md +16 -18
  75. package/yida-skills/skills/yida-ppt-slider/references/dark-tech-theme.md +3 -3
  76. package/yida-skills/skills/yida-ppt-slider/references/echarts-race-example.md +1 -1
  77. package/yida-skills/skills/yida-ppt-slider/references/examples.md +5 -5
  78. package/yida-skills/skills/yida-process-rule/SKILL.md +1 -1
  79. package/yida-skills/skills/yida-publish-page/SKILL.md +42 -44
  80. package/yida-skills/skills/yida-rechart/SKILL.md +8 -8
  81. package/yida-skills/skills/yida-report/SKILL.md +1 -1
  82. package/yida-skills/skills-index.json +50 -58
  83. package/lib/app/check-prd-completeness.js +0 -631
  84. package/lib/app/display-page-readback.js +0 -187
package/README.md CHANGED
@@ -68,9 +68,9 @@ OpenYida returns a compact machine-readable summary with the version, login stat
68
68
  openyida login
69
69
  ```
70
70
 
71
- 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 user auth store when available. If the user auth store is not writable, OpenYida explicitly falls back to the current project cache and reports that narrower persistence scope.
71
+ 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.
72
72
 
73
- When the user names a target Yida entry URL, pass it to the login command so OpenYida can select the matching environment and auth profile. For example:
73
+ 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`:
74
74
 
75
75
  ```bash
76
76
  openyida login https://yida-group.alibaba-inc.com/
@@ -185,16 +185,14 @@ Form definitions support 19 business field types plus verified presentation/layo
185
185
 
186
186
  ```bash
187
187
  openyida create-page APP_XXX "Dashboard" --mode dashboard
188
- openyida check-page pages/src/home.canvas.jsx --json
189
- openyida compile pages/src/home.canvas.jsx
190
188
  openyida publish pages/src/home.canvas.jsx APP_XXX FORM_XXX
191
189
  ```
192
190
 
193
- Custom page source is authored directly from PRD and design guidance. Code Canvas is the default output (`.canvas.jsx`); use `.oyd.jsx` only when the page must use the 普通自定义页面 JSX/Jsx 组件链路.
191
+ Custom page source is authored directly from PRD and design guidance. Custom page development uses `yida-canvas-custom-page` and `.canvas.jsx`.
194
192
 
195
- For member, department, attachment, and image upload components, choose the page chain first. Code Canvas pages should follow `yida-canvas-custom-page/references/native-components-bridge.md` for feature detection, fallback, and value normalization. 普通自定义页面 JSX/Jsx pages should use `.oyd.jsx`, read `yida-custom-page/references/component-jsx-guide.md`, and read `attachment-upload-guide.md` when upload fields are involved.
193
+ For member, department, attachment, and image upload components, `.canvas.jsx` pages should follow `yida-canvas-custom-page/references/native-components-bridge.md` for feature detection, fallback, and value normalization.
196
194
 
197
- For the current AI custom page native-component support matrix, see [Yida native components supported by AI custom pages](https://demo.aliwork.com/o/openyida/sample/canvas-native-components).
195
+ For the current custom page native-component support matrix, see [Yida native components supported by custom pages](https://demo.aliwork.com/o/openyida/sample/canvas-native-components).
198
196
 
199
197
  ### Workflow, Data, and Permissions
200
198
 
@@ -395,7 +393,6 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
395
393
  | `openyida list-forms <appType> [--keyword <text>]` | List forms/pages in an app |
396
394
  | `openyida aggregate-table <list\|create-empty\|inspect\|preview\|save\|publish\|status> <appType> ...` | Manage aggregate tables (virtualView) |
397
395
  | `openyida get-schema <appType> <formUuid\|--all> [--summary-json\|--field-map-json]` | Get one form Schema or all form Schemas |
398
- | `openyida check-prd-completeness <prd.md> --app-type <appType> [--build-manifest <file>] [--json]` | Check PRD page/resource count risk |
399
396
  | `openyida er <appType> [--format mermaid\|json] [--output file] [--include-system] [--include-pages]` | Export app entity relationship diagram |
400
397
  | `openyida create-page <appType> "<name>" [--mode dashboard] [--hide-nav] [--locale zh_CN\|en_US\|ja_JP] [--open\|--no-open]` | Create a custom display page |
401
398
  | `openyida build-page <sourceFile> [--output file\|--write]` | Build Yida-compatible page source |
package/bin/yida.js CHANGED
@@ -30,22 +30,13 @@ function isAgentEnvironment(env) {
30
30
  env.CLAUDE_CODE_ENTRYPOINT ||
31
31
  env.MULERUN_CHAT_ID ||
32
32
  env.MULE_DATA_DIR ||
33
- env.MULE_WORKSPACE_DIR ||
34
33
  env.OPENCODE ||
35
34
  env.OPENCODE_CLIENT ||
36
35
  env.QODER_IDE ||
37
36
  env.QODER_AGENT ||
38
37
  env.QODERCLI_INTEGRATION_MODE ||
39
- env.QODER_WORK_INTEGRATION_PRODUCT ||
40
38
  env.QWENWORK_INTEGRATION_MODE ||
41
39
  env.QWENWORKCN_INTEGRATION_MODE ||
42
- env.QWENWORK ||
43
- env.QWENWORK_CLIENT ||
44
- env.QWENWORK_WORKSPACE_DIR ||
45
- env.QWENWORK_SANDBOX_ID ||
46
- env.QWENWORK_PREVIEW_URL ||
47
- env.QWENWORK_VNC_URL ||
48
- (env.AGENT_PLATFORM || '').toLowerCase().includes('qwenwork') ||
49
40
  env.CURSOR_TRACE_ID ||
50
41
  env.AGENT_WORK_ROOT ||
51
42
  env.OPENYIDA_AGENT_MODE ||
@@ -275,12 +266,6 @@ function printLoginResult(result) {
275
266
  status: result.status || (tokenUsable ? 'ok' : 'token_not_issued'),
276
267
  auth_mode: 'token',
277
268
  auth_source: result.auth_source || result.authSource,
278
- auth_store: result.auth_store || result.authStore,
279
- auth_profile: result.auth_profile || result.authProfile,
280
- persistence_scope: result.persistence_scope || result.persistenceScope,
281
- user_auth_store_writable: result.user_auth_store_writable !== undefined
282
- ? result.user_auth_store_writable
283
- : result.userAuthStoreWritable,
284
269
  can_auto_use: result.can_auto_use !== undefined ? !!result.can_auto_use : tokenUsable,
285
270
  token_type: result.token_type || 'Bearer',
286
271
  access_token: maskSensitiveAuthOutput({ access_token: result.access_token }).access_token,
@@ -291,7 +276,6 @@ function printLoginResult(result) {
291
276
  user_name: result.user_name,
292
277
  failure_reason: result.failure_reason,
293
278
  message: result.message,
294
- warning: result.warning,
295
279
  raw: tokenUsable ? undefined : result.raw,
296
280
  };
297
281
  console.log(JSON.stringify(summary));
@@ -428,7 +412,6 @@ function applyLoginEnvironmentFlags(cliArgs, options = {}) {
428
412
  const valuePassthroughFlags = new Set([
429
413
  '--corp-id',
430
414
  '--client-id',
431
- '--profile',
432
415
  '--user-id',
433
416
  ]);
434
417
  const targetUrlFlags = new Set([
@@ -540,9 +523,6 @@ function printLoginHelp() {
540
523
  function buildTokenLoginOptions(loginArgs) {
541
524
  return {
542
525
  clientId: getArgValue(loginArgs, '--client-id'),
543
- corpId: getArgValue(loginArgs, '--corp-id'),
544
- userId: getArgValue(loginArgs, '--user-id'),
545
- authProfile: getArgValue(loginArgs, '--profile'),
546
526
  quiet: process.env.YIDA_QUIET === '1' || loginArgs.includes('--quiet'),
547
527
  noBrowser: loginArgs.includes('--no-browser'),
548
528
  };
@@ -646,9 +626,9 @@ async function main() {
646
626
  } else {
647
627
  assertNoUnsupportedLegacyLoginFlags(rawArgs, loginArgs);
648
628
  if (loginArgs.includes('--check-only')) {
649
- console.log(JSON.stringify(getAuthStatus(buildTokenLoginOptions(loginArgs)), null, 2));
629
+ console.log(JSON.stringify(getAuthStatus(), null, 2));
650
630
  } else if (isEnvAuthMode()) {
651
- printLoginResult(getAuthStatus(buildTokenLoginOptions(loginArgs)));
631
+ printLoginResult(getAuthStatus());
652
632
  } else {
653
633
  const { tokenLogin } = require('../lib/auth/token-auth');
654
634
  const result = await tokenLogin(buildTokenLoginOptions(loginArgs));
@@ -672,14 +652,14 @@ async function main() {
672
652
  if (!subCommand || subCommand === '--help' || subCommand === '-h') {
673
653
  printAuthHelp();
674
654
  } else if (subCommand === 'status') {
675
- console.log(JSON.stringify(getAuthStatus(buildTokenLoginOptions(authArgs)), null, 2));
655
+ console.log(JSON.stringify(getAuthStatus(), null, 2));
676
656
  } else if (subCommand === 'login') {
677
657
  if (hasHelpFlag(authArgs)) {
678
658
  printLoginHelp();
679
659
  } else {
680
660
  assertNoUnsupportedLegacyLoginFlags(rawArgs.slice(1), authArgs);
681
661
  const result = isEnvAuthMode()
682
- ? getAuthStatus(buildTokenLoginOptions(authArgs))
662
+ ? getAuthStatus()
683
663
  : await tokenLogin(buildTokenLoginOptions(authArgs));
684
664
  printLoginResult(result);
685
665
  }
@@ -754,12 +734,6 @@ async function main() {
754
734
  break;
755
735
  }
756
736
 
757
- case 'check-prd-completeness': {
758
- const { run } = require('../lib/app/check-prd-completeness');
759
- await run(args);
760
- break;
761
- }
762
-
763
737
  case 'er': {
764
738
  const { run } = require('../lib/app/er');
765
739
  await run(args);
@@ -53,9 +53,6 @@ const {
53
53
  const {
54
54
  buildCanvasPageSchemaContent,
55
55
  } = require('./services/canvas-page-schema-builder');
56
- const {
57
- verifyPublishedContentMatch,
58
- } = require('./display-page-readback');
59
56
 
60
57
  // ── 配置读取 ──────────────────────────────────────────
61
58
  const CONFIG = fs.existsSync(path.resolve(findProjectRoot(), 'config.json')) ? JSON.parse(fs.readFileSync(path.resolve(findProjectRoot(), 'config.json'), 'utf-8')) : {};
@@ -648,55 +645,79 @@ async function ensurePublishTargetOrExit(appType, formUuid, authRef, options = {
648
645
  return null;
649
646
  }
650
647
 
651
- async function runPublishReadbackHealthCheck(appType, formUuid, authRef, schemaContent, publishMode) {
652
- const baseResult = {
653
- ok: false,
654
- mode: 'publish_readback',
655
- authMode: 'token',
656
- targetReadable: false,
657
- schemaParsed: false,
658
- displayComponentPresent: false,
659
- publishedContentMatched: false,
660
- };
648
+ function sendHealthCheckRequest(pageUrl, cookies) {
649
+ return new Promise((resolve) => {
650
+ let parsedUrl;
651
+ try {
652
+ parsedUrl = new URL(pageUrl);
653
+ } catch (urlError) {
654
+ resolve({ ok: false, statusCode: 0, error: urlError.message });
655
+ return;
656
+ }
657
+ const isHttps = parsedUrl.protocol === 'https:';
658
+ const requestModule = isHttps ? https : http;
659
+ const cookieHeader = Array.isArray(cookies) ? cookies
660
+ .filter((cookie) => cookie && cookie.name !== undefined && cookie.value !== undefined)
661
+ .map((cookie) => `${cookie.name}=${cookie.value}`)
662
+ .join('; ') : '';
661
663
 
662
- let readback;
663
- try {
664
- readback = await fetchExistingSchemaContent(appType, formUuid, authRef);
665
- } catch (readbackError) {
666
- return {
667
- ...baseResult,
668
- reason: 'schema_readback_failed',
669
- error: readbackError && readbackError.message ? readbackError.message : t('common.unknown_error'),
664
+ if (!cookieHeader) {
665
+ resolve({
666
+ ok: false,
667
+ skipped: true,
668
+ reason: 'missing_cookies',
669
+ statusCode: 0,
670
+ error: t('common.request_failed'),
671
+ });
672
+ return;
673
+ }
674
+
675
+ const requestOptions = {
676
+ hostname: parsedUrl.hostname,
677
+ port: parsedUrl.port || (isHttps ? 443 : 80),
678
+ path: `${parsedUrl.pathname}${parsedUrl.search}`,
679
+ method: 'GET',
680
+ headers: {
681
+ Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
682
+ Cookie: cookieHeader,
683
+ },
684
+ timeout: 30000,
670
685
  };
671
- }
672
686
 
673
- const match = verifyPublishedContentMatch(readback.schema, schemaContent, publishMode);
674
- const resultPayload = {
675
- ...baseResult,
676
- targetReadable: true,
677
- schemaParsed: true,
678
- displayComponentPresent: match.displayComponentPresent,
679
- publishedContentMatched: match.publishedContentMatched,
680
- };
687
+ let request;
688
+ try {
689
+ request = requestModule.request(requestOptions, (response) => {
690
+ let responseData = '';
691
+ response.on('data', (chunk) => {
692
+ if (responseData.length < 2000) {
693
+ responseData += chunk;
694
+ }
695
+ });
696
+ response.on('end', () => {
697
+ const statusCode = response.statusCode || 0;
698
+ resolve({
699
+ ok: statusCode >= 200 && statusCode < 400,
700
+ statusCode,
701
+ snippet: responseData.substring(0, 300).replace(/\s+/g, ' ').trim(),
702
+ });
703
+ });
704
+ });
705
+ } catch (requestError) {
706
+ resolve({ ok: false, statusCode: 0, error: requestError.message });
707
+ return;
708
+ }
681
709
 
682
- if (!match.displayComponentPresent) {
683
- return {
684
- ...resultPayload,
685
- reason: 'display_component_missing',
686
- };
687
- }
710
+ request.on('timeout', () => {
711
+ request.destroy();
712
+ resolve({ ok: false, statusCode: 0, error: t('common.request_timeout') });
713
+ });
688
714
 
689
- if (!match.publishedContentMatched) {
690
- return {
691
- ...resultPayload,
692
- reason: 'published_content_mismatch',
693
- };
694
- }
715
+ request.on('error', (requestError) => {
716
+ resolve({ ok: false, statusCode: 0, error: requestError.message });
717
+ });
695
718
 
696
- return {
697
- ...resultPayload,
698
- ok: true,
699
- };
719
+ request.end();
720
+ });
700
721
  }
701
722
 
702
723
  // ── 主流程 ────────────────────────────────────────────
@@ -727,7 +748,7 @@ async function runMain(argv) {
727
748
  process.exit(1);
728
749
  }
729
750
 
730
- // 路由:默认 native;.canvas.jsx / .canvas.tsx 源文件自动走 Code Canvas 链路,
751
+ // 路由:默认平台 JSX 组件;.canvas.jsx / .canvas.tsx 源文件自动走 YidaCodeCanvas 发布分支,
731
752
  // --canvas 作为显式覆盖(用于扩展名不规范但确为 canvas 源码的场景)。
732
753
  const isCanvas = canvasFlag || /\.canvas\.(jsx|tsx)$/i.test(sourcePath);
733
754
 
@@ -741,7 +762,7 @@ async function runMain(argv) {
741
762
  let canvasResult = null;
742
763
 
743
764
  if (isCanvas) {
744
- // Code Canvas 链路:跳过 native 编译/lint,改用本地 Babel 编译
765
+ // YidaCodeCanvas 发布分支:跳过平台 JSX 组件编译/lint,改用本地 Babel 编译
745
766
  // (JSX/TS → runtimeCode + importedModules),无需登录态,可在开浏览器前失败快。
746
767
  step(1, t('publish.step_canvas_compile'));
747
768
  info(t('publish.canvas_compiling'));
@@ -791,8 +812,10 @@ async function runMain(argv) {
791
812
 
792
813
  step(2, t('common.step_login', 2));
793
814
  const authRef = createAuthRef();
815
+ let cookies = authRef.cookies;
794
816
  let baseUrl = authRef.baseUrl;
795
817
  await ensurePublishTargetOrExit(appType, formUuid, authRef, { force });
818
+ cookies = authRef.cookies;
796
819
  baseUrl = authRef.baseUrl;
797
820
 
798
821
  let schemaContent;
@@ -816,6 +839,7 @@ async function runMain(argv) {
816
839
  fail(t('publish.data_source_fetch_failed', dataSourceError.message));
817
840
  process.exit(1);
818
841
  }
842
+ cookies = authRef.cookies;
819
843
  baseUrl = authRef.baseUrl;
820
844
  schemaContent = buildSchemaContent(sourceCode, compiledCode, formUuid, { existingDataSource });
821
845
  }
@@ -849,6 +873,7 @@ async function runMain(argv) {
849
873
  step(4, t('publish.step_config'));
850
874
  info(t('publish.sending_config'));
851
875
  const configResponse = await sendUpdateConfigRequestWithAuth(authRef, appType, savedFormUuid, version, 8);
876
+ cookies = authRef.cookies;
852
877
  baseUrl = authRef.baseUrl || baseUrl;
853
878
 
854
879
  const pageUrl = `${baseUrl}/${appType}/workbench/${savedFormUuid}`;
@@ -858,30 +883,18 @@ async function runMain(argv) {
858
883
  if (healthCheck) {
859
884
  step(5, t('publish.step_health_check'));
860
885
  try {
861
- healthCheckResult = await runPublishReadbackHealthCheck(
862
- appType,
863
- savedFormUuid,
864
- authRef,
865
- schemaContent,
866
- isCanvas ? 'canvas' : 'native'
867
- );
886
+ healthCheckResult = await sendHealthCheckRequest(pageUrl, cookies);
868
887
  } catch (healthCheckError) {
869
888
  healthCheckResult = {
870
889
  ok: false,
871
- mode: 'publish_readback',
872
- authMode: 'token',
873
- targetReadable: false,
874
- schemaParsed: false,
875
- displayComponentPresent: false,
876
- publishedContentMatched: false,
877
- reason: 'schema_readback_failed',
890
+ statusCode: 0,
878
891
  error: healthCheckError && healthCheckError.message ? healthCheckError.message : t('common.unknown_error'),
879
892
  };
880
893
  }
881
894
  if (healthCheckResult.ok) {
882
- success(t('publish.health_check_ok', healthCheckResult.mode));
895
+ success(t('publish.health_check_ok', healthCheckResult.statusCode));
883
896
  } else {
884
- warn(t('publish.health_check_failed', healthCheckResult.reason || '-', healthCheckResult.error || t('common.unknown_error')));
897
+ warn(t('publish.health_check_failed', healthCheckResult.statusCode || '-', healthCheckResult.error || healthCheckResult.snippet || t('common.unknown_error')));
885
898
  }
886
899
  }
887
900
 
@@ -946,7 +959,7 @@ if (require.main === module) {
946
959
  module.exports.buildMissingSourceHints = buildMissingSourceHints;
947
960
  module.exports.findDuplicateSourceMismatches = findDuplicateSourceMismatches;
948
961
  module.exports.loadPublishSource = loadPublishSource;
949
- module.exports.runPublishReadbackHealthCheck = runPublishReadbackHealthCheck;
962
+ module.exports.sendHealthCheckRequest = sendHealthCheckRequest;
950
963
  module.exports.normalizeFormType = normalizeFormType;
951
964
  module.exports.findPublishTarget = findPublishTarget;
952
965
  module.exports.isCustomPageTarget = isCustomPageTarget;
@@ -290,17 +290,13 @@ function resolveBrowserLauncher(url, platform = process.platform, openMode = 'le
290
290
  function isQwenWorkEnvironment(env = process.env) {
291
291
  const bundleId = String(env.__CFBundleIdentifier || '').toLowerCase();
292
292
  const product = String(env.QODER_WORK_INTEGRATION_PRODUCT || '').toLowerCase();
293
- const qoderConfigDir = String(`${env.QODER_CONFIG_DIR || ''} ${env.QODERCN_CONFIG_DIR || ''}`).toLowerCase();
294
- const qoderWorkerCwd = String(env.QODER_WORKER_CWD || '').replace(/\\/g, '/').toLowerCase();
293
+ const qoderConfigDir = String(env.QODER_CONFIG_DIR || env.QODERCN_CONFIG_DIR || '');
295
294
  return !!(
296
295
  env.QWENWORK_INTEGRATION_MODE ||
297
296
  env.QWENWORKCN_INTEGRATION_MODE ||
298
297
  product.includes('qwenwork') ||
299
298
  product.includes('qwen-work') ||
300
- product.includes('qwenworkcn') ||
301
299
  qoderConfigDir.includes('.qwenworkcn') ||
302
- qoderWorkerCwd.includes('.qwenworkcn/workspace') ||
303
- qoderWorkerCwd.includes('/.qwenworkcn/') ||
304
300
  bundleId.includes('qwenwork') ||
305
301
  bundleId.includes('qwen-work')
306
302
  );
@@ -423,13 +419,8 @@ function openBrowser(url, options = {}) {
423
419
  return runLegacy();
424
420
  }
425
421
 
426
- function callerOwnsLoginBrowser(options = {}) {
427
- const env = options.env || process.env;
428
- return !!options.noBrowser || env.OPENYIDA_NO_BROWSER === '1';
429
- }
430
-
431
422
  function launchLoginBrowser(authUrl, options = {}) {
432
- if (callerOwnsLoginBrowser(options)) {
423
+ if (options.noBrowser) {
433
424
  return false;
434
425
  }
435
426
  const openBrowserImpl = options.openBrowser || openBrowser;
@@ -580,11 +571,8 @@ function runDingtalkLoopback(options = {}) {
580
571
  scope: options.scope,
581
572
  prompt: options.prompt,
582
573
  });
583
- const callerOwnsBrowser = callerOwnsLoginBrowser(options);
584
- if (!options.quiet || callerOwnsBrowser) {
585
- process.stderr.write(`Open this URL to login:\n${authUrl}\n`);
586
- }
587
574
  if (!options.quiet) {
575
+ process.stderr.write(`Open this URL to login:\n${authUrl}\n`);
588
576
  process.stderr.write(`Waiting for browser authorization (timeout: ${Math.ceil(timeoutMs / 1000)} seconds). Stop the task or press Ctrl+C to cancel.\n`);
589
577
  }
590
578
  launchLoginBrowser(authUrl, options);
@@ -17,7 +17,6 @@ const {
17
17
  loadTokenSession,
18
18
  maskToken,
19
19
  normalizeTokenSession,
20
- resolveTokenSession,
21
20
  saveBusinessContext,
22
21
  saveTokenSession,
23
22
  } = require('./token-store');
@@ -304,27 +303,20 @@ async function tokenLogin(options = {}) {
304
303
  }
305
304
 
306
305
  function tokenStatus(options = {}) {
307
- const resolution = resolveTokenSession(options);
308
- const session = resolution.session;
306
+ const session = loadTokenSession(options);
309
307
  if (!session || (!session.access_token && !session.refresh_token)) {
310
308
  const env = options.env || process.env;
311
309
  const hostInjected = isHostInjectedTokenMode(env);
312
310
  const status = {
313
311
  ok: false,
314
312
  auth_mode: 'token',
315
- auth_source: resolution.auth_source || (hostInjected ? 'env' : undefined),
316
- auth_store: resolution.auth_store,
317
- auth_profile: resolution.auth_profile,
318
- status: resolution.status === 'profile_required' ? 'profile_required' : 'not_logged_in',
313
+ auth_source: hostInjected ? 'env' : undefined,
314
+ status: 'not_logged_in',
319
315
  can_auto_use: false,
320
- failure_reason: hostInjected ? 'env_token_missing' : resolution.status,
321
- message: resolution.message || (hostInjected
316
+ failure_reason: hostInjected ? 'env_token_missing' : undefined,
317
+ message: hostInjected
322
318
  ? 'host-injected token is missing. Ask the host to inject OPENYIDA_ACCESS_TOKEN or OPENYIDA_REFRESH_TOKEN.'
323
- : undefined),
324
- candidate_count: resolution.candidate_count,
325
- user_auth_store_writable: resolution.user_auth_store_writable,
326
- persistence_scope: resolution.persistence_scope,
327
- warning: resolution.warning,
319
+ : undefined,
328
320
  };
329
321
  if (!hostInjected) {
330
322
  status.token_file = require('./token-store').getTokenFilePath(options);
@@ -336,11 +328,6 @@ function tokenStatus(options = {}) {
336
328
  ok: true,
337
329
  auth_mode: 'token',
338
330
  auth_source: session.auth_source,
339
- auth_store: session.auth_store,
340
- auth_profile: session.auth_profile,
341
- persistence_scope: session.persistence_scope,
342
- user_auth_store_writable: session.user_auth_store_writable,
343
- warning: session.warning,
344
331
  status: 'refresh_required',
345
332
  can_auto_use: true,
346
333
  refresh_token: maskToken(session.refresh_token),
@@ -355,11 +342,6 @@ function tokenStatus(options = {}) {
355
342
  ok: true,
356
343
  auth_mode: 'token',
357
344
  auth_source: session.auth_source,
358
- auth_store: session.auth_store,
359
- auth_profile: session.auth_profile,
360
- persistence_scope: session.persistence_scope,
361
- user_auth_store_writable: session.user_auth_store_writable,
362
- warning: session.warning,
363
345
  status: 'ok',
364
346
  can_auto_use: true,
365
347
  token_type: session.token_type,
@@ -467,10 +449,7 @@ async function tokenLogout(options = {}) {
467
449
  // Local logout should still clear the credential cache.
468
450
  }
469
451
  }
470
- clearTokenSession({
471
- ...options,
472
- authProfile: session && session.auth_profile,
473
- });
452
+ clearTokenSession(options);
474
453
  return {
475
454
  ok: true,
476
455
  auth_mode: 'token',