openyida 2026.5.25 → 2026.5.27-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -297,7 +297,7 @@ For overseas apps, pass `--locale en_US` or `--locale ja_JP` on creation command
297
297
  | `openyida app-list [--size N]` | List Yida applications |
298
298
  | `openyida corp-efficiency [overview\|details\|detail\|groups\|notify] [options] [--open\|--no-open]` | Query enterprise efficiency metrics, detail report entries, and related notification actions |
299
299
  | `openyida create-app "<name>"\|--name <name> [options] [--locale zh_CN\|en_US\|ja_JP] [--open\|--no-open]` | Create an application and output `appType` |
300
- | `openyida update-app <appType> --name "..."` | Update application metadata |
300
+ | `openyida update-app <appType> [--name "..."] [--layout slide\|ver] [--theme deepBlue]` | Update application metadata and theme/layout fields |
301
301
  | `openyida nav-group <list\|create\|rename\|delete\|move\|hide\|show> <appType> ...` | Manage sidebar navigation groups and move pages between groups |
302
302
  | `openyida app-permission <get\|set\|add\|remove\|search-user> ...` | Manage app primary admins, data admins, and developer members |
303
303
  | `openyida i18n <overview\|config\|languages\|list\|upsert\|delete\|translate\|translate-all\|upgrade> <appType> ...` | Manage app multilingual copy and language configuration |
@@ -330,7 +330,7 @@ For overseas apps, pass `--locale en_US` or `--locale ja_JP` on creation command
330
330
 
331
331
  | Command | Description |
332
332
  |---------|-------------|
333
- | `openyida data <action> <resource> [args]` | Unified data management for forms, processes, tasks, and subforms |
333
+ | `openyida data <action> <resource> [args]` | Unified data management for forms, processes, tasks, and subforms; form queries support `--all` and `--form-uuid` subform hydration |
334
334
  | `openyida data check <appType> <formUuid> <rules.json>` | Detect anomalous process-form records |
335
335
  | `openyida task-center <type> [options]` | Query todo, created, processed, CC, or proxy-submitted tasks |
336
336
  | `openyida agent-center <sub-command>` | Manage Yida process delegation and departure delegation |
@@ -372,6 +372,7 @@ For overseas apps, pass `--locale en_US` or `--locale ja_JP` on creation command
372
372
  | `openyida sample [--list]` | Emit sample templates |
373
373
  | `openyida bridge start [--token <pair-token>] [--port 6736] [--open]` | Start the local OpenYida web bridge for `https://demo.aliwork.com/s/openyida` |
374
374
  | `openyida doctor [--fix]` | Diagnose and repair environment issues |
375
+ | `openyida db-seq-fix [--fix]` | Detect and repair PostgreSQL sequence drift |
375
376
  | `openyida formula evaluate <formula\|file> [--schema file]` | Static-check formula syntax and field references |
376
377
  | `openyida update` | Update OpenYida through npm |
377
378
  | `openyida export-conversation [options]` | Export AI conversation history |
package/bin/yida.js CHANGED
@@ -27,6 +27,7 @@ function isAgentEnvironment(env) {
27
27
  env.CLAUDE_CODE ||
28
28
  env.CLAUDE_CODE_ENTRYPOINT ||
29
29
  env.OPENCODE ||
30
+ env.OPENCODE_CLIENT ||
30
31
  env.QODER_IDE ||
31
32
  env.QODER_AGENT ||
32
33
  env.QODERCLI_INTEGRATION_MODE ||
@@ -287,7 +288,7 @@ function noteLoginCommandResult(result) {
287
288
 
288
289
  function isAgentConversationEnvironment() {
289
290
  const { detectActiveTool } = require('../lib/core/utils');
290
- return !!detectActiveTool();
291
+ return !!detectActiveTool() || process.env.OPENYIDA_AGENT_MODE === '1';
291
292
  }
292
293
 
293
294
  function shouldUseBrowserHandoffLogin(cliArgs) {
@@ -303,12 +304,13 @@ function shouldUseAgentLogin(cliArgs) {
303
304
  }
304
305
 
305
306
  function shouldUsePlaywrightFallbackInAgentLogin() {
306
- const { detectActiveTool } = require('../lib/core/utils');
307
- const activeTool = detectActiveTool();
308
- if (activeTool && activeTool.tool === 'wukong') {
309
- return true;
310
- }
311
- return process.env.OPENYIDA_AGENT_PLAYWRIGHT_FALLBACK === '1';
307
+ const { hasDesktopEnvironment } = require('../lib/core/utils');
308
+ return hasDesktopEnvironment() || process.env.OPENYIDA_AGENT_PLAYWRIGHT_FALLBACK === '1';
309
+ }
310
+
311
+ function shouldUseDesktopBrowserLogin() {
312
+ const { hasDesktopEnvironment } = require('../lib/core/utils');
313
+ return hasDesktopEnvironment();
312
314
  }
313
315
 
314
316
  function shouldUseCodexQrLogin(cliArgs) {
@@ -477,6 +479,8 @@ async function main() {
477
479
  if (cachedResult.status === 'ok') {
478
480
  printLoginResult(cachedResult);
479
481
  } else {
482
+ const { detectActiveTool } = require('../lib/core/utils');
483
+ const activeTool = detectActiveTool();
480
484
  const { interactiveLogin } = require('../lib/auth/login');
481
485
  const browserResult = interactiveLogin({
482
486
  playwrightFallback: shouldUsePlaywrightFallbackInAgentLogin(),
@@ -485,12 +489,10 @@ async function main() {
485
489
  printLoginResult(browserResult);
486
490
  } else {
487
491
  // CDP/Playwright 失败后的兜底策略:
488
- // QoderWork 有 in-app browser,优先使用 browser handoff;其余走终端二维码
489
- const { detectActiveTool } = require('../lib/core/utils');
490
- const activeTool = detectActiveTool();
491
- if (activeTool && activeTool.tool === 'qoderwork') {
492
+ // Wukong/QoderWork 有 in-app browser,优先使用 browser handoff;其余走 AI 对话框 QR handoff。
493
+ if (activeTool && (activeTool.tool === 'wukong' || activeTool.tool === 'qoderwork')) {
492
494
  const { codexLogin } = require('../lib/auth/codex-login');
493
- const result = await codexLogin({ tool: 'qoderwork' });
495
+ const result = await codexLogin({ tool: activeTool.tool });
494
496
  printLoginResult(result);
495
497
  } else {
496
498
  const { startCodexQrLogin } = require('../lib/auth/qr-login');
@@ -514,6 +516,14 @@ async function main() {
514
516
  printLoginResult(cachedResult);
515
517
  break;
516
518
  }
519
+ if (shouldUseDesktopBrowserLogin()) {
520
+ const { interactiveLogin } = require('../lib/auth/login');
521
+ const browserResult = interactiveLogin({ playwrightFallback: true });
522
+ if (browserResult) {
523
+ printLoginResult(browserResult);
524
+ break;
525
+ }
526
+ }
517
527
  const { qrLogin } = require('../lib/auth/qr-login');
518
528
  const result = await qrLogin({ corpId: getArgValue(loginArgs, '--corp-id') });
519
529
  printLoginResult(result);
@@ -534,9 +544,25 @@ async function main() {
534
544
  if (subCommand === 'status') {
535
545
  authStatus();
536
546
  } else if (subCommand === 'login') {
537
- const authArgs = [subCommand, ...applyLoginEnvironmentFlags(args.slice(1))];
538
- const loginType = shouldUseBrowserHandoffLogin(authArgs) ? 'browser' : 'qrcode';
539
- await authLogin({ type: loginType, corpId: getArgValue(authArgs, '--corp-id') });
547
+ const authArgs = applyLoginEnvironmentFlags(args.slice(1));
548
+ let loginType = 'qrcode';
549
+ if (authArgs.includes('--codex')) {
550
+ loginType = 'codex';
551
+ } else if (authArgs.includes('--qoder')) {
552
+ loginType = 'qoder';
553
+ } else if (authArgs.includes('--wukong')) {
554
+ loginType = 'wukong';
555
+ } else if (authArgs.includes('--browser')) {
556
+ loginType = 'browser';
557
+ }
558
+ const result = await authLogin({
559
+ type: loginType,
560
+ corpId: getArgValue(authArgs, '--corp-id'),
561
+ forceTerminalQr: authArgs.includes('--qr'),
562
+ });
563
+ if (result) {
564
+ printLoginResult(result);
565
+ }
540
566
  } else if (subCommand === 'refresh') {
541
567
  authRefresh();
542
568
  } else if (subCommand === 'logout') {
@@ -1065,6 +1091,12 @@ async function main() {
1065
1091
  break;
1066
1092
  }
1067
1093
 
1094
+ case 'db-seq-fix': {
1095
+ const { run: runDbSeqFix } = require('../lib/db/db-seq-fix');
1096
+ await runDbSeqFix(args);
1097
+ break;
1098
+ }
1099
+
1068
1100
  case 'update': {
1069
1101
  const { runUpdate } = require('../lib/core/update');
1070
1102
  await runUpdate(currentVersion);
@@ -604,6 +604,16 @@ function lintYidaSource(sourceCode, filePath) {
604
604
  pushIssue(warnings, lineNumber, 'native-select-ui', t('publish.lint_native_select_ui'), disableMap);
605
605
  }
606
606
 
607
+ const iframeSelfNavigationMatch = line.match(/<a\b(?=[^>]*(?:aliwork\.com|yidaapps\.com|\/preview\/|\/workbench))(?!(?=[^>]*\btarget=(['"]?)_top\1))(?!(?=[^>]*\btarget=(['"]?)_blank\2))[^>]*>/i);
608
+ if (iframeSelfNavigationMatch && !isInCommentOrString(line, iframeSelfNavigationMatch.index)) {
609
+ pushIssue(warnings, lineNumber, 'iframe-self-navigation', t('publish.lint_iframe_self_navigation'), disableMap);
610
+ }
611
+
612
+ const topLocationMatch = line.match(/window\.location\.href\s*=\s*[^;\n]*(?:aliwork\.com|yidaapps\.com|\/preview\/|\/workbench)/i);
613
+ if (topLocationMatch && !isInCommentOrString(line, topLocationMatch.index) && !line.includes('window.top.location')) {
614
+ pushIssue(warnings, lineNumber, 'iframe-self-navigation', t('publish.lint_iframe_self_navigation'), disableMap);
615
+ }
616
+
607
617
  const pageSizeMatch = line.match(/\bpageSize\s*:\s*(\d+)/);
608
618
  if (pageSizeMatch && Number(pageSizeMatch[1]) > 100 && !isInCommentOrString(line, pageSizeMatch.index)) {
609
619
  pushIssue(errors, lineNumber, 'page-size-limit', t('publish.lint_page_size_limit', pageSizeMatch[1]), disableMap);
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * update-app.js - 更新宜搭应用信息
3
3
  *
4
- * 用法:openyida update-app <appType> --name "新名称" [--desc "描述"] [--icon "图标"]
4
+ * 用法:openyida update-app <appType> --name "新名称" [--desc "描述"] [--icon "图标"] [--layout slide|ver]
5
5
  */
6
6
 
7
7
  'use strict';
@@ -29,6 +29,9 @@ function parseArgs(args) {
29
29
  desc: null,
30
30
  icon: null,
31
31
  iconColor: null,
32
+ colour: null,
33
+ navTheme: null,
34
+ layoutDirection: null,
32
35
  };
33
36
 
34
37
  // 第一个参数是 appType
@@ -69,6 +72,28 @@ function parseArgs(args) {
69
72
  i++;
70
73
  }
71
74
  break;
75
+ case '--theme':
76
+ case '--colour':
77
+ if (nextArg) {
78
+ result.colour = nextArg;
79
+ i++;
80
+ }
81
+ break;
82
+ case '--nav-theme':
83
+ case '--navTheme':
84
+ if (nextArg) {
85
+ result.navTheme = nextArg;
86
+ i++;
87
+ }
88
+ break;
89
+ case '--layout':
90
+ case '--layout-direction':
91
+ case '--layoutDirection':
92
+ if (nextArg) {
93
+ result.layoutDirection = nextArg;
94
+ i++;
95
+ }
96
+ break;
72
97
  }
73
98
  }
74
99
 
@@ -88,7 +113,7 @@ async function run(args) {
88
113
  const params = parseArgs(args);
89
114
 
90
115
  // 验证必填参数
91
- const { c, banner, step, label, info, success: chalkSuccess, result: chalkResult, error: chalkError } = require('../core/chalk');
116
+ const { c, banner, step, label, info, warn, success: chalkSuccess, result: chalkResult, error: chalkError } = require('../core/chalk');
92
117
 
93
118
  if (!params.appType) {
94
119
  chalkError(t('update_app.missing_app_type'), { exit: false });
@@ -96,7 +121,7 @@ async function run(args) {
96
121
  process.exit(1);
97
122
  }
98
123
 
99
- if (!params.name && !params.desc && !params.icon) {
124
+ if (!params.name && !params.desc && !params.icon && !params.colour && !params.navTheme && !params.layoutDirection) {
100
125
  chalkError(t('update_app.missing_update_field'), { exit: false });
101
126
  printUsage();
102
127
  process.exit(1);
@@ -107,6 +132,9 @@ async function run(args) {
107
132
  if (params.name) {label('Name', params.name);}
108
133
  if (params.desc) {label('Desc', params.desc);}
109
134
  if (params.icon) {label('Icon', `${params.icon} ${c.dim}(${params.iconColor || '#0089FF'})${c.reset}`);}
135
+ if (params.colour || params.navTheme || params.layoutDirection) {
136
+ label('Theme', `${params.colour || '-'} / ${params.navTheme || '-'} / ${params.layoutDirection || '-'}`);
137
+ }
110
138
 
111
139
  // Step 1: 读取登录态
112
140
  step(1, t('common.step_login', 1));
@@ -158,6 +186,13 @@ async function run(args) {
158
186
  postDataObj.iconUrl = iconValue;
159
187
  }
160
188
 
189
+ if (params.colour) {postDataObj.colour = params.colour;}
190
+ if (params.navTheme) {postDataObj.navTheme = params.navTheme;}
191
+ if (params.layoutDirection) {
192
+ postDataObj.layoutDirection = params.layoutDirection;
193
+ warn(t('update_app.layout_notice'));
194
+ }
195
+
161
196
  const postData = querystring.stringify(postDataObj);
162
197
 
163
198
  const response = await requestWithAutoLogin((auth) => {
@@ -182,6 +217,9 @@ async function run(args) {
182
217
  name: params.name || undefined,
183
218
  desc: params.desc || undefined,
184
219
  icon: params.icon || undefined,
220
+ colour: params.colour || undefined,
221
+ navTheme: params.navTheme || undefined,
222
+ layoutDirection: params.layoutDirection || undefined,
185
223
  },
186
224
  }));
187
225
  } else {
package/lib/auth/auth.js CHANGED
@@ -18,8 +18,8 @@
18
18
 
19
19
  const fs = require('fs');
20
20
  const path = require('path');
21
- const { findProjectRoot, loadCookieData, extractInfoFromCookies, resolveBaseUrl } = require('../core/utils');
22
- const { logout, checkLoginOnly } = require('./login');
21
+ const { findProjectRoot, loadCookieData, extractInfoFromCookies, resolveBaseUrl, detectActiveTool, hasDesktopEnvironment } = require('../core/utils');
22
+ const { logout, checkLoginOnly, interactiveLogin } = require('./login');
23
23
  const { t } = require('../core/i18n');
24
24
 
25
25
  const AUTH_CACHE_FILE = '.cache/auth.json';
@@ -135,7 +135,7 @@ function authStatus() {
135
135
  * @returns {Promise<object>|object} 登录结果
136
136
  */
137
137
  async function authLogin(options = {}) {
138
- const { type = 'qrcode', corpId } = options;
138
+ const { type = 'qrcode', corpId, forceTerminalQr = false } = options;
139
139
 
140
140
  const { c, info, success: chalkSuccess, label } = require('../core/chalk');
141
141
  info(t('auth.login_start', type));
@@ -143,14 +143,21 @@ async function authLogin(options = {}) {
143
143
  // 调用现有的登录逻辑
144
144
  let result;
145
145
  const cachedResult = checkLoginOnly({ includeSecrets: true });
146
- if (type === 'browser' || type === 'codex' || type === 'qoder' || type === 'wukong') {
147
- result = cachedResult.status === 'ok'
148
- ? cachedResult
149
- : await require('./codex-login').codexLogin();
146
+ if (cachedResult.status === 'ok') {
147
+ result = cachedResult;
148
+ } else if (type === 'browser') {
149
+ result = interactiveLogin({ playwrightFallback: true });
150
+ } else if (type === 'codex' || type === 'qoder' || type === 'wukong') {
151
+ result = await require('./codex-login').codexLogin({
152
+ tool: type,
153
+ });
154
+ } else if (type === 'qrcode' && !forceTerminalQr && isAgentConversationEnvironment()) {
155
+ result = await loginInAgentConversation({ corpId });
156
+ } else if (type === 'qrcode' && !forceTerminalQr && hasDesktopEnvironment()) {
157
+ result = interactiveLogin({ playwrightFallback: true }) ||
158
+ await require('./qr-login').qrLogin({ corpId });
150
159
  } else {
151
- result = cachedResult.status === 'ok'
152
- ? cachedResult
153
- : await require('./qr-login').qrLogin({ corpId });
160
+ result = await require('./qr-login').qrLogin({ corpId });
154
161
  }
155
162
 
156
163
  if (!result) {
@@ -178,6 +185,31 @@ async function authLogin(options = {}) {
178
185
  return result;
179
186
  }
180
187
 
188
+ function isAgentConversationEnvironment() {
189
+ return !!detectActiveTool() || process.env.OPENYIDA_AGENT_MODE === '1';
190
+ }
191
+
192
+ function shouldUsePlaywrightFallbackInAgentLogin() {
193
+ return hasDesktopEnvironment() || process.env.OPENYIDA_AGENT_PLAYWRIGHT_FALLBACK === '1';
194
+ }
195
+
196
+ async function loginInAgentConversation(options = {}) {
197
+ const activeTool = detectActiveTool();
198
+
199
+ const browserResult = interactiveLogin({
200
+ playwrightFallback: shouldUsePlaywrightFallbackInAgentLogin(),
201
+ });
202
+ if (browserResult) {
203
+ return browserResult;
204
+ }
205
+
206
+ if (activeTool && (activeTool.tool === 'wukong' || activeTool.tool === 'qoderwork')) {
207
+ return require('./codex-login').codexLogin({ tool: activeTool.tool });
208
+ }
209
+
210
+ return require('./qr-login').startCodexQrLogin({ corpId: options.corpId });
211
+ }
212
+
181
213
  // ── 刷新登录态 ────────────────────────────────────────
182
214
 
183
215
  /**
@@ -45,7 +45,7 @@ const COMMAND_GROUPS = [
45
45
  output: 'json',
46
46
  }),
47
47
  command('create-app', ['create-app'], 'create-app "<name>"|--name <name> [options] [--locale zh_CN|en_US|ja_JP] [--open|--no-open]', 'help.cmd_create_app'),
48
- command('update-app', ['update-app'], 'update-app <appType> --name "..."', 'help.cmd_update_app'),
48
+ command('update-app', ['update-app'], 'update-app <appType> [--name "..."] [--layout slide|ver] [--theme deepBlue]', 'help.cmd_update_app'),
49
49
  command('nav-group', ['nav-group'], 'nav-group <list|create|rename|delete|move|hide|show> <appType> ...', 'help.cmd_nav_group', {
50
50
  output: 'json',
51
51
  }),
@@ -175,6 +175,7 @@ const COMMAND_GROUPS = [
175
175
  command('copy', ['copy'], 'copy [--force]', 'help.cmd_copy', { requiresLogin: false }),
176
176
  command('sample', ['sample'], 'sample [--list]', 'help.cmd_sample', { requiresLogin: false }),
177
177
  command('doctor', ['doctor'], 'doctor [--fix]', 'help.cmd_doctor', { requiresLogin: false }),
178
+ command('db-seq-fix', ['db-seq-fix'], 'db-seq-fix [--fix]', 'help.cmd_db_seq_fix'),
178
179
  command('formula.evaluate', ['formula', 'evaluate'], 'formula evaluate <formula|file> [--schema file]', 'help.cmd_formula_evaluate', {
179
180
  requiresLogin: false,
180
181
  output: 'text|json',
@@ -81,6 +81,7 @@ module.exports = {
81
81
  cmd_commands: 'Output machine-readable command manifest',
82
82
  cmd_a2a: 'Start local read-only A2A adapter or print Agent Card',
83
83
  cmd_bridge: 'Start OpenYida local web bridge service',
84
+ cmd_db_seq_fix: 'Detect and repair PostgreSQL sequence drift',
84
85
  cmd_copy: 'نسخ دليل عمل project',
85
86
  cmd_sample: 'إخراج أمثلة/قوالب الكود',
86
87
  cmd_doctor: 'تشخيص البيئة والإصلاح التلقائي',
@@ -462,6 +463,7 @@ module.exports = {
462
463
  lint_foreach_callback_function: '.forEach(function ...) may lose this in callbacks; prefer .forEach((item) => ...)',
463
464
  lint_controlled_input: 'input uses controlled value mode. Yida pages should use defaultValue + onChange to update _customState',
464
465
  lint_native_select_ui: 'Found a native select. User-facing custom page dropdowns should use a Tailwind-styled custom dropdown component for consistent visual quality',
466
+ lint_iframe_self_navigation: 'Yida custom pages run in an iframe. Use target="_top"/target="_blank" or window.top.location for Yida page navigation to avoid nested pages.',
465
467
  lint_page_size_limit: 'pageSize={0} exceeds the Yida API limit of 100; use 100 or less',
466
468
  lint_yida_api_catch: 'this.utils.yida API call has no detected .catch(); add error handling and toast the user',
467
469
  lint_echarts_legacy_map_china: 'ECharts 5 no longer supports echarts/map/js/china.js. Load DataV GeoJSON and call echarts.registerMap("china", geoJson) instead',
@@ -675,6 +677,9 @@ module.exports = {
675
677
  done_meeting: ' التعرف على الاجتماع: {0} حقول بيانات وصفية، {1} أقسام A1، {2} متحدثين',
676
678
  },
677
679
  },
680
+ update_app: {
681
+ layout_notice: 'Note: layoutDirection is consumed by the Yida app shell during creation/refresh. If the top action bar does not recover immediately after a backend switch, reopen the workbench or recreate the app with the target layout.',
682
+ },
678
683
  codex_login: {
679
684
  title: ' openyida login {0} - {1} Login Mode',
680
685
  not_codex: 'Current environment is not detected as Codex / Qoder / Wukong; returning an in-app browser login handoff only.',
@@ -81,6 +81,7 @@ module.exports = {
81
81
  cmd_commands: 'Maschinenlesbares Command Manifest ausgeben',
82
82
  cmd_a2a: 'Lokalen schreibgeschützten A2A-Adapter starten oder Agent Card ausgeben',
83
83
  cmd_bridge: 'Lokalen OpenYida Web-Bridge-Dienst starten',
84
+ cmd_db_seq_fix: 'Detect and repair PostgreSQL sequence drift',
84
85
  cmd_copy: 'project-Arbeitsverzeichnis kopieren',
85
86
  cmd_sample: 'Codebeispiele/Vorlagen ausgeben',
86
87
  cmd_doctor: 'Umgebungsdiagnose & automatische Reparatur',
@@ -462,6 +463,7 @@ module.exports = {
462
463
  lint_foreach_callback_function: '.forEach(function ...) may lose this in callbacks; prefer .forEach((item) => ...)',
463
464
  lint_controlled_input: 'input uses controlled value mode. Yida pages should use defaultValue + onChange to update _customState',
464
465
  lint_native_select_ui: 'Found a native select. User-facing custom page dropdowns should use a Tailwind-styled custom dropdown component for consistent visual quality',
466
+ lint_iframe_self_navigation: 'Yida custom pages run in an iframe. Use target="_top"/target="_blank" or window.top.location for Yida page navigation to avoid nested pages.',
465
467
  lint_page_size_limit: 'pageSize={0} exceeds the Yida API limit of 100; use 100 or less',
466
468
  lint_yida_api_catch: 'this.utils.yida API call has no detected .catch(); add error handling and toast the user',
467
469
  lint_echarts_legacy_map_china: 'ECharts 5 no longer supports echarts/map/js/china.js. Load DataV GeoJSON and call echarts.registerMap("china", geoJson) instead',
@@ -675,6 +677,9 @@ module.exports = {
675
677
  done_meeting: ' Meeting-Erkennung: {0} Metadaten, {1} A1-Abschnitte, {2} Sprecher',
676
678
  },
677
679
  },
680
+ update_app: {
681
+ layout_notice: 'Note: layoutDirection is consumed by the Yida app shell during creation/refresh. If the top action bar does not recover immediately after a backend switch, reopen the workbench or recreate the app with the target layout.',
682
+ },
678
683
  codex_login: {
679
684
  title: ' openyida login {0} - {1} Login Mode',
680
685
  not_codex: 'Current environment is not detected as Codex / Qoder / Wukong; returning an in-app browser login handoff only.',
@@ -87,6 +87,7 @@ module.exports = {
87
87
  cmd_copy: 'Copy project working directory',
88
88
  cmd_sample: 'Output code samples/templates',
89
89
  cmd_doctor: 'Environment diagnostics & auto-fix',
90
+ cmd_db_seq_fix: 'Detect and repair PostgreSQL sequence drift',
90
91
  cmd_formula_evaluate: 'Static-check Yida formula syntax and field refs',
91
92
  cmd_update: 'Check and update to latest version',
92
93
  cmd_export_conversation: 'Export AI conversation records',
@@ -802,11 +803,11 @@ Examples:
802
803
 
803
804
  // ── lib/update-app.js ─────────────────────────────
804
805
  update_app: {
805
- usage: 'Usage: openyida update-app <appType> --name "New Name" [--desc "Description"] [--icon "icon-name"] [--icon-color "color"]',
806
- example: 'Example: openyida update-app APP_XXX --name "New App Name" --desc "New Description"',
807
- options: 'Options:\n --name, -n App name (required or at least one update field)\n --desc, -d App description\n --icon Icon name (e.g. xian-yingyong)\n --icon-color Icon color (default: #0089FF)',
806
+ usage: 'Usage: openyida update-app <appType> [--name "New Name"] [--desc "Description"] [--layout slide|ver] [--theme deepBlue]',
807
+ example: 'Example: openyida update-app APP_XXX --name "New App Name" --layout ver --theme deepBlue',
808
+ options: 'Options:\n --name, -n App name (specify at least one update field)\n --desc, -d App description\n --icon Icon name (e.g. xian-yingyong)\n --icon-color Icon color (default: #0089FF)\n --theme App theme colour\n --nav-theme Navigation theme navTheme\n --layout Layout direction layoutDirection (slide or ver)',
808
809
  missing_app_type: 'Error: missing appType argument',
809
- missing_update_field: 'Error: at least one update field must be specified (--name, --desc, --icon)',
810
+ missing_update_field: 'Error: at least one update field must be specified (--name, --desc, --icon, --theme, --nav-theme, --layout)',
810
811
  title: ' update-app - Yida App Info Update Tool',
811
812
  app_type: '\n App ID: {0}',
812
813
  new_name: ' New name: {0}',
@@ -817,6 +818,7 @@ Examples:
817
818
  app_type_label: ' appType: {0}',
818
819
  name_label: ' App name: {0}',
819
820
  failed: ' ❌ Update failed: {0}',
821
+ layout_notice: 'Note: layoutDirection is consumed by the Yida app shell during creation/refresh. If the top action bar does not recover immediately after a backend switch, reopen the workbench or recreate the app with the target layout.',
820
822
  },
821
823
 
822
824
  // ── lib/update-form-config.js ──────────────────────
@@ -960,6 +962,7 @@ Examples:
960
962
  lint_foreach_callback_function: '.forEach(function ...) may lose this in callbacks; prefer .forEach((item) => ...)',
961
963
  lint_controlled_input: 'input uses controlled value mode. Yida pages should use defaultValue + onChange to update _customState',
962
964
  lint_native_select_ui: 'Found a native select. User-facing custom page dropdowns should use a Tailwind-styled custom dropdown component for consistent visual quality',
965
+ lint_iframe_self_navigation: 'Yida custom pages run in an iframe. Use target="_top"/target="_blank" or window.top.location for Yida page navigation to avoid nested pages.',
963
966
  lint_page_size_limit: 'pageSize={0} exceeds the Yida API limit of 100; use 100 or less',
964
967
  lint_yida_api_catch: 'this.utils.yida API call has no detected .catch(); add error handling and toast the user',
965
968
  lint_echarts_legacy_map_china: 'ECharts 5 no longer supports echarts/map/js/china.js. Load DataV GeoJSON and call echarts.registerMap("china", geoJson) instead',
@@ -81,6 +81,7 @@ module.exports = {
81
81
  cmd_commands: 'Emitir manifiesto de comandos legible por máquina',
82
82
  cmd_a2a: 'Iniciar adaptador A2A local de solo lectura o imprimir Agent Card',
83
83
  cmd_bridge: 'Iniciar servicio local OpenYida web bridge',
84
+ cmd_db_seq_fix: 'Detect and repair PostgreSQL sequence drift',
84
85
  cmd_copy: 'Copiar directorio de trabajo project',
85
86
  cmd_sample: 'Generar ejemplos/plantillas de código',
86
87
  cmd_doctor: 'Diagnóstico de entorno y reparación automática',
@@ -462,6 +463,7 @@ module.exports = {
462
463
  lint_foreach_callback_function: '.forEach(function ...) may lose this in callbacks; prefer .forEach((item) => ...)',
463
464
  lint_controlled_input: 'input uses controlled value mode. Yida pages should use defaultValue + onChange to update _customState',
464
465
  lint_native_select_ui: 'Found a native select. User-facing custom page dropdowns should use a Tailwind-styled custom dropdown component for consistent visual quality',
466
+ lint_iframe_self_navigation: 'Yida custom pages run in an iframe. Use target="_top"/target="_blank" or window.top.location for Yida page navigation to avoid nested pages.',
465
467
  lint_page_size_limit: 'pageSize={0} exceeds the Yida API limit of 100; use 100 or less',
466
468
  lint_yida_api_catch: 'this.utils.yida API call has no detected .catch(); add error handling and toast the user',
467
469
  lint_echarts_legacy_map_china: 'ECharts 5 no longer supports echarts/map/js/china.js. Load DataV GeoJSON and call echarts.registerMap("china", geoJson) instead',
@@ -675,6 +677,9 @@ module.exports = {
675
677
  done_meeting: ' Reconocimiento de reunion: {0} metadatos, {1} secciones A1, {2} ponentes',
676
678
  },
677
679
  },
680
+ update_app: {
681
+ layout_notice: 'Note: layoutDirection is consumed by the Yida app shell during creation/refresh. If the top action bar does not recover immediately after a backend switch, reopen the workbench or recreate the app with the target layout.',
682
+ },
678
683
  codex_login: {
679
684
  title: ' openyida login {0} - {1} Login Mode',
680
685
  not_codex: 'Current environment is not detected as Codex / Qoder / Wukong; returning an in-app browser login handoff only.',
@@ -81,6 +81,7 @@ module.exports = {
81
81
  cmd_commands: 'Afficher le manifeste des commandes lisible par machine',
82
82
  cmd_a2a: 'Démarrer l’adaptateur A2A local en lecture seule ou afficher l’Agent Card',
83
83
  cmd_bridge: 'Démarrer le service web bridge local OpenYida',
84
+ cmd_db_seq_fix: 'Detect and repair PostgreSQL sequence drift',
84
85
  cmd_copy: 'Copier le répertoire de travail project',
85
86
  cmd_sample: 'Exporter des exemples/modèles de code',
86
87
  cmd_doctor: 'Diagnostic d\'environnement et réparation auto',
@@ -462,6 +463,7 @@ module.exports = {
462
463
  lint_foreach_callback_function: '.forEach(function ...) may lose this in callbacks; prefer .forEach((item) => ...)',
463
464
  lint_controlled_input: 'input uses controlled value mode. Yida pages should use defaultValue + onChange to update _customState',
464
465
  lint_native_select_ui: 'Found a native select. User-facing custom page dropdowns should use a Tailwind-styled custom dropdown component for consistent visual quality',
466
+ lint_iframe_self_navigation: 'Yida custom pages run in an iframe. Use target="_top"/target="_blank" or window.top.location for Yida page navigation to avoid nested pages.',
465
467
  lint_page_size_limit: 'pageSize={0} exceeds the Yida API limit of 100; use 100 or less',
466
468
  lint_yida_api_catch: 'this.utils.yida API call has no detected .catch(); add error handling and toast the user',
467
469
  lint_echarts_legacy_map_china: 'ECharts 5 no longer supports echarts/map/js/china.js. Load DataV GeoJSON and call echarts.registerMap("china", geoJson) instead',
@@ -675,6 +677,9 @@ module.exports = {
675
677
  done_meeting: ' Reconnaissance reunion : {0} metadonnees, {1} sections A1, {2} intervenants',
676
678
  },
677
679
  },
680
+ update_app: {
681
+ layout_notice: 'Note: layoutDirection is consumed by the Yida app shell during creation/refresh. If the top action bar does not recover immediately after a backend switch, reopen the workbench or recreate the app with the target layout.',
682
+ },
678
683
  codex_login: {
679
684
  title: ' openyida login {0} - {1} Login Mode',
680
685
  not_codex: 'Current environment is not detected as Codex / Qoder / Wukong; returning an in-app browser login handoff only.',
@@ -81,6 +81,7 @@ module.exports = {
81
81
  cmd_commands: 'Output machine-readable command manifest',
82
82
  cmd_a2a: 'Start local read-only A2A adapter or print Agent Card',
83
83
  cmd_bridge: 'Start OpenYida local web bridge service',
84
+ cmd_db_seq_fix: 'Detect and repair PostgreSQL sequence drift',
84
85
  cmd_copy: 'project कार्य निर्देशिका कॉपी करें',
85
86
  cmd_sample: 'कोड सैंपल/टेम्पलेट आउटपुट करें',
86
87
  cmd_doctor: 'वातावरण निदान और स्वचालित मरम्मत',
@@ -462,6 +463,7 @@ module.exports = {
462
463
  lint_foreach_callback_function: '.forEach(function ...) may lose this in callbacks; prefer .forEach((item) => ...)',
463
464
  lint_controlled_input: 'input uses controlled value mode. Yida pages should use defaultValue + onChange to update _customState',
464
465
  lint_native_select_ui: 'Found a native select. User-facing custom page dropdowns should use a Tailwind-styled custom dropdown component for consistent visual quality',
466
+ lint_iframe_self_navigation: 'Yida custom pages run in an iframe. Use target="_top"/target="_blank" or window.top.location for Yida page navigation to avoid nested pages.',
465
467
  lint_page_size_limit: 'pageSize={0} exceeds the Yida API limit of 100; use 100 or less',
466
468
  lint_yida_api_catch: 'this.utils.yida API call has no detected .catch(); add error handling and toast the user',
467
469
  lint_echarts_legacy_map_china: 'ECharts 5 no longer supports echarts/map/js/china.js. Load DataV GeoJSON and call echarts.registerMap("china", geoJson) instead',
@@ -675,6 +677,9 @@ module.exports = {
675
677
  done_meeting: ' Meeting recognition: {0} metadata, {1} A1 sections, {2} speakers',
676
678
  },
677
679
  },
680
+ update_app: {
681
+ layout_notice: 'Note: layoutDirection is consumed by the Yida app shell during creation/refresh. If the top action bar does not recover immediately after a backend switch, reopen the workbench or recreate the app with the target layout.',
682
+ },
678
683
  codex_login: {
679
684
  title: ' openyida login {0} - {1} Login Mode',
680
685
  not_codex: 'Current environment is not detected as Codex / Qoder / Wukong; returning an in-app browser login handoff only.',
@@ -83,6 +83,7 @@ module.exports = {
83
83
  cmd_commands: '機械可読コマンド manifest を出力',
84
84
  cmd_a2a: 'ローカル読み取り専用 A2A Adapter を起動、または Agent Card を出力',
85
85
  cmd_bridge: 'OpenYida ローカル Web ブリッジサービスを起動',
86
+ cmd_db_seq_fix: 'PostgreSQL Sequence ドリフトを検出・修復',
86
87
  cmd_copy: 'project 作業ディレクトリをコピー',
87
88
  cmd_sample: 'コードサンプル/テンプレートを出力',
88
89
  cmd_doctor: '環境診断と自動修復',
@@ -882,6 +883,7 @@ openyida - Yida CLI ツール
882
883
  lint_foreach_callback_function: '.forEach(function ...) may lose this in callbacks; prefer .forEach((item) => ...)',
883
884
  lint_controlled_input: 'input uses controlled value mode. Yida pages should use defaultValue + onChange to update _customState',
884
885
  lint_native_select_ui: 'Found a native select. User-facing custom page dropdowns should use a Tailwind-styled custom dropdown component for consistent visual quality',
886
+ lint_iframe_self_navigation: 'Yida custom pages run in an iframe. Use target="_top"/target="_blank" or window.top.location for Yida page navigation to avoid nested pages.',
885
887
  lint_page_size_limit: 'pageSize={0} exceeds the Yida API limit of 100; use 100 or less',
886
888
  lint_yida_api_catch: 'this.utils.yida API call has no detected .catch(); add error handling and toast the user',
887
889
  lint_echarts_legacy_map_china: 'ECharts 5 no longer supports echarts/map/js/china.js. Load DataV GeoJSON and call echarts.registerMap("china", geoJson) instead',
@@ -1067,6 +1069,9 @@ openyida - Yida CLI ツール
1067
1069
  done_meeting: ' 会議認識:メタ情報 {0} 項目、A1 要約 {1} セクション、発言者 {2} 名',
1068
1070
  },
1069
1071
  },
1072
+ update_app: {
1073
+ layout_notice: 'Note: layoutDirection is consumed by the Yida app shell during creation/refresh. If the top action bar does not recover immediately after a backend switch, reopen the workbench or recreate the app with the target layout.',
1074
+ },
1070
1075
  codex_login: {
1071
1076
  title: ' openyida login {0} - {1} Login Mode',
1072
1077
  not_codex: 'Current environment is not detected as Codex / Qoder / Wukong; returning an in-app browser login handoff only.',
@@ -81,6 +81,7 @@ module.exports = {
81
81
  cmd_commands: 'Output machine-readable command manifest',
82
82
  cmd_a2a: 'Start local read-only A2A adapter or print Agent Card',
83
83
  cmd_bridge: 'Start OpenYida local web bridge service',
84
+ cmd_db_seq_fix: 'Detect and repair PostgreSQL sequence drift',
84
85
  cmd_copy: 'project 작업 디렉토리 복사',
85
86
  cmd_sample: '코드 샘플/템플릿 출력',
86
87
  cmd_doctor: '환경 진단 및 자동 수정',
@@ -464,6 +465,7 @@ module.exports = {
464
465
  lint_foreach_callback_function: '.forEach(function ...) may lose this in callbacks; prefer .forEach((item) => ...)',
465
466
  lint_controlled_input: 'input uses controlled value mode. Yida pages should use defaultValue + onChange to update _customState',
466
467
  lint_native_select_ui: 'Found a native select. User-facing custom page dropdowns should use a Tailwind-styled custom dropdown component for consistent visual quality',
468
+ lint_iframe_self_navigation: 'Yida custom pages run in an iframe. Use target="_top"/target="_blank" or window.top.location for Yida page navigation to avoid nested pages.',
467
469
  lint_page_size_limit: 'pageSize={0} exceeds the Yida API limit of 100; use 100 or less',
468
470
  lint_yida_api_catch: 'this.utils.yida API call has no detected .catch(); add error handling and toast the user',
469
471
  lint_echarts_legacy_map_china: 'ECharts 5 no longer supports echarts/map/js/china.js. Load DataV GeoJSON and call echarts.registerMap("china", geoJson) instead',
@@ -677,6 +679,9 @@ module.exports = {
677
679
  done_meeting: ' 회의 인식: 메타정보 {0}개, A1 요약 {1}개, 발언자 {2}명',
678
680
  },
679
681
  },
682
+ update_app: {
683
+ layout_notice: 'Note: layoutDirection is consumed by the Yida app shell during creation/refresh. If the top action bar does not recover immediately after a backend switch, reopen the workbench or recreate the app with the target layout.',
684
+ },
680
685
  codex_login: {
681
686
  title: ' openyida login {0} - {1} Login Mode',
682
687
  not_codex: 'Current environment is not detected as Codex / Qoder / Wukong; returning an in-app browser login handoff only.',
@@ -81,6 +81,7 @@ module.exports = {
81
81
  cmd_commands: 'Emitir manifesto de comandos legível por máquina',
82
82
  cmd_a2a: 'Iniciar adaptador A2A local somente leitura ou imprimir Agent Card',
83
83
  cmd_bridge: 'Iniciar serviço local OpenYida web bridge',
84
+ cmd_db_seq_fix: 'Detect and repair PostgreSQL sequence drift',
84
85
  cmd_copy: 'Copiar diretório de trabalho project',
85
86
  cmd_sample: 'Gerar exemplos/modelos de código',
86
87
  cmd_doctor: 'Diagnóstico de ambiente e reparo automático',
@@ -462,6 +463,7 @@ module.exports = {
462
463
  lint_foreach_callback_function: '.forEach(function ...) may lose this in callbacks; prefer .forEach((item) => ...)',
463
464
  lint_controlled_input: 'input uses controlled value mode. Yida pages should use defaultValue + onChange to update _customState',
464
465
  lint_native_select_ui: 'Found a native select. User-facing custom page dropdowns should use a Tailwind-styled custom dropdown component for consistent visual quality',
466
+ lint_iframe_self_navigation: 'Yida custom pages run in an iframe. Use target="_top"/target="_blank" or window.top.location for Yida page navigation to avoid nested pages.',
465
467
  lint_page_size_limit: 'pageSize={0} exceeds the Yida API limit of 100; use 100 or less',
466
468
  lint_yida_api_catch: 'this.utils.yida API call has no detected .catch(); add error handling and toast the user',
467
469
  lint_echarts_legacy_map_china: 'ECharts 5 no longer supports echarts/map/js/china.js. Load DataV GeoJSON and call echarts.registerMap("china", geoJson) instead',
@@ -675,6 +677,9 @@ module.exports = {
675
677
  done_meeting: ' Reconhecimento de reuniao: {0} metadados, {1} secoes A1, {2} palestrantes',
676
678
  },
677
679
  },
680
+ update_app: {
681
+ layout_notice: 'Note: layoutDirection is consumed by the Yida app shell during creation/refresh. If the top action bar does not recover immediately after a backend switch, reopen the workbench or recreate the app with the target layout.',
682
+ },
678
683
  codex_login: {
679
684
  title: ' openyida login {0} - {1} Login Mode',
680
685
  not_codex: 'Current environment is not detected as Codex / Qoder / Wukong; returning an in-app browser login handoff only.',