openyida 2026.7.18 → 2026.7.21

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 (200) hide show
  1. package/README.md +37 -2
  2. package/bin/yida.js +113 -18
  3. package/docs/capabilities.md +202 -0
  4. package/lib/agent-center/agent-center.js +2 -3
  5. package/lib/app/app-list.js +3 -4
  6. package/lib/app/build-page.js +13 -6
  7. package/lib/app/check-page.js +16 -6
  8. package/lib/app/compile.js +17 -7
  9. package/lib/app/create-app.js +14 -2
  10. package/lib/app/create-form/api-path.js +25 -0
  11. package/lib/app/create-form/args.js +13 -0
  12. package/lib/app/create-form/commands.js +4 -0
  13. package/lib/app/create-form/definition-reader.js +23 -23
  14. package/lib/app/create-form/field-normalizers.js +26 -7
  15. package/lib/app/create-form/schema-patch.js +4 -1
  16. package/lib/app/create-form.js +155 -68
  17. package/lib/app/create-page.js +47 -10
  18. package/lib/app/generate-page.js +20 -1
  19. package/lib/app/get-form-config.js +2 -1
  20. package/lib/app/get-schema.js +67 -15
  21. package/lib/app/import-app.js +94 -42
  22. package/lib/app/list-forms.js +4 -8
  23. package/lib/app/page-ir.js +140 -0
  24. package/lib/app/publish.js +289 -556
  25. package/lib/app/schema-field-resolution.js +370 -0
  26. package/lib/app/services/app-reader.js +85 -0
  27. package/lib/app/services/app-service.js +235 -0
  28. package/lib/app/services/canvas-page-compiler.js +91 -0
  29. package/lib/app/services/canvas-page-schema-builder.js +149 -0
  30. package/lib/app/services/field-bindings.js +68 -0
  31. package/lib/app/services/form-compiler.js +1922 -0
  32. package/lib/app/services/form-mode-service.js +182 -0
  33. package/lib/app/services/form-schema-patcher.js +333 -0
  34. package/lib/app/services/form-schema-reader.js +59 -0
  35. package/lib/app/services/form-service.js +379 -0
  36. package/lib/app/services/form-validation.js +562 -0
  37. package/lib/app/services/native-page-compiler.js +92 -0
  38. package/lib/app/services/native-page-schema-builder.js +428 -0
  39. package/lib/app/services/page-resource-service.js +185 -0
  40. package/lib/app/update-app.js +22 -9
  41. package/lib/app/update-form-config.js +4 -2
  42. package/lib/asset/asset-cmd.js +19 -6
  43. package/lib/auth/oauth-loopback.js +376 -15
  44. package/lib/auth/token-auth.js +34 -3
  45. package/lib/auth/token-store.js +22 -4
  46. package/lib/basic-info/basic-info.js +2 -1
  47. package/lib/bridge/bridge.js +43 -18
  48. package/lib/core/agent-capabilities.js +5 -3
  49. package/lib/core/command-errors.js +38 -0
  50. package/lib/core/command-manifest.js +59 -1
  51. package/lib/core/copy.js +12 -0
  52. package/lib/core/doctor.js +15 -4
  53. package/lib/core/env-cmd.js +1 -1
  54. package/lib/core/env.js +7 -6
  55. package/lib/core/i18n.js +66 -8
  56. package/lib/core/legacy-schema-guard.js +408 -0
  57. package/lib/core/locales/en.js +38 -46
  58. package/lib/core/locales/zh.js +30 -46
  59. package/lib/core/sample.js +12 -2
  60. package/lib/core/utils.js +334 -66
  61. package/lib/core/yida-client.js +108 -5
  62. package/lib/corp-efficiency/corp-efficiency.js +2 -2
  63. package/lib/corp-manager/corp-manager.js +3 -3
  64. package/lib/formula/evaluate.js +11 -68
  65. package/lib/formula/field-refs.js +83 -0
  66. package/lib/i18n-management/i18n-management.js +2 -3
  67. package/lib/process/configure-process.js +44 -1992
  68. package/lib/process/create-process.js +54 -87
  69. package/lib/process/preview-process.js +20 -8
  70. package/lib/process/services/process-compiler.js +2056 -0
  71. package/lib/process/services/process-reader.js +232 -0
  72. package/lib/process/services/process-resource-service.js +571 -0
  73. package/lib/process/services/process-service.js +122 -0
  74. package/lib/process/services/process-stage-checkpoint.js +246 -0
  75. package/lib/report/append.js +7 -26
  76. package/lib/report/http.js +31 -5
  77. package/lib/report/index.js +10 -2
  78. package/lib/samples/yida-canvas-custom-page/business-list.canvas.jsx +63 -14
  79. package/lib/samples/yida-canvas-custom-page/dashboard-overview.canvas.jsx +176 -32
  80. package/lib/samples/yida-canvas-custom-page/dashboard-starter.canvas.jsx +5 -2
  81. package/lib/samples/yida-canvas-custom-page/data-management.canvas.jsx +228 -14
  82. package/lib/samples/yida-canvas-custom-page/portal-shell-home.canvas.jsx +2 -2
  83. package/lib/samples/yida-canvas-custom-page/split-pane-detail.canvas.jsx +206 -10
  84. package/lib/samples/yida-custom-page/data-management.oyd.jsx +14 -3
  85. package/lib/samples/yida-custom-page/design-tokens.js +2 -2
  86. package/lib/samples/yida-custom-page/detail-profile.oyd.jsx +1 -1
  87. package/lib/samples/yida-custom-page/portal-shell-home.oyd.jsx +7 -2
  88. package/lib/samples/yida-custom-page/split-pane-detail.oyd.jsx +2 -1
  89. package/lib/schema/adapters/app-adapter.js +210 -0
  90. package/lib/schema/adapters/form-adapter.js +1362 -0
  91. package/lib/schema/adapters/keys.js +19 -0
  92. package/lib/schema/adapters/page-adapter.js +566 -0
  93. package/lib/schema/adapters/process-adapter.js +519 -0
  94. package/lib/schema/applier.js +1878 -0
  95. package/lib/schema/apply-store.js +1083 -0
  96. package/lib/schema/command.js +645 -0
  97. package/lib/schema/dependency-graph.js +83 -0
  98. package/lib/schema/errors.js +481 -0
  99. package/lib/schema/hash.js +9 -0
  100. package/lib/schema/manifest-limits.js +177 -0
  101. package/lib/schema/manifest-loader.js +309 -0
  102. package/lib/schema/manifest-schema-v1.json +193 -0
  103. package/lib/schema/normalize-manifest.js +281 -0
  104. package/lib/schema/page-canvas-foundation.js +447 -0
  105. package/lib/schema/page-data-source-builder.js +561 -0
  106. package/lib/schema/page-foundation.js +556 -0
  107. package/lib/schema/page-source-loader.js +314 -0
  108. package/lib/schema/planner.js +691 -0
  109. package/lib/schema/remote-dispatch-boundary.js +39 -0
  110. package/lib/schema/remote-missing.js +21 -0
  111. package/lib/schema/remote-reader.js +189 -0
  112. package/lib/schema/resource-registry.js +157 -0
  113. package/lib/schema/server-revision.js +71 -0
  114. package/lib/schema/sort.js +28 -0
  115. package/lib/schema/state-store.js +589 -0
  116. package/package.json +10 -8
  117. package/scripts/check-release-risks.js +254 -0
  118. package/scripts/generate-command-docs.js +6 -1
  119. package/scripts/i18n-baseline.json +11 -11
  120. package/scripts/postinstall.js +8 -12
  121. package/scripts/validate-ci.sh +15 -11
  122. package/scripts/validate-i18n.js +30 -9
  123. package/scripts/validate-package-size.js +5 -2
  124. package/scripts/validate-skills.js +4 -0
  125. package/scripts/validate-structure.js +15 -0
  126. package/yida-skills/SKILL.md +117 -30
  127. package/yida-skills/references/schema-as-code-phase1.md +99 -0
  128. package/yida-skills/references/setup-and-env.md +59 -59
  129. package/yida-skills/references/task-retrospective.md +6 -6
  130. package/yida-skills/skills/yida-app/SKILL.md +78 -17
  131. package/yida-skills/skills/yida-canvas-custom-page/SKILL.md +18 -7
  132. package/yida-skills/skills/yida-canvas-custom-page/references/data-bridge-guide.md +3 -3
  133. package/yida-skills/skills/yida-canvas-custom-page/references/page-generation-guide.md +15 -0
  134. package/yida-skills/skills/yida-create-app/SKILL.md +21 -3
  135. package/yida-skills/skills/yida-create-form-page/SKILL.md +19 -1
  136. package/yida-skills/skills/yida-create-page/SKILL.md +16 -3
  137. package/yida-skills/skills/yida-create-process/SKILL.md +100 -4
  138. package/yida-skills/skills/yida-custom-page/SKILL.md +19 -4
  139. package/yida-skills/skills/yida-dashboard/SKILL.md +1 -1
  140. package/yida-skills/skills/yida-dashboard/references/pitfalls.md +1 -1
  141. package/yida-skills/skills/yida-get-schema/SKILL.md +49 -5
  142. package/yida-skills/skills/yida-i18n/SKILL.md +1 -1
  143. package/yida-skills/skills/yida-integration/SKILL.md +7 -1
  144. package/yida-skills/skills/yida-login/SKILL.md +50 -99
  145. package/yida-skills/skills/yida-page-config/SKILL.md +7 -1
  146. package/yida-skills/skills/yida-page-uiux/references/app/blueprint.md +0 -1
  147. package/yida-skills/skills/yida-page-uiux/references/app/navigation-patterns.md +0 -1
  148. package/yida-skills/skills/yida-page-uiux/references/app/role-journey.md +0 -1
  149. package/yida-skills/skills/yida-page-uiux/references/dashboard/app-blueprint.md +0 -1
  150. package/yida-skills/skills/yida-page-uiux/references/dashboard/chart-contracts.md +0 -1
  151. package/yida-skills/skills/yida-page-uiux/references/dashboard/component-contracts.md +0 -1
  152. package/yida-skills/skills/yida-page-uiux/references/dashboard/layout-patterns.md +0 -1
  153. package/yida-skills/skills/yida-page-uiux/references/dashboard/theme-recipes.md +0 -1
  154. package/yida-skills/skills/yida-page-uiux/references/detail/object-narrative.md +0 -1
  155. package/yida-skills/skills/yida-page-uiux/references/detail/section-patterns.md +0 -1
  156. package/yida-skills/skills/yida-page-uiux/references/detail/timeline-and-related.md +0 -1
  157. package/yida-skills/skills/yida-page-uiux/references/landing/assets-workflow.md +0 -1
  158. package/yida-skills/skills/yida-page-uiux/references/landing/industry-playbooks.md +0 -1
  159. package/yida-skills/skills/yida-page-uiux/references/landing/research-levels.md +0 -1
  160. package/yida-skills/skills/yida-page-uiux/references/landing/section-patterns.md +0 -1
  161. package/yida-skills/skills/yida-page-uiux/references/list/drawer-detail.md +0 -1
  162. package/yida-skills/skills/yida-page-uiux/references/list/empty-loading-error.md +0 -1
  163. package/yida-skills/skills/yida-page-uiux/references/list/filter-patterns.md +0 -1
  164. package/yida-skills/skills/yida-page-uiux/references/list/table-patterns.md +0 -1
  165. package/yida-skills/skills/yida-page-uiux/references/scenes/screen.md +0 -1
  166. package/yida-skills/skills/yida-page-uiux/references/workbench/entry-patterns.md +0 -1
  167. package/yida-skills/skills/yida-page-uiux/references/workbench/portal-layouts.md +0 -1
  168. package/yida-skills/skills/yida-page-uiux/references/workbench/task-feed.md +0 -1
  169. package/yida-skills/skills/yida-page-uiux/workflow/output-decision-block.md +1 -1
  170. package/yida-skills/skills/yida-process-rule/SKILL.md +35 -1
  171. package/yida-skills/skills/yida-publish-page/SKILL.md +46 -4
  172. package/yida-skills/skills/yida-report/SKILL.md +9 -235
  173. package/yida-skills/skills/yida-report/references/schema-builder-details.md +239 -0
  174. package/yida-skills/skills/yida-skill-evaluator/SKILL.md +170 -0
  175. package/yida-skills/skills-index.json +238 -54
  176. package/lib/core/locales/ar.js +0 -834
  177. package/lib/core/locales/de.js +0 -834
  178. package/lib/core/locales/es.js +0 -834
  179. package/lib/core/locales/fr.js +0 -834
  180. package/lib/core/locales/hi.js +0 -834
  181. package/lib/core/locales/ja.js +0 -1227
  182. package/lib/core/locales/ko.js +0 -836
  183. package/lib/core/locales/pt.js +0 -834
  184. package/lib/core/locales/vi.js +0 -834
  185. package/lib/core/locales/zh-HK.js +0 -1263
  186. package/project/pages/src/demo-birthday-game.oyd.jsx +0 -832
  187. package/project/pages/src/demo-chip-insight.oyd.jsx +0 -983
  188. package/project/pages/src/demo-compat-smoke.oyd.jsx +0 -58
  189. package/project/pages/src/demo-crm-batch-entry.oyd.jsx +0 -805
  190. package/project/pages/src/demo-crm-dashboard.oyd.jsx +0 -677
  191. package/project/pages/src/demo-future-vision-2026.oyd.jsx +0 -1102
  192. package/project/pages/src/demo-ppt.oyd.jsx +0 -1192
  193. package/project/pages/src/demo-salary-calculator.oyd.jsx +0 -904
  194. package/project/pages/src/openyida-knowledge-doc.oyd.jsx +0 -1714
  195. package/yida-skills/skills/large-file-write/SKILL.md +0 -93
  196. package/yida-skills/skills/large-file-write/references/write-patterns.md +0 -147
  197. package/yida-skills/skills/large-file-write/scripts/write.js +0 -157
  198. package/yida-skills/skills/sls-log-workbench/SKILL.md +0 -134
  199. package/yida-skills/skills/sls-log-workbench/references/workbench-reference.md +0 -130
  200. package/yida-skills/skills/sls-log-workbench/sls-query.js +0 -295
@@ -0,0 +1,408 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { CliError } = require('./cli-error');
6
+
7
+ const TRUE_VALUES = new Set(['1', 'true', 'yes', 'y', 'on', 'schema-managed']);
8
+ const CONTEXT_FLAGS = new Set(['--schema-managed-context', '--resource-context', '--schema-context']);
9
+ const STATE_FLAGS = new Set(['--schema-state', '--schema-state-path']);
10
+
11
+ function extractLegacyGuardArgs(rawArgs = []) {
12
+ const args = [];
13
+ const guardOptions = {
14
+ schemaManaged: false,
15
+ contextInputs: [],
16
+ statePaths: [],
17
+ };
18
+
19
+ for (let index = 0; index < rawArgs.length; index++) {
20
+ const arg = rawArgs[index];
21
+ if (arg === '--schema-managed') {
22
+ guardOptions.schemaManaged = true;
23
+ continue;
24
+ }
25
+ if (typeof arg === 'string' && arg.startsWith('--schema-managed=')) {
26
+ guardOptions.schemaManaged = isTruthy(arg.slice('--schema-managed='.length));
27
+ continue;
28
+ }
29
+ const inlineContext = readInlineValue(arg, CONTEXT_FLAGS);
30
+ if (inlineContext !== null) {
31
+ guardOptions.contextInputs.push(inlineContext);
32
+ continue;
33
+ }
34
+ if (CONTEXT_FLAGS.has(arg)) {
35
+ const value = rawArgs[index + 1];
36
+ if (!value || String(value).startsWith('--')) {
37
+ throw invalidGuardInput(`${arg} requires a JSON value or file path`);
38
+ }
39
+ guardOptions.contextInputs.push(value);
40
+ index += 1;
41
+ continue;
42
+ }
43
+ const inlineState = readInlineValue(arg, STATE_FLAGS);
44
+ if (inlineState !== null) {
45
+ guardOptions.statePaths.push(inlineState);
46
+ continue;
47
+ }
48
+ if (STATE_FLAGS.has(arg)) {
49
+ const value = rawArgs[index + 1];
50
+ if (!value || String(value).startsWith('--')) {
51
+ throw invalidGuardInput(`${arg} requires a state file path`);
52
+ }
53
+ guardOptions.statePaths.push(value);
54
+ index += 1;
55
+ continue;
56
+ }
57
+ args.push(arg);
58
+ }
59
+
60
+ return { args, guardOptions };
61
+ }
62
+
63
+ function assertLegacyDirectWriteAllowed(target = {}, options = {}) {
64
+ const env = options.env || process.env;
65
+ const fsImpl = options.fsImpl || fs;
66
+ const cwd = options.cwd || process.cwd();
67
+ const guardOptions = options.guardOptions || {};
68
+ const contexts = collectContexts(guardOptions, env, fsImpl, cwd);
69
+ const statePaths = collectStatePaths(guardOptions, env);
70
+ const reasons = [];
71
+
72
+ if (guardOptions.schemaManaged || isTruthy(env.OPENYIDA_SCHEMA_MANAGED)) {
73
+ reasons.push({ source: 'explicit_schema_managed_flag' });
74
+ }
75
+
76
+ for (const context of contexts) {
77
+ const managedReason = matchManagedContext(context, target);
78
+ if (managedReason) {
79
+ reasons.push(managedReason);
80
+ }
81
+ }
82
+
83
+ for (const statePath of statePaths) {
84
+ const stateReason = matchManagedStatePath(statePath, target, { fsImpl, cwd });
85
+ if (stateReason) {
86
+ reasons.push(stateReason);
87
+ }
88
+ }
89
+
90
+ if (reasons.length > 0) {
91
+ throw new CliError(
92
+ `Refusing legacy direct ${target.command || 'write'} because the target is schema-managed. Use openyida schema validate -> schema plan -> schema apply.`,
93
+ {
94
+ code: 'LEGACY_SCHEMA_MANAGED_GUARD',
95
+ details: sanitizeGuardDetails(target, reasons),
96
+ }
97
+ );
98
+ }
99
+
100
+ const conflict = findBoundResourceConflict(contexts, target);
101
+ if (conflict) {
102
+ throw new CliError(
103
+ `Refusing legacy direct ${target.command || 'create'} because resource context already contains a bound ${conflict.resourceType}. Reuse the bound resource or set allowCreate=true explicitly.`,
104
+ {
105
+ code: 'LEGACY_RESOURCE_CONTEXT_CONFLICT',
106
+ details: sanitizeGuardDetails(target, [conflict]),
107
+ }
108
+ );
109
+ }
110
+ }
111
+
112
+ function collectContexts(guardOptions, env, fsImpl, cwd) {
113
+ const inputs = [];
114
+ if (env.OPENYIDA_RESOURCE_CONTEXT) {
115
+ inputs.push(env.OPENYIDA_RESOURCE_CONTEXT);
116
+ }
117
+ if (env.OPENYIDA_SCHEMA_CONTEXT) {
118
+ inputs.push(env.OPENYIDA_SCHEMA_CONTEXT);
119
+ }
120
+ if (env.OPENYIDA_SCHEMA_MANAGED_CONTEXT) {
121
+ inputs.push(env.OPENYIDA_SCHEMA_MANAGED_CONTEXT);
122
+ }
123
+ if (Array.isArray(guardOptions.contextInputs)) {
124
+ inputs.push(...guardOptions.contextInputs);
125
+ }
126
+ return inputs.map(input => parseContextInput(input, { fsImpl, cwd }));
127
+ }
128
+
129
+ function collectStatePaths(guardOptions, env) {
130
+ const paths = [];
131
+ if (env.OPENYIDA_SCHEMA_STATE) {
132
+ paths.push(env.OPENYIDA_SCHEMA_STATE);
133
+ }
134
+ if (env.OPENYIDA_SCHEMA_STATE_PATH) {
135
+ paths.push(env.OPENYIDA_SCHEMA_STATE_PATH);
136
+ }
137
+ if (Array.isArray(guardOptions.statePaths)) {
138
+ paths.push(...guardOptions.statePaths);
139
+ }
140
+ return paths.filter(Boolean);
141
+ }
142
+
143
+ function parseContextInput(input, options = {}) {
144
+ if (input && typeof input === 'object' && !Array.isArray(input)) {
145
+ return input;
146
+ }
147
+ const raw = String(input || '').trim();
148
+ if (!raw) {
149
+ throw invalidGuardInput('Resource context is empty');
150
+ }
151
+ const fsImpl = options.fsImpl || fs;
152
+ const cwd = options.cwd || process.cwd();
153
+ if (raw.startsWith('{') || raw.startsWith('[')) {
154
+ return parseJson(raw, 'Resource context is not valid JSON');
155
+ }
156
+ const contextPath = path.resolve(cwd, raw);
157
+ if (!fsImpl.existsSync(contextPath)) {
158
+ throw invalidGuardInput(`Resource context file not found: ${raw}`);
159
+ }
160
+ return parseJson(fsImpl.readFileSync(contextPath, 'utf8'), `Resource context file is not valid JSON: ${raw}`);
161
+ }
162
+
163
+ function matchManagedContext(context, target) {
164
+ if (!context || typeof context !== 'object' || Array.isArray(context)) {
165
+ return null;
166
+ }
167
+ if (isManagedMarker(context)) {
168
+ return { source: 'schema_managed_context', resourceType: target.resourceType };
169
+ }
170
+ const candidates = collectContextResources(context, target.resourceType);
171
+ for (const candidate of candidates) {
172
+ if (isManagedMarker(candidate) && resourceMatchesTarget(candidate, target)) {
173
+ return {
174
+ source: 'schema_managed_context',
175
+ resourceType: target.resourceType,
176
+ key: candidate.key || candidate.name || candidate.source,
177
+ };
178
+ }
179
+ }
180
+ if (target.resourceType === 'process' && target.formUuid) {
181
+ for (const candidate of collectContextResources(context, 'form')) {
182
+ if (isManagedMarker(candidate) && resourceMatchesTarget(candidate, { resourceType: 'form', formUuid: target.formUuid })) {
183
+ return {
184
+ source: 'schema_managed_form_context',
185
+ resourceType: 'form',
186
+ key: candidate.key || candidate.name || candidate.source,
187
+ };
188
+ }
189
+ }
190
+ }
191
+ if (target.resourceType !== 'app' && target.appType) {
192
+ for (const candidate of collectContextResources(context, 'app')) {
193
+ if (isManagedMarker(candidate) && resourceMatchesTarget(candidate, { resourceType: 'app', appType: target.appType })) {
194
+ return {
195
+ source: 'schema_managed_app_context',
196
+ resourceType: 'app',
197
+ key: candidate.key || candidate.name || candidate.source,
198
+ };
199
+ }
200
+ }
201
+ }
202
+ return null;
203
+ }
204
+
205
+ function collectContextResources(context, resourceType) {
206
+ const values = [];
207
+ const direct = context[resourceType];
208
+ if (direct) {
209
+ values.push(direct);
210
+ }
211
+ if (resourceType === 'page' && context.pageContext) {
212
+ values.push(context.pageContext);
213
+ }
214
+ if (resourceType === 'form' && context.formContext) {
215
+ values.push(context.formContext);
216
+ }
217
+ if (Array.isArray(context.resources)) {
218
+ values.push(...context.resources.filter(item => !item.resourceType || item.resourceType === resourceType));
219
+ }
220
+ return values.filter(item => item && typeof item === 'object' && !Array.isArray(item));
221
+ }
222
+
223
+ function matchManagedStatePath(statePath, target, options = {}) {
224
+ const fsImpl = options.fsImpl || fs;
225
+ const cwd = options.cwd || process.cwd();
226
+ const resolved = path.resolve(cwd, statePath);
227
+ if (!fsImpl.existsSync(resolved)) {
228
+ throw invalidGuardInput(`Schema state file not found: ${statePath}`);
229
+ }
230
+ const state = parseJson(fsImpl.readFileSync(resolved, 'utf8'), `Schema state file is not valid JSON: ${statePath}`);
231
+ if (!state || state.kind !== 'openyida_resource_state' || !state.resources || typeof state.resources !== 'object') {
232
+ throw invalidGuardInput(`Schema state file is not an OpenYida resource state: ${statePath}`);
233
+ }
234
+ const directMatch = matchStateResourceCollection(state.resources[target.resourceType], target);
235
+ if (directMatch) {
236
+ return { source: 'schema_state', statePath, resourceType: target.resourceType, key: directMatch.key };
237
+ }
238
+ if (target.resourceType === 'process' && target.formUuid) {
239
+ const formMatch = matchStateResourceCollection(state.resources.form, { resourceType: 'form', formUuid: target.formUuid });
240
+ if (formMatch) {
241
+ return { source: 'schema_state_form', statePath, resourceType: 'form', key: formMatch.key };
242
+ }
243
+ }
244
+ if (target.appType) {
245
+ const appMatch = matchStateResourceCollection(state.resources.app, { resourceType: 'app', appType: target.appType });
246
+ if (appMatch) {
247
+ return { source: 'schema_state_app', statePath, resourceType: 'app', key: appMatch.key };
248
+ }
249
+ }
250
+ return null;
251
+ }
252
+
253
+ function matchStateResourceCollection(collection, target) {
254
+ if (!collection || typeof collection !== 'object') {
255
+ return null;
256
+ }
257
+ for (const [key, entry] of Object.entries(collection)) {
258
+ if (entry && typeof entry === 'object' && resourceMatchesTarget(entry.bindings || {}, target)) {
259
+ return { key };
260
+ }
261
+ }
262
+ return null;
263
+ }
264
+
265
+ function findBoundResourceConflict(contexts, target) {
266
+ if (target.action !== 'create') {
267
+ return null;
268
+ }
269
+ for (const context of contexts) {
270
+ for (const resourceType of getCreateConflictResourceTypes(target)) {
271
+ const candidates = collectContextResources(context, resourceType);
272
+ for (const candidate of candidates) {
273
+ if (candidate && candidate.allowCreate === false && hasBoundIdentity(candidate, resourceType)) {
274
+ return {
275
+ source: 'resource_context',
276
+ resourceType,
277
+ };
278
+ }
279
+ }
280
+ }
281
+ }
282
+ return null;
283
+ }
284
+
285
+ function getCreateConflictResourceTypes(target) {
286
+ if (target.resourceType === 'process') {
287
+ return ['process', 'form'];
288
+ }
289
+ return [target.resourceType];
290
+ }
291
+
292
+ function hasBoundIdentity(resource, resourceType) {
293
+ if (resourceType === 'app') {
294
+ return hasNonEmptyString(resource.appType);
295
+ }
296
+ if (resourceType === 'page' || resourceType === 'form') {
297
+ return hasNonEmptyString(resource.formUuid) || hasNonEmptyString(resource.pageId);
298
+ }
299
+ if (resourceType === 'process') {
300
+ return hasNonEmptyString(resource.processCode) || hasNonEmptyString(resource.formUuid);
301
+ }
302
+ return false;
303
+ }
304
+
305
+ function resourceMatchesTarget(resource, target) {
306
+ if (!resource || typeof resource !== 'object') {
307
+ return false;
308
+ }
309
+
310
+ if (target.resourceType === 'app') {
311
+ return hasNonEmptyString(target.appType) &&
312
+ hasNonEmptyString(resource.appType) &&
313
+ String(resource.appType) === String(target.appType);
314
+ }
315
+
316
+ if (target.resourceType === 'form' || target.resourceType === 'page') {
317
+ const targetFormUuid = target.formUuid || target.pageId;
318
+ const resourceFormUuid = resource.formUuid || resource.pageId;
319
+ return hasNonEmptyString(targetFormUuid) &&
320
+ hasNonEmptyString(resourceFormUuid) &&
321
+ String(resourceFormUuid) === String(targetFormUuid);
322
+ }
323
+
324
+ if (target.resourceType === 'process') {
325
+ if (hasNonEmptyString(target.processCode)) {
326
+ return hasNonEmptyString(resource.processCode) &&
327
+ String(resource.processCode) === String(target.processCode);
328
+ }
329
+ const targetFormUuid = target.formUuid || target.pageId;
330
+ const resourceFormUuid = resource.formUuid || resource.pageId;
331
+ return hasNonEmptyString(targetFormUuid) &&
332
+ hasNonEmptyString(resourceFormUuid) &&
333
+ String(resourceFormUuid) === String(targetFormUuid);
334
+ }
335
+
336
+ return false;
337
+ }
338
+
339
+ function isManagedMarker(value) {
340
+ if (!value || typeof value !== 'object') {
341
+ return false;
342
+ }
343
+ return value.schemaManaged === true ||
344
+ value.managed === true ||
345
+ value.executionPath === 'schema-managed' ||
346
+ value.path === 'schema-managed' ||
347
+ value.managedBy === 'schema' ||
348
+ value.source === 'schema_state' ||
349
+ value.source === 'schema_manifest' ||
350
+ value.kind === 'openyida_schema_managed_context';
351
+ }
352
+
353
+ function readInlineValue(arg, names) {
354
+ if (typeof arg !== 'string') {
355
+ return null;
356
+ }
357
+ for (const name of names) {
358
+ const prefix = `${name}=`;
359
+ if (arg.startsWith(prefix)) {
360
+ return arg.slice(prefix.length);
361
+ }
362
+ }
363
+ return null;
364
+ }
365
+
366
+ function parseJson(raw, message) {
367
+ try {
368
+ return JSON.parse(raw);
369
+ } catch (error) {
370
+ throw invalidGuardInput(message);
371
+ }
372
+ }
373
+
374
+ function invalidGuardInput(message) {
375
+ return new CliError(message, {
376
+ code: 'LEGACY_SCHEMA_GUARD_INVALID_CONTEXT',
377
+ });
378
+ }
379
+
380
+ function isTruthy(value) {
381
+ return TRUE_VALUES.has(String(value || '').trim().toLowerCase());
382
+ }
383
+
384
+ function hasNonEmptyString(value) {
385
+ return typeof value === 'string' && value.trim() !== '';
386
+ }
387
+
388
+ function sanitizeGuardDetails(target, reasons) {
389
+ return {
390
+ command: target.command,
391
+ resourceType: target.resourceType,
392
+ action: target.action,
393
+ appType: target.appType,
394
+ formUuid: target.formUuid,
395
+ processCode: target.processCode,
396
+ reasons,
397
+ };
398
+ }
399
+
400
+ module.exports = {
401
+ assertLegacyDirectWriteAllowed,
402
+ extractLegacyGuardArgs,
403
+ _private: {
404
+ matchManagedContext,
405
+ matchManagedStatePath,
406
+ resourceMatchesTarget,
407
+ },
408
+ };
@@ -43,6 +43,10 @@ module.exports = {
43
43
  cmd_publish: 'Compile and publish custom page',
44
44
  cmd_update_form_config: 'Update form configuration',
45
45
  cmd_get_form_config: 'Query form configuration',
46
+ group_schema: 'Schema-as-Code',
47
+ cmd_schema_validate: 'Validate Schema-as-Code manifest locally',
48
+ cmd_schema_plan: 'Plan Schema-as-Code changes with read-only remote observation',
49
+ cmd_schema_apply: 'Apply a reviewed Schema-as-Code plan with checkpoints and recovery guards',
46
50
  group_data: 'Data & Permissions',
47
51
  cmd_data: 'Unified data management (form/process/task/subform)',
48
52
  cmd_task_center: 'Global task center (todo/processed/cc etc.)',
@@ -96,6 +100,7 @@ module.exports = {
96
100
  cmd_copy: 'Copy project working directory',
97
101
  cmd_sample: 'Output code samples/templates',
98
102
  cmd_doctor: 'Environment diagnostics & auto-fix',
103
+ cmd_eval: 'Multi-dimensional skill evaluation (doc quality, routing accuracy, safety, etc.)',
99
104
  cmd_db_seq_fix: 'Detect and repair PostgreSQL sequence drift',
100
105
  cmd_formula_evaluate: 'Static-check Yida formula syntax and field refs',
101
106
  cmd_update: 'Check and update to latest version',
@@ -126,7 +131,7 @@ Usage:
126
131
  Commands:
127
132
  env Detect AI tool environment and login status
128
133
  copy [--force] Copy project directory to current AI tool environment
129
- login Manage login credentials (cache first, then QR scan)
134
+ login Manage OAuth token credentials
130
135
  logout Logout / switch account
131
136
  create-app "<name>" [desc] [icon] [color] [theme] [nav] [layout] Create an app, output appType
132
137
  create-page <appType> "<pageName>" [--mode dashboard] Create a custom page, output pageId
@@ -284,6 +289,9 @@ Examples:
284
289
  save_permission_usage: 'Usage: openyida save-permission <appType> <formUuid> [--data-permission <json>] [--action-permission <json>]',
285
290
  save_permission_example: "Example: openyida save-permission APP_XXX FORM-XXX --data-permission '{\"role\":\"DEFAULT\",\"dataRange\":\"SELF\"}'",
286
291
  exec_failed: '\n❌ Execution failed: {0}',
292
+ login_usage: 'Usage: openyida login [entryUrl|--public|--alibaba|--intl] [--check-only] [--json] [--client-id <clientId>]',
293
+ login_example: 'Examples:\n openyida login # Open browser via OAuth loopback login\n openyida login --check-only --json # Check token auth status only\n openyida login --intl # Login against the international environment\n OPENYIDA_NO_BROWSER=1 openyida login # Only suppress auto-opening the browser; this is not a CLI login mode\n openyida auth login # Login alias',
294
+ login_unsupported_option: 'Removed legacy login option is no longer supported: {0}. Use token/OAuth login; host-injected mode only checks the injected token.',
287
295
  auth_usage: 'Usage: openyida auth <status|login|refresh|logout>',
288
296
  auth_example: 'Examples:\n openyida auth status # View login status\n openyida auth login # Perform login\n openyida auth refresh # Refresh login session\n openyida auth logout # Logout',
289
297
  org_usage: 'Usage: openyida org <list|switch> [--json] [--corp-id <corpId>]',
@@ -487,8 +495,6 @@ Examples:
487
495
  csrf_ok: ' ✅ csrf_token: {0}...',
488
496
  corp_id_ok: ' ✅ corpId: {0}',
489
497
  no_playwright: '\n❌ This version only supports token login. Run openyida login.',
490
- playwright_install1: ' npm install -g playwright',
491
- playwright_install2: ' npx playwright install chromium',
492
498
  browser_opening: '\n🔐 Opening browser for OAuth login...',
493
499
  login_url_label: ' Login URL: {0}',
494
500
  waiting_login: ' Waiting for login (up to 10 minutes)...',
@@ -723,6 +729,23 @@ Examples:
723
729
  changes_file_not_found: ' ❌ Changes definition file not found: ',
724
730
  changes_must_be_array: 'Changes definition must be a non-empty array',
725
731
  changes_parse_failed: ' ❌ Failed to parse changes definition: ',
732
+ patch_file_not_found: 'Patch file not found: ',
733
+ patch_must_not_be_empty: 'Patch array must not be empty',
734
+ patch_invalid_shape: 'Patch must be an array, {operations: []}, or a single operation object',
735
+ patch_parse_failed: 'Failed to parse patch JSON: ',
736
+ rule_file_not_found: 'Rule file not found: ',
737
+ rule_array_empty: 'Rule array must not be empty',
738
+ rules_array_empty: 'The rules array must not be empty',
739
+ rule_invalid_shape: 'Rules must be an array, {rules: []}, or a single rule object',
740
+ rule_parse_failed: 'Failed to parse rule JSON: ',
741
+ validation_file_not_found: 'Validation rule file not found: ',
742
+ validation_array_empty: 'Validation rule array must not be empty',
743
+ validations_array_empty: 'The validations array must not be empty',
744
+ validation_invalid_shape: 'Validation rules must be an array, {validations: []}, {rules: []}, or a single rule object',
745
+ validation_parse_failed: 'Failed to parse validation rule JSON: ',
746
+ datasource_file_not_found: 'Data source file not found: ',
747
+ datasource_must_be_object: 'Data source config must be an object',
748
+ datasource_parse_failed: 'Failed to parse data source JSON: ',
726
749
  no_components_tree: ' ❌ componentsTree not found in Schema',
727
750
  no_form_container: ' ❌ FormContainer not found in Schema',
728
751
  add_missing_field: ' - missing field.type or field.label, skipped',
@@ -813,6 +836,14 @@ Examples:
813
836
  unnamed_form: 'Unnamed form',
814
837
  },
815
838
 
839
+ import_example2: ' openyida import ./yida-export.json "Quality Traceability System (Production)"',
840
+ exec_failed: '\n❌ Execution failed: {0}',
841
+ auth_usage: 'Usage: openyida auth <status|login|refresh|logout>',
842
+ auth_example: 'Examples:\n openyida auth status # View login status\n openyida auth login # Perform login\n openyida auth refresh # Refresh login session\n openyida auth logout # Logout',
843
+ org_usage: 'Usage: openyida org <list|switch> [--json] [--corp-id <corpId>]',
844
+ org_example: 'Examples:\n openyida org list --json # List accessible organizations\n openyida org switch --corp-id dingXXX # Switch by OAuth re-login to the specified organization',
845
+ title: ' openyida import - Yida App Import Tool',
846
+
816
847
  // ── lib/import-app.js ──────────────────────────────
817
848
  import: {
818
849
  usage: 'Usage: openyida import <file> [name]',
@@ -1051,6 +1082,10 @@ Examples:
1051
1082
  output: 'Yida-compatible source: {0}',
1052
1083
  success: 'Yida-compatible page source built',
1053
1084
  done: 'Page build complete',
1085
+ failed: 'Page build failed',
1086
+ },
1087
+ check_page: {
1088
+ failed: 'Page lint check failed',
1054
1089
  },
1055
1090
  publish: {
1056
1091
  title: ' yida-publish - Yida Page Publishing Tool',
@@ -1170,49 +1205,6 @@ Examples:
1170
1205
  example: 'Example: openyida publish pages/src/xxx.js APP_XXX FORM-XXX --health-check',
1171
1206
  },
1172
1207
 
1173
- // ── token-only disabled QR login ────────────────────────────────
1174
- qr_login: {
1175
- title: '🔐 Yida Terminal QR Code Login',
1176
- step_init: ' Step 1: Initializing session...',
1177
- step_get_qr: ' Step 2: Fetching QR code...',
1178
- scan_hint: ' 📱 Please scan the QR code below with DingTalk:',
1179
- browser_alternative: ' 💡 If this is not a cloud/remote machine, use browser login instead; if QR scan fails, try: {0}',
1180
- qr_url_label: ' QR code URL: {0}',
1181
- waiting_scan: ' ⏳ Waiting for scan (up to 2 minutes)...',
1182
- scanned_confirm: ' ✅ QR code scanned! Please confirm login on your phone...',
1183
- scan_success: ' ✅ Scan confirmed!',
1184
- step_exchange: ' Step 4: Exchanging login credentials...',
1185
- step_get_corps: ' Step 5: Fetching organization list...',
1186
- step_switch_corp: ' Step 7: Switching to selected organization...',
1187
- only_one_corp: ' ✅ Single organization detected: {0}, auto-selected',
1188
- select_corp_prompt: ' 🏢 Multiple organizations found, please select one:',
1189
- select_corp_input: ' Enter number (1-{0}): ',
1190
- select_corp_invalid: ' ❌ Invalid input, please enter a number between 1 and {0}',
1191
- target_corp_not_found: 'Specified corpId was not found in accessible organizations: {0}',
1192
- corp_selected: ' ✅ Selected organization: {0}',
1193
- login_success: '✅ Login successful!',
1194
- qrcode_fallback: ' ⚠️ qrcode package not installed, please visit the URL below manually:',
1195
- qrcode_render_failed: ' ⚠️ QR code render failed ({0}), please visit the URL below:',
1196
- get_qr_failed: 'Failed to parse QR code response: {0}',
1197
- get_qr_api_failed: 'QR code API failed: {0}',
1198
- get_qr_error: 'Failed to get QR code: {0}',
1199
- qr_expired: 'QR code expired, please login again',
1200
- poll_timeout: 'Scan timeout (2 minutes), please login again',
1201
- poll_error: 'Failed to poll scan status: {0}',
1202
- exchange_failed: 'Failed to parse auth code exchange response: {0}',
1203
- exchange_api_failed: 'Auth code exchange API failed: {0}',
1204
- exchange_error: 'Failed to exchange auth code: {0}',
1205
- get_corp_list_failed: 'Failed to parse organization list response: {0}',
1206
- get_corp_list_api_failed: 'Organization list API failed: {0}',
1207
- get_corps_warn: ' ⚠️ Failed to get organization list ({0}), using default organization',
1208
- switch_corp_failed: 'Failed to switch organization: {0}',
1209
- switch_corp_warn: ' ⚠️ Failed to switch organization ({0}), using current organization',
1210
- select_corp_warn: ' ⚠️ Organization selection failed ({0}), using default organization',
1211
- no_corp_available: 'No accessible organizations found',
1212
- no_csrf_in_cookie: 'Login succeeded but no csrf_token found, please try again',
1213
- stdin_closed: 'Input stream closed, cannot select organization',
1214
- },
1215
-
1216
1208
  // ── scripts/postinstall.js ─────────────────────────
1217
1209
  postinstall: {
1218
1210
  welcome_title: ' 🎉 Welcome to OpenYida! ',
@@ -43,6 +43,10 @@ module.exports = {
43
43
  cmd_publish: '编译并发布自定义页面',
44
44
  cmd_update_form_config: '更新表单配置',
45
45
  cmd_get_form_config: '查询表单配置',
46
+ group_schema: 'Schema-as-Code',
47
+ cmd_schema_validate: '本地校验 Schema-as-Code Manifest',
48
+ cmd_schema_plan: '只读观测远端并规划 Schema-as-Code 变更',
49
+ cmd_schema_apply: '使用 checkpoint 和恢复护栏执行已审阅的 Schema-as-Code 计划',
46
50
  group_data: '数据 & 权限',
47
51
  cmd_data: '统一数据管理(表单/流程/任务/子表单)',
48
52
  cmd_task_center: '全局任务中心(待办/已处理/抄送等)',
@@ -96,6 +100,7 @@ module.exports = {
96
100
  cmd_copy: '复制 project 工作目录',
97
101
  cmd_sample: '输出代码示例/模板',
98
102
  cmd_doctor: '环境诊断与自动修复',
103
+ cmd_eval: '技能多维评测(文档质量、路由准确率、安全合规等)',
99
104
  cmd_db_seq_fix: 'PostgreSQL Sequence 漂移检测与修复',
100
105
  cmd_formula_evaluate: '静态检查宜搭公式语法和字段引用',
101
106
  cmd_update: '检查并更新到最新版本',
@@ -126,7 +131,7 @@ openyida - 宜搭命令行工具
126
131
  命令:
127
132
  env 检测当前 AI 工具环境和登录态
128
133
  copy [--force] 复制 project 工作目录到当前 AI 工具环境
129
- login 登录态管理(优先缓存,否则扫码)
134
+ login OAuth token 登录态管理
130
135
  logout 退出登录 / 切换账号
131
136
  create-app "<名称>" [描述] [图标] [颜色] [主题色] [导航风格] [布局] 创建应用,输出 appType
132
137
  create-page <appType> "<页面名>" [--mode dashboard] 创建自定义页面,输出 pageId
@@ -285,6 +290,9 @@ openyida - 宜搭命令行工具
285
290
  save_permission_usage: '用法: openyida save-permission <appType> <formUuid> [--data-permission <json>] [--action-permission <json>]',
286
291
  save_permission_example: "示例: openyida save-permission APP_XXX FORM-XXX --data-permission '{\"role\":\"DEFAULT\",\"dataRange\":\"SELF\"}'",
287
292
  exec_failed: '\n❌ 执行失败: {0}',
293
+ login_usage: '用法: openyida login [entryUrl|--public|--alibaba|--intl] [--check-only] [--json] [--client-id <clientId>]',
294
+ login_example: '示例:\n openyida login # 通过 OAuth loopback 打开浏览器登录\n openyida login --check-only --json # 只检查 token 登录态\n openyida login --intl # 使用国际站环境登录\n OPENYIDA_NO_BROWSER=1 openyida login # 仅抑制自动打开浏览器,不是 CLI 登录模式\n openyida auth login # 登录入口别名',
295
+ login_unsupported_option: '已删除的旧登录参数不再支持: {0}。请使用 token/OAuth 登录;host 注入模式下只检查宿主注入的 token。',
288
296
  first_run_title: ' 🤖 OpenYida - AI 问答模式已开启! ',
289
297
  first_run_welcome: ' {0}欢迎首次使用 OpenYida!{1} 以下是快速上手指南:',
290
298
  first_run_way1_title: ' 📝 方式一:直接描述需求',
@@ -459,8 +467,6 @@ openyida - 宜搭命令行工具
459
467
  csrf_ok: ' ✅ csrf_token: {0}...',
460
468
  corp_id_ok: ' ✅ corpId: {0}',
461
469
  no_playwright: '\n❌ 当前版本仅支持 token 登录,请运行 openyida login。',
462
- playwright_install1: ' npm install -g playwright',
463
- playwright_install2: ' npx playwright install chromium',
464
470
  browser_opening: '\n🔐 正在打开浏览器完成 OAuth 登录...',
465
471
  login_url_label: ' 登录地址: {0}',
466
472
  waiting_login: ' 等待登录完成(最长等待 10 分钟)...',
@@ -695,6 +701,23 @@ openyida - 宜搭命令行工具
695
701
  changes_file_not_found: ' ❌ 修改定义文件不存在: ',
696
702
  changes_must_be_array: '修改定义必须是非空数组',
697
703
  changes_parse_failed: ' ❌ 解析修改定义失败: ',
704
+ patch_file_not_found: '补丁文件不存在: ',
705
+ patch_must_not_be_empty: '补丁数组不能为空',
706
+ patch_invalid_shape: '补丁必须是数组、{operations: []} 或单个操作对象',
707
+ patch_parse_failed: '补丁 JSON 解析失败: ',
708
+ rule_file_not_found: '规则文件不存在: ',
709
+ rule_array_empty: '规则数组不能为空',
710
+ rules_array_empty: 'rules 数组不能为空',
711
+ rule_invalid_shape: '规则必须是数组、{rules: []} 或单个规则对象',
712
+ rule_parse_failed: '规则 JSON 解析失败: ',
713
+ validation_file_not_found: '校验规则文件不存在: ',
714
+ validation_array_empty: '校验规则数组不能为空',
715
+ validations_array_empty: 'validations 数组不能为空',
716
+ validation_invalid_shape: '校验规则必须是数组、{validations: []}、{rules: []} 或单个规则对象',
717
+ validation_parse_failed: '校验规则 JSON 解析失败: ',
718
+ datasource_file_not_found: '数据源文件不存在: ',
719
+ datasource_must_be_object: '数据源配置必须是对象',
720
+ datasource_parse_failed: '数据源 JSON 解析失败: ',
698
721
  no_components_tree: ' ❌ Schema 中未找到 componentsTree',
699
722
  no_form_container: ' ❌ Schema 中未找到 FormContainer',
700
723
  add_missing_field: ' - 缺少 field.type 或 field.label,跳过',
@@ -1053,6 +1076,10 @@ openyida - 宜搭命令行工具
1053
1076
  output: '宜搭兼容源码:{0}',
1054
1077
  success: '宜搭兼容页面源码已构建',
1055
1078
  done: '页面构建完成',
1079
+ failed: '页面构建失败',
1080
+ },
1081
+ check_page: {
1082
+ failed: '页面规范检查失败',
1056
1083
  },
1057
1084
  publish: {
1058
1085
  title: ' yida-publish - 宜搭页面发布工具',
@@ -1172,49 +1199,6 @@ openyida - 宜搭命令行工具
1172
1199
  example: '示例:openyida publish pages/src/xxx.js APP_XXX FORM-XXX --health-check',
1173
1200
  },
1174
1201
 
1175
- // ── token-only disabled QR login ────────────────────────────────
1176
- qr_login: {
1177
- title: '🔐 宜搭终端二维码登录',
1178
- step_init: ' Step 1: 初始化会话...',
1179
- step_get_qr: ' Step 2: 获取二维码...',
1180
- scan_hint: ' 📱 请用钉钉扫描以下二维码登录:',
1181
- browser_alternative: ' 💡 如果当前不是云端/远程电脑,建议使用浏览器登录;扫码失败也请尝试:{0}',
1182
- qr_url_label: ' 二维码链接: {0}',
1183
- waiting_scan: ' ⏳ 等待扫码中(最长 2 分钟)...',
1184
- scanned_confirm: ' ✅ 已扫码!请在手机上确认登录...',
1185
- scan_success: ' ✅ 扫码确认成功!',
1186
- step_exchange: ' Step 4: 获取登录凭证...',
1187
- step_get_corps: ' Step 5: 获取组织列表...',
1188
- step_switch_corp: ' Step 7: 切换到目标组织...',
1189
- only_one_corp: ' ✅ 检测到唯一组织:{0},自动选择',
1190
- select_corp_prompt: ' 🏢 检测到多个可访问组织,请选择:',
1191
- select_corp_input: ' 请输入序号 (1-{0}): ',
1192
- select_corp_invalid: ' ❌ 无效输入,请输入 1 到 {0} 之间的数字',
1193
- target_corp_not_found: '未在可访问组织中找到指定 corpId:{0}',
1194
- corp_selected: ' ✅ 已选择组织:{0}',
1195
- login_success: '✅ 登录成功!',
1196
- qrcode_fallback: ' ⚠️ qrcode 包未安装,请手动访问以下链接完成登录:',
1197
- qrcode_render_failed: ' ⚠️ 二维码渲染失败({0}),请手动访问以下链接:',
1198
- get_qr_failed: '获取二维码响应解析失败: {0}',
1199
- get_qr_api_failed: '获取二维码接口失败: {0}',
1200
- get_qr_error: '获取二维码失败: {0}',
1201
- qr_expired: '二维码已过期,请重新登录',
1202
- poll_timeout: '等待扫码超时(2 分钟),请重新登录',
1203
- poll_error: '轮询扫码状态失败: {0}',
1204
- exchange_failed: '换取登录凭证响应解析失败: {0}',
1205
- exchange_api_failed: '换取登录凭证接口失败: {0}',
1206
- exchange_error: '换取登录凭证失败: {0}',
1207
- get_corp_list_failed: '获取组织列表响应解析失败: {0}',
1208
- get_corp_list_api_failed: '获取组织列表接口失败: {0}',
1209
- get_corps_warn: ' ⚠️ 获取组织列表失败({0}),将使用默认组织',
1210
- switch_corp_failed: '切换组织失败: {0}',
1211
- switch_corp_warn: ' ⚠️ 切换组织失败({0}),将使用当前组织',
1212
- select_corp_warn: ' ⚠️ 组织选择失败({0}),将使用默认组织',
1213
- no_corp_available: '未找到可访问的组织',
1214
- no_csrf_in_cookie: '登录成功但未获取到 csrf_token,请重试',
1215
- stdin_closed: '输入流已关闭,无法选择组织',
1216
- },
1217
-
1218
1202
  // ── scripts/postinstall.js ─────────────────────────
1219
1203
  postinstall: {
1220
1204
  welcome_title: ' 🎉 欢迎使用 OpenYida! ',