openyida 2026.7.23 → 2026.7.25-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -13
- package/bin/yida.js +0 -6
- package/lib/app/canvas-compile.js +64 -1
- package/lib/app/create-app.js +1 -12
- package/lib/app/create-form/args.js +0 -1
- package/lib/app/create-form.js +1250 -189
- package/lib/app/create-page.js +7 -20
- package/lib/app/generate-page.js +54 -2
- package/lib/app/import-app.js +2 -12
- package/lib/app/page-compiler.js +15 -0
- package/lib/app/page-linter.js +26 -0
- package/lib/app/publish.js +72 -35
- package/lib/app/services/canvas-page-compiler.js +17 -3
- package/lib/app/services/canvas-page-schema-builder.js +22 -1
- package/lib/app/services/form-compiler.js +108 -5
- package/lib/app/services/form-mode-service.js +1 -1
- package/lib/app/services/native-page-compiler.js +14 -2
- package/lib/{schema → app/services}/page-source-loader.js +1 -1
- package/lib/app/update-app.js +1 -12
- package/lib/auth/token-auth.js +13 -0
- package/lib/auth/token-store.js +94 -2
- package/lib/core/agent-capabilities.js +3 -0
- package/lib/core/command-manifest.js +0 -40
- package/lib/core/locales/en.js +6 -5
- package/lib/core/locales/zh.js +6 -5
- package/lib/core/no-emoji-detector.js +261 -0
- package/lib/core/no-emoji-guard.js +59 -0
- package/lib/{schema → core}/remote-dispatch-boundary.js +1 -1
- package/lib/{schema → core}/server-revision.js +2 -2
- package/lib/core/structured-error.js +27 -0
- package/lib/core/utils.js +11 -4
- package/lib/process/configure-process.js +1 -15
- package/lib/process/create-process.js +1 -24
- package/lib/process/services/process-compiler.js +3 -2
- package/lib/report/append.js +1 -1
- package/lib/report/http.js +1 -1
- package/lib/report/index.js +1 -1
- package/package.json +1 -1
- package/yida-skills/SKILL.md +16 -22
- package/yida-skills/skills/yida-app/SKILL.md +10 -9
- package/yida-skills/skills/yida-canvas-custom-page/SKILL.md +2 -0
- package/yida-skills/skills/yida-canvas-custom-page/references/dependencies-and-cdn.md +1 -1
- package/yida-skills/skills/yida-create-app/SKILL.md +3 -4
- package/yida-skills/skills/yida-create-form-page/SKILL.md +43 -12
- package/yida-skills/skills/yida-create-page/SKILL.md +2 -3
- package/yida-skills/skills/yida-create-process/SKILL.md +2 -3
- package/yida-skills/skills/yida-custom-page/SKILL.md +1 -1
- package/yida-skills/skills/yida-get-schema/SKILL.md +3 -3
- package/yida-skills/skills/yida-integration/SKILL.md +4 -5
- package/yida-skills/skills/yida-page-config/SKILL.md +4 -5
- package/yida-skills/skills/yida-process-rule/SKILL.md +2 -3
- package/yida-skills/skills/yida-publish-page/SKILL.md +2 -3
- package/yida-skills/skills/yida-report/SKILL.md +4 -5
- package/yida-skills/skills/yida-theme/SKILL.md +1 -1
- package/yida-skills/skills-index.json +9 -0
- package/lib/app/services/app-reader.js +0 -85
- package/lib/app/services/app-service.js +0 -235
- package/lib/app/services/form-schema-patcher.js +0 -333
- package/lib/app/services/form-schema-reader.js +0 -59
- package/lib/app/services/form-service.js +0 -379
- package/lib/app/services/page-resource-service.js +0 -185
- package/lib/core/legacy-schema-guard.js +0 -408
- package/lib/process/services/process-reader.js +0 -232
- package/lib/process/services/process-resource-service.js +0 -571
- package/lib/process/services/process-stage-checkpoint.js +0 -246
- package/lib/schema/adapters/app-adapter.js +0 -210
- package/lib/schema/adapters/form-adapter.js +0 -1362
- package/lib/schema/adapters/keys.js +0 -19
- package/lib/schema/adapters/page-adapter.js +0 -566
- package/lib/schema/adapters/process-adapter.js +0 -519
- package/lib/schema/applier.js +0 -1878
- package/lib/schema/apply-store.js +0 -1083
- package/lib/schema/command.js +0 -645
- package/lib/schema/dependency-graph.js +0 -83
- package/lib/schema/errors.js +0 -481
- package/lib/schema/hash.js +0 -9
- package/lib/schema/manifest-limits.js +0 -177
- package/lib/schema/manifest-loader.js +0 -309
- package/lib/schema/manifest-schema-v1.json +0 -193
- package/lib/schema/normalize-manifest.js +0 -281
- package/lib/schema/page-canvas-foundation.js +0 -447
- package/lib/schema/page-data-source-builder.js +0 -561
- package/lib/schema/page-foundation.js +0 -556
- package/lib/schema/planner.js +0 -691
- package/lib/schema/remote-missing.js +0 -21
- package/lib/schema/remote-reader.js +0 -189
- package/lib/schema/resource-registry.js +0 -157
- package/lib/schema/sort.js +0 -28
- package/lib/schema/state-store.js +0 -589
- package/yida-skills/references/schema-as-code-phase1.md +0 -99
package/README.md
CHANGED
|
@@ -241,7 +241,6 @@ Most checks should stay offline, but OpenYida also includes an explicit real-env
|
|
|
241
241
|
OPENYIDA_E2E=1 npm run test:e2e:real
|
|
242
242
|
OPENYIDA_E2E=1 npm run test:e2e:real:full
|
|
243
243
|
OPENYIDA_E2E=1 OPENYIDA_E2E_FULL_STAGES=auth,app,form,process npm run test:e2e:real:full
|
|
244
|
-
npm run test:e2e:real:schema-source
|
|
245
244
|
npm run test:e2e:real:skills
|
|
246
245
|
```
|
|
247
246
|
|
|
@@ -251,8 +250,6 @@ The runner creates a disposable app, form, and custom page with an `OY_E2E_*` pr
|
|
|
251
250
|
|
|
252
251
|
`test:e2e:real:skills` enforces coverage for every directory under `yida-skills/skills/`. Each skill must be classified as real E2E, offline/unit, opt-in, or deprecated with an explicit reason. This prevents new skills from quietly bypassing the real-environment test plan.
|
|
253
252
|
|
|
254
|
-
`test:e2e:real:schema-source` is a local process-level Schema-as-Code E2E for agent/source checkout validation. It reads `yida-skills/` in place, creates a temporary `openyida` launcher that executes the current checkout `bin/yida.js`, and runs CRM app/form/page/process create, managed-update, and noop scenarios through `schema validate -> plan -> apply -> noop` against a mock Yida service, including customer field updates and approval-flow/page changes. Report and integration automation manifests remain compatibility-boundary scenarios and must return unsupported.
|
|
255
|
-
|
|
256
253
|
Each successful full run leaves a human-inspectable result app in the target organization. The final step publishes a dedicated `Full E2E Dashboard` custom page, renames the app to `OY_E2E_*_PASSED` by default, and prints direct links for the app, form, dashboard page, and report; the same links are saved under `resultApp` in the registry JSON.
|
|
257
254
|
|
|
258
255
|
Useful options:
|
|
@@ -358,8 +355,6 @@ openyida append-chart APP_XXX REPORT_XXX .cache/openyida/reports/chart.json
|
|
|
358
355
|
|
|
359
356
|
Run `openyida --help` or `openyida <command> --help` for detailed usage.
|
|
360
357
|
|
|
361
|
-
Schema-as-Code Phase 1 manages app, form, process, and native/default display page resources. Use the single [Phase 1 Manifest guide](yida-skills/references/schema-as-code-phase1.md): create any referenced page source first, run `validate`, run the read-only `plan`, review its current `planId`, then explicitly approve and run `apply`. Error `nextAction`/`ask_human` never grants the first write; `stale_replanned` only returns a replacement plan for another explicit review. State is the only persisted bindings authority; report, automation, and page config/delete/pull remain outside Phase 1.
|
|
362
|
-
|
|
363
358
|
<!-- OPENYIDA_COMMANDS_START -->
|
|
364
359
|
<!-- This section is generated by `npm run docs:commands`. Do not edit command rows by hand. -->
|
|
365
360
|
|
|
@@ -412,14 +407,6 @@ Schema-as-Code Phase 1 manages app, form, process, and native/default display pa
|
|
|
412
407
|
| `openyida update-form-config <appType> ...` | Update form configuration |
|
|
413
408
|
| `openyida get-form-config <appType> <formUuid> [--json]` | Query form configuration |
|
|
414
409
|
|
|
415
|
-
### Schema-as-Code
|
|
416
|
-
|
|
417
|
-
| Command | Description |
|
|
418
|
-
|---------|-------------|
|
|
419
|
-
| `openyida schema validate <manifest> --json --quiet` | Validate Schema-as-Code manifest locally |
|
|
420
|
-
| `openyida schema plan <manifest> --state <path> --json --quiet` | Plan Schema-as-Code changes with read-only remote observation |
|
|
421
|
-
| `openyida schema apply <manifest> --state <path> --plan-id <planId> --json --quiet` | Apply a reviewed Schema-as-Code plan with checkpoints and recovery guards |
|
|
422
|
-
|
|
423
410
|
### Data & Permissions
|
|
424
411
|
|
|
425
412
|
| Command | Description |
|
package/bin/yida.js
CHANGED
|
@@ -729,12 +729,6 @@ async function main() {
|
|
|
729
729
|
break;
|
|
730
730
|
}
|
|
731
731
|
|
|
732
|
-
case 'schema': {
|
|
733
|
-
const { run } = require('../lib/schema/command');
|
|
734
|
-
await run(args);
|
|
735
|
-
break;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
732
|
case 'formula': {
|
|
739
733
|
const subCommand = args[0];
|
|
740
734
|
const subArgs = args.slice(1);
|
|
@@ -25,10 +25,14 @@
|
|
|
25
25
|
* 这些 UMD 依赖由画布运行时依据 importedModules 白名单按需注入。
|
|
26
26
|
*
|
|
27
27
|
* 因此本地编译 = Babel 把 JSX/TS 转成 ES5 → 把 import 改写成 window 别名引用、
|
|
28
|
-
* 把 export default
|
|
28
|
+
* 把 export default 改写成画布入口 `YidaComp` → 正则抽出依赖包名。
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
31
|
const Babel = require('@babel/standalone');
|
|
32
|
+
const {
|
|
33
|
+
assertNoEmojiInArtifactName,
|
|
34
|
+
assertNoEmojiInText,
|
|
35
|
+
} = require('../core/no-emoji-guard');
|
|
32
36
|
|
|
33
37
|
/**
|
|
34
38
|
* 依赖 → window 别名白名单。
|
|
@@ -148,6 +152,15 @@ function esmToWindowPlugin({ types: t }, options = {}) {
|
|
|
148
152
|
);
|
|
149
153
|
}
|
|
150
154
|
|
|
155
|
+
function hasProgramBinding(path, name) {
|
|
156
|
+
const program = path.findParent((parentPath) => parentPath.isProgram());
|
|
157
|
+
return Boolean(program && program.scope.hasBinding(name));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function isExistingYidaCompDefault(path, decl) {
|
|
161
|
+
return t.isIdentifier(decl, { name: 'YidaComp' }) && hasProgramBinding(path, 'YidaComp');
|
|
162
|
+
}
|
|
163
|
+
|
|
151
164
|
return {
|
|
152
165
|
name: 'yida-esm-to-window',
|
|
153
166
|
visitor: {
|
|
@@ -213,6 +226,10 @@ function esmToWindowPlugin({ types: t }, options = {}) {
|
|
|
213
226
|
const decl = path.node.declaration;
|
|
214
227
|
if (t.isFunctionDeclaration(decl) || t.isClassDeclaration(decl)) {
|
|
215
228
|
if (decl.id) {
|
|
229
|
+
if (decl.id.name === 'YidaComp') {
|
|
230
|
+
path.replaceWith(decl);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
216
233
|
// 具名声明:保留声明本体,再补 `var YidaComp = <name>;`
|
|
217
234
|
const idName = decl.id.name;
|
|
218
235
|
path.replaceWithMultiple([
|
|
@@ -231,6 +248,10 @@ function esmToWindowPlugin({ types: t }, options = {}) {
|
|
|
231
248
|
);
|
|
232
249
|
return;
|
|
233
250
|
}
|
|
251
|
+
if (isExistingYidaCompDefault(path, decl)) {
|
|
252
|
+
path.remove();
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
234
255
|
// export default <表达式>
|
|
235
256
|
path.replaceWith(
|
|
236
257
|
t.variableDeclaration('var', [t.variableDeclarator(t.identifier('YidaComp'), decl)])
|
|
@@ -254,12 +275,48 @@ function esmToWindowPlugin({ types: t }, options = {}) {
|
|
|
254
275
|
};
|
|
255
276
|
}
|
|
256
277
|
|
|
278
|
+
function buildCanvasRuntimeWrapper(runtimeCode) {
|
|
279
|
+
return (
|
|
280
|
+
'return function(iframeWindow, parentWindow){ const window = iframeWindow; '
|
|
281
|
+
+ runtimeCode
|
|
282
|
+
+ ' return YidaComp; }'
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function assertCanvasRuntimeParseable(runtimeCode, options = {}) {
|
|
287
|
+
try {
|
|
288
|
+
// 只编译 wrapper,不执行 factory 或用户组件,避免触发源码里的运行期副作用。
|
|
289
|
+
// eslint-disable-next-line no-new-func
|
|
290
|
+
new Function(buildCanvasRuntimeWrapper(runtimeCode));
|
|
291
|
+
} catch (error) {
|
|
292
|
+
const detail = error && error.message ? error.message : String(error);
|
|
293
|
+
const sourceLabel = options.sourcePath ? ` (${options.sourcePath})` : '';
|
|
294
|
+
const compileError = new Error(
|
|
295
|
+
`Code Canvas runtimeCode 无法通过画布运行时装配校验${sourceLabel}: ${detail}`
|
|
296
|
+
+ '。请检查默认导出、YidaComp 入口或 window 等运行时保留变量是否重复声明。'
|
|
297
|
+
);
|
|
298
|
+
compileError.code = 'OPENYIDA_CANVAS_RUNTIME_PARSE_FAILED';
|
|
299
|
+
compileError.cause = error;
|
|
300
|
+
throw compileError;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
257
304
|
/**
|
|
258
305
|
* 本地编译 Code Canvas 源码。
|
|
259
306
|
* @param {string} source 原始 React/JSX/TSX 源码
|
|
260
307
|
* @returns {{ runtimeCode: string, importedModules: string }}
|
|
261
308
|
*/
|
|
262
309
|
function compileCanvasLocal(source, options = {}) {
|
|
310
|
+
if (options.sourcePath) {
|
|
311
|
+
assertNoEmojiInArtifactName(options.sourcePath, {
|
|
312
|
+
code: 'OPENYIDA_PAGE_FILENAME_EMOJI_FORBIDDEN',
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
assertNoEmojiInText(source, {
|
|
316
|
+
artifact: options.sourcePath || 'Code Canvas source',
|
|
317
|
+
code: 'OPENYIDA_CANVAS_SOURCE_EMOJI_FORBIDDEN',
|
|
318
|
+
});
|
|
319
|
+
|
|
263
320
|
const importedModules = extractImportedModules(source);
|
|
264
321
|
|
|
265
322
|
// 第一步:剥类型 + 转 JSX(classic runtime,产出 React.createElement,
|
|
@@ -304,6 +361,11 @@ function compileCanvasLocal(source, options = {}) {
|
|
|
304
361
|
});
|
|
305
362
|
|
|
306
363
|
const runtimeCode = stage2.code || '';
|
|
364
|
+
assertNoEmojiInText(runtimeCode, {
|
|
365
|
+
artifact: options.sourcePath ? options.sourcePath + ' runtime' : 'Code Canvas runtime',
|
|
366
|
+
code: 'OPENYIDA_CANVAS_SOURCE_EMOJI_FORBIDDEN',
|
|
367
|
+
});
|
|
368
|
+
assertCanvasRuntimeParseable(runtimeCode, options);
|
|
307
369
|
return {
|
|
308
370
|
runtimeCode,
|
|
309
371
|
importedModules: JSON.stringify(importedModules),
|
|
@@ -338,5 +400,6 @@ module.exports = {
|
|
|
338
400
|
extractImportedModules,
|
|
339
401
|
resolveWindowAlias,
|
|
340
402
|
shouldAllowUnsupportedBareImports,
|
|
403
|
+
assertCanvasRuntimeParseable,
|
|
341
404
|
MODULE_ALIAS_MAP,
|
|
342
405
|
};
|
package/lib/app/create-app.js
CHANGED
|
@@ -18,10 +18,6 @@ const { t } = require('../core/i18n');
|
|
|
18
18
|
const { buildYidaI18n, normalizeYidaLocale, resolveContentLocale } = require('../core/yida-i18n');
|
|
19
19
|
const { parseOpenOption, withBrowserHandoff } = require('../core/browser-handoff');
|
|
20
20
|
const { throwCommandError } = require('../core/command-errors');
|
|
21
|
-
const {
|
|
22
|
-
assertLegacyDirectWriteAllowed,
|
|
23
|
-
extractLegacyGuardArgs,
|
|
24
|
-
} = require('../core/legacy-schema-guard');
|
|
25
21
|
const { assertPresetThemeKey } = require('./theme-presets');
|
|
26
22
|
|
|
27
23
|
const DEFAULT_APP_OPTIONS = {
|
|
@@ -285,8 +281,7 @@ function buildCreateAppPayload(params, auth, contentLocale, openExclusive, openP
|
|
|
285
281
|
|
|
286
282
|
async function run(args) {
|
|
287
283
|
const openOption = parseOpenOption(args);
|
|
288
|
-
|
|
289
|
-
args = guardSplit.args;
|
|
284
|
+
args = openOption.args;
|
|
290
285
|
|
|
291
286
|
if (hasHelpFlag(args)) {
|
|
292
287
|
printUsage();
|
|
@@ -306,12 +301,6 @@ async function run(args) {
|
|
|
306
301
|
chalkError(t('create_app.usage'), { hint: t('create_app.example') });
|
|
307
302
|
}
|
|
308
303
|
|
|
309
|
-
assertLegacyDirectWriteAllowed({
|
|
310
|
-
command: 'create-app',
|
|
311
|
-
resourceType: 'app',
|
|
312
|
-
action: 'create',
|
|
313
|
-
}, { guardOptions: guardSplit.guardOptions });
|
|
314
|
-
|
|
315
304
|
const { appName, description, icon, iconColor, colour, navTheme, layoutDirection } = params;
|
|
316
305
|
|
|
317
306
|
const { c, banner, step, label, success: chalkSuccess, result: chalkResult } = require('../core/chalk');
|