openyida 2026.7.29-beta.3 → 2026.8.3
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 +12 -9
- package/bin/yida.js +6 -1
- package/docs/capabilities.md +10 -5
- package/lib/ai/ai.js +2 -2
- package/lib/app/canvas-compile.js +5 -7
- package/lib/app/create-app.js +6 -6
- package/lib/app/create-form/args.js +18 -0
- package/lib/app/create-form.js +37 -16
- package/lib/app/create-page.js +32 -5
- package/lib/app/generate-page.js +123 -2
- package/lib/app/nav-group.js +117 -0
- package/lib/app/page-ir.js +64 -38
- package/lib/app/publish.js +25 -4
- package/lib/app/theme-presets.js +96 -1
- package/lib/bridge/bridge.js +28 -4
- package/lib/core/browser-handoff.js +1 -1
- package/lib/core/command-contract.js +558 -0
- package/lib/core/command-manifest.js +107 -9
- package/lib/core/doctor.js +2 -2
- package/lib/core/env-cmd.js +1 -1
- package/lib/core/env.js +1 -0
- package/lib/core/locales/en.js +20 -16
- package/lib/core/locales/zh.js +22 -18
- package/lib/core/utils.js +17 -1
- package/lib/flash-note/build-flash-note-prompt.js +1 -1
- package/lib/samples/yida-canvas-custom-page/business-list.canvas.jsx +71 -4
- package/lib/samples/yida-canvas-custom-page/dashboard-overview.canvas.jsx +71 -4
- package/lib/samples/yida-canvas-custom-page/data-management.canvas.jsx +81 -14
- package/lib/samples/yida-canvas-custom-page/data-screen.canvas.jsx +151 -68
- package/lib/samples/yida-canvas-custom-page/native-components-smoke.canvas.jsx +22 -9
- package/lib/samples/yida-canvas-custom-page/official-homepage.canvas.jsx +115 -115
- package/lib/samples/yida-canvas-custom-page/portal-native-components.canvas.jsx +18 -4
- package/lib/samples/yida-canvas-custom-page/portal-shell-home.canvas.jsx +31 -13
- package/lib/samples/yida-canvas-custom-page/split-pane-detail.canvas.jsx +71 -4
- package/lib/samples/yida-canvas-custom-page/workbench-home.canvas.jsx +47 -17
- package/lib/samples/yida-custom-page/workbench-home.oyd.jsx +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.js +23 -4
- package/yida-skills/SKILL.md +35 -35
- package/yida-skills/references/development-rules.md +1 -1
- package/yida-skills/references/setup-and-env.md +4 -4
- package/yida-skills/references/task-retrospective.md +3 -3
- package/yida-skills/skills/yida-app/SKILL.md +52 -44
- package/yida-skills/skills/yida-app/references/app-build-contract.md +114 -0
- package/yida-skills/skills/yida-app/references/ui-guidance-by-mode.md +77 -0
- package/yida-skills/skills/yida-app-uiux/SKILL.md +4 -2
- package/yida-skills/skills/yida-canvas-custom-page/SKILL.md +26 -23
- package/yida-skills/skills/yida-canvas-custom-page/references/canvas-authoring-examples.md +3 -3
- package/yida-skills/skills/yida-canvas-custom-page/references/canvas-design-system.md +14 -12
- package/yida-skills/skills/yida-canvas-custom-page/references/component-library-guide.md +1 -1
- package/yida-skills/skills/yida-canvas-custom-page/references/data-bridge-guide.md +27 -9
- package/yida-skills/skills/yida-canvas-custom-page/references/dependencies-and-cdn.md +4 -4
- package/yida-skills/skills/yida-canvas-custom-page/references/employeefield-verification.md +12 -4
- package/yida-skills/skills/yida-canvas-custom-page/references/native-components-bridge.md +14 -12
- package/yida-skills/skills/yida-canvas-custom-page/references/navigation-and-entry-guide.md +100 -0
- package/yida-skills/skills/yida-canvas-custom-page/references/page-generation-guide.md +8 -4
- package/yida-skills/skills/yida-canvas-data-binding/SKILL.md +33 -13
- package/yida-skills/skills/yida-canvas-table-form/SKILL.md +1 -1
- package/yida-skills/skills/yida-chart/references/echarts-design-spec.md +3 -2
- package/yida-skills/skills/yida-create-app/SKILL.md +21 -35
- package/yida-skills/skills/yida-create-form-page/SKILL.md +7 -3
- package/yida-skills/skills/yida-create-form-page/references/form-field-properties.md +13 -4
- package/yida-skills/skills/yida-create-page/SKILL.md +6 -3
- package/yida-skills/skills/yida-custom-page/SKILL.md +3 -3
- package/yida-skills/skills/yida-custom-page/references/coding-guide.md +3 -3
- package/yida-skills/skills/yida-custom-page/references/component-jsx-guide.md +3 -3
- package/yida-skills/skills/yida-custom-page/references/design-system.md +5 -3
- package/yida-skills/skills/yida-dashboard/SKILL.md +5 -5
- package/yida-skills/skills/yida-dashboard/references/interaction-patterns.md +2 -2
- package/yida-skills/skills/yida-dashboard/references/pitfalls.md +3 -3
- package/yida-skills/skills/yida-dashboard/references/structure-and-layout.md +1 -1
- package/yida-skills/skills/yida-dashboard/references/theme-presets.md +11 -8
- package/yida-skills/skills/yida-form-detail/SKILL.md +33 -4
- package/yida-skills/skills/yida-login/SKILL.md +12 -10
- package/yida-skills/skills/yida-nav-group/SKILL.md +5 -1
- package/yida-skills/skills/yida-nav-shell/SKILL.md +4 -3
- package/yida-skills/skills/yida-nav-shell/references/nav-shell-patterns.md +3 -3
- package/yida-skills/skills/yida-page-config/SKILL.md +1 -1
- package/yida-skills/skills/yida-page-uiux/SKILL.md +14 -10
- package/yida-skills/skills/yida-page-uiux/references/app/blueprint.md +1 -1
- package/yida-skills/skills/yida-page-uiux/references/app/navigation-patterns.md +4 -2
- package/yida-skills/skills/yida-page-uiux/references/dashboard/theme-recipes.md +3 -2
- package/yida-skills/skills/yida-page-uiux/references/landing/realistic-brand-homepage.md +2 -2
- package/yida-skills/skills/yida-page-uiux/references/scenes/screen.md +3 -2
- package/yida-skills/skills/yida-page-uiux/references/scenes/workbench.md +3 -0
- package/yida-skills/skills/yida-page-uiux/references/visual-decision-engine.md +6 -6
- package/yida-skills/skills/yida-page-uiux/references/workbench/entry-patterns.md +2 -0
- package/yida-skills/skills/yida-page-uiux/workflow/output-decision-block.md +13 -2
- package/yida-skills/skills/yida-page-uiux/workflow/step-0-nav-shape.md +16 -12
- package/yida-skills/skills/yida-page-uiux/workflow/step-1-page-type.md +2 -2
- package/yida-skills/skills/yida-page-uiux/workflow/step-3-scene-routing.md +2 -2
- package/yida-skills/skills/yida-page-uiux/workflow/step-4-visual-decision.md +16 -4
- package/yida-skills/skills/yida-page-uiux/workflow/step-6-deai-selfcheck.md +1 -1
- package/yida-skills/skills/yida-ppt-slider/references/dark-tech-theme.md +2 -0
- package/yida-skills/skills/yida-publish-page/SKILL.md +3 -2
- package/yida-skills/skills/yida-report/SKILL.md +2 -2
- package/yida-skills/skills/yida-report/references/report-api-guide.md +3 -3
- package/yida-skills/skills/yida-skill-evaluator/SKILL.md +2 -2
- package/yida-skills/skills/yida-table-form/SKILL.md +1 -1
- package/yida-skills/skills/yida-theme/SKILL.md +36 -42
- package/yida-skills/skills/yida-theme/references/theme-token-presets.md +135 -0
- package/yida-skills/skills-index.json +13 -8
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
5
|
# OpenYida
|
|
6
6
|
|
|
@@ -16,7 +16,7 @@ OpenYida connects AI coding agents with Yida's low-code platform, so developers
|
|
|
16
16
|
[](./LICENSE)
|
|
17
17
|
[](https://nodejs.org)
|
|
18
18
|
|
|
19
|
-
**Documentation:** [English](https://
|
|
19
|
+
**Documentation:** [English](https://xmtrf1.aliwork.com/o/openyida/help) · [简体中文](https://xmtrf1.aliwork.com/o/openyida/help) · [繁體中文](https://xmtrf1.aliwork.com/o/openyida/help) · [日本語](https://xmtrf1.aliwork.com/o/openyida/help) · [한국어](https://xmtrf1.aliwork.com/o/openyida/help) · [Français](https://xmtrf1.aliwork.com/o/openyida/help) · [Deutsch](https://xmtrf1.aliwork.com/o/openyida/help) · [Español](https://xmtrf1.aliwork.com/o/openyida/help) · [Português](https://xmtrf1.aliwork.com/o/openyida/help) · [Tiếng Việt](https://xmtrf1.aliwork.com/o/openyida/help) · [हिन्दी](https://xmtrf1.aliwork.com/o/openyida/help) · [العربية](https://xmtrf1.aliwork.com/o/openyida/help)
|
|
20
20
|
|
|
21
21
|
[English README](./README.md) · [简体中文 README](./README_zhCN.md)
|
|
22
22
|
|
|
@@ -96,7 +96,7 @@ Build an IPD workflow for chip production, including approval nodes and dashboar
|
|
|
96
96
|
Generate a public landing page and publish it to my Yida app.
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
The agent can then call OpenYida commands to create the application, generate source files, publish pages, and return the final Yida URLs. In Codex, QoderWork, Qoder, and Wukong environments, successful creation and publish commands also include a browser handoff so the agent can open the resulting Yida page in the in-app browser. Use `--open` to force this handoff or `--no-open` to suppress it.
|
|
99
|
+
The agent can then call OpenYida commands to create the application, generate source files, publish pages, and return the final Yida URLs. In Codex, QwenWork, QoderWork, Qoder, and Wukong environments, successful creation and publish commands also include a browser handoff so the agent can open the resulting Yida page in the in-app browser. Use `--open` to force this handoff or `--no-open` to suppress it.
|
|
100
100
|
|
|
101
101
|
## Wukong Installation
|
|
102
102
|
|
|
@@ -123,6 +123,7 @@ export PATH="$HOME/.real/.bin/node/bin:$PATH"
|
|
|
123
123
|
| [OpenCode](https://opencode.ai) | Full support |
|
|
124
124
|
| [Cursor](https://cursor.com/) | Full support |
|
|
125
125
|
| [Visual Studio Code](https://code.visualstudio.com/) | Full support |
|
|
126
|
+
| QwenWork(千问办公) | Full support |
|
|
126
127
|
| [QoderWork](https://qoder.com) | Full support |
|
|
127
128
|
| [Qoder](https://qoder.com) | Full support |
|
|
128
129
|
| [Wukong](https://dingtalk.com/wukong) | Full support |
|
|
@@ -178,7 +179,7 @@ openyida get-schema APP_XXX FORM_XXX --compact --resolve-fields "Customer Name,S
|
|
|
178
179
|
openyida get-schema APP_XXX --all --output-dir .cache/schemas
|
|
179
180
|
```
|
|
180
181
|
|
|
181
|
-
Form definitions support 19 business field types plus verified
|
|
182
|
+
Form definitions support 19 business field types plus verified presentation/layout components. Prefer `Divider` for section titles and `ColumnContainer` (mapped to `ColumnsLayout` + `Column`) for multi-column layout; use `GroupContainer` / `PageSection` only when an actual grouping container is needed.
|
|
182
183
|
|
|
183
184
|
### Custom Page Development
|
|
184
185
|
|
|
@@ -197,7 +198,7 @@ openyida publish pages/src/home.canvas.jsx APP_XXX FORM_XXX
|
|
|
197
198
|
```
|
|
198
199
|
|
|
199
200
|
`generate-page` turns a structured spec into a Page IR, renders a curated template, writes a `.openyida-page.json` manifest, and optionally compiles the result. Code Canvas is the default output (`.canvas.jsx`); pass `--native` or output `.oyd.jsx` only when the page must use the 普通自定义页面 JSX/Jsx 组件链路. Pass `--scene workbench|dashboard|list|detail|landing|screen` and `--theme-profile <name-or-json>` / `--visual-profile <name-or-json>` to preserve the visual direction decision in both source comments and the manifest. The user-facing default theme profile is `yida-app-theme`, which follows Yida application theme styling, compact business density, and layered 12/8/6/4 radii. `--theme-scope page` only injects theme variables into the generated page root; `--theme-scope app` additionally calls `window.__YIDA__.updateShellConfig({ themeConfig })` so the application shell can adopt the same theme. Landing pages should declare `spec.assets.heroImage` / `productImages`; use `--resolve-assets` to verify public image URLs and `--upload-assets` to mirror local or verified external images to CDN when CDN is configured. Use `--offline-assets` only for draft/offline gating. The manifest makes follow-up AI edits safer because agents can update known blocks and visual constraints instead of rewriting a large JSX file by hand.
|
|
200
|
-
Built-in templates currently include `official-homepage` for brand/law-firm/product official sites, `data-screen` for immersive monitoring screens, `dashboard-overview` for business dashboards, `workbench-home` for task/entry workbenches, `business-list` for list management pages, `detail-profile` for single-object detail pages, `split-pane-detail` for left-list/right-detail processing consoles, `portal-shell-home` for in-page portal shells, `native-components-smoke` for runtime probing existing Yida host components
|
|
201
|
+
Built-in templates currently include `official-homepage` for brand/law-firm/product official sites, `data-screen` for immersive monitoring screens, `dashboard-overview` for business dashboards, `workbench-home` for task/entry workbenches, `business-list` for list management pages, `detail-profile` for single-object detail pages, `split-pane-detail` for left-list/right-detail processing consoles, `portal-shell-home` for in-page portal shells, `native-components-smoke` for runtime probing existing Yida host components through `window.Deep` / `window.DeepYida`, `portal-native-components` for runtime-bridged portal, member, department, and upload components, `product-homepage` for legacy workbench-style pages, and `todo-mvc` for a full interaction smoke page covering events, custom state, list rendering, editing, filtering, and localStorage persistence.
|
|
201
202
|
|
|
202
203
|
For member, department, attachment, and image upload components, choose the page chain first. Code Canvas pages should start with `native-components-smoke` or `portal-native-components` and follow `yida-canvas-custom-page/references/native-components-bridge.md` for feature detection, fallback, and value normalization. 普通自定义页面 JSX/Jsx pages should use `.oyd.jsx`, read `yida-custom-page/references/component-jsx-guide.md`, and read `attachment-upload-guide.md` when upload fields are involved.
|
|
203
204
|
|
|
@@ -376,7 +377,7 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
|
|
|
376
377
|
| `openyida corp-efficiency [overview\|details\|detail\|groups\|notify] [options] [--open\|--no-open]` | Query enterprise efficiency overview and detail reports |
|
|
377
378
|
| `openyida create-app "<name>"\|--name <name> [options] [--locale zh_CN\|en_US\|ja_JP] [--open\|--no-open]` | Create a Yida app |
|
|
378
379
|
| `openyida update-app <appType> [--name "..."] [--layout slide\|ver] [--theme deepBlue]` | Update app info |
|
|
379
|
-
| `openyida nav-group <list\|create\|rename\|delete\|move\|order\|hide\|show> <appType> ...` | Manage app sidebar navigation groups |
|
|
380
|
+
| `openyida nav-group <list\|create\|rename\|delete\|move\|order\|auto-order\|hide\|show> <appType> ...` | Manage app sidebar navigation groups |
|
|
380
381
|
| `openyida app-permission <get\|set\|add\|remove\|search-user> ...` | Manage app primary, data, and developer admins |
|
|
381
382
|
| `openyida i18n <overview\|config\|languages\|list\|upsert\|delete\|translate\|translate-all\|upgrade> <appType> ...` | Manage app multilingual copy and language config |
|
|
382
383
|
| `openyida export <appType> [output]` | Export app (generate migration package) |
|
|
@@ -386,7 +387,7 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
|
|
|
386
387
|
|
|
387
388
|
| Command | Description |
|
|
388
389
|
|---------|-------------|
|
|
389
|
-
| `openyida create-form create <appType>
|
|
390
|
+
| `openyida create-form create <appType> "<formTitle>" <fieldsJsonFile> [--locale zh_CN\|en_US\|ja_JP] [--open\|--no-open]` | Create a form page |
|
|
390
391
|
| `openyida create-form validate-fields <fieldsJsonOrFile> [--json]` | Validate form field JSON locally |
|
|
391
392
|
| `openyida create-form update <appType> ... [--locale zh_CN\|en_US\|ja_JP] [--open\|--no-open]` | Update a form page |
|
|
392
393
|
| `openyida create-form patch <appType> <formUuid> <patchJsonOrFile> [--open\|--no-open]` | Update a form page |
|
|
@@ -399,12 +400,12 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
|
|
|
399
400
|
| `openyida aggregate-table <list\|create-empty\|inspect\|preview\|save\|publish\|status> <appType> ...` | Manage aggregate tables (virtualView) |
|
|
400
401
|
| `openyida get-schema <appType> <formUuid\|--all> [--summary-json\|--field-map-json]` | Get one form Schema or all form Schemas |
|
|
401
402
|
| `openyida er <appType> [--format mermaid\|json] [--output file] [--include-system] [--include-pages]` | Export app entity relationship diagram |
|
|
402
|
-
| `openyida create-page <appType> "<name>" [--mode dashboard] [--locale zh_CN\|en_US\|ja_JP] [--open\|--no-open]` | Create a custom display page |
|
|
403
|
+
| `openyida create-page <appType> "<name>" [--mode dashboard] [--hide-nav] [--locale zh_CN\|en_US\|ja_JP] [--open\|--no-open]` | Create a custom display page |
|
|
403
404
|
| `openyida generate-page <template>` | Generate page from curated template |
|
|
404
405
|
| `openyida build-page <sourceFile> [--output file\|--write]` | Build Yida-compatible page source |
|
|
405
406
|
| `openyida check-page <src> [--compat]` | Check custom page standards |
|
|
406
407
|
| `openyida compile <src>` | Compile custom page locally |
|
|
407
|
-
| `openyida publish <src> <appType> <formUuid> [--health-check] [--force] [--canvas] [--open\|--no-open]` | Compile and publish custom page |
|
|
408
|
+
| `openyida publish <src> <appType> <formUuid> [--health-check] [--force] [--canvas] [--auto-nav-order] [--open\|--no-open]` | Compile and publish custom page |
|
|
408
409
|
| `openyida update-form-config <appType> ...` | Update form configuration |
|
|
409
410
|
| `openyida get-form-config <appType> <formUuid> [--json]` | Query form configuration |
|
|
410
411
|
|
|
@@ -548,6 +549,8 @@ When OpenYida is used inside a supported AI coding environment, these skills hel
|
|
|
548
549
|
|
|
549
550
|
For Wukong manual import, upload the generated `openyida-skills.zip`. The package follows Wukong's custom skill rules: folder name and `frontmatter.name` are both `openyida`, root frontmatter only contains `name` and `description`, and long references live under `references/`.
|
|
550
551
|
|
|
552
|
+
For QwenWork, use the same user-level global skills layout as QoderWork: `~/.qwenworkcn/skills/yida-skills/`. Skip QwenWork setup when `~/.qwenworkcn` is not present.
|
|
553
|
+
|
|
551
554
|
For Codex, `npm install -g openyida` additionally creates a local plugin marketplace under `~/.openyida/codex-plugin` and enables `openyida@openyida` in `~/.codex/config.toml` when Codex is detected. This makes OpenYida show up in Codex's `@` plugin menu as **宜搭** after Codex reloads.
|
|
552
555
|
|
|
553
556
|
## Examples
|
package/bin/yida.js
CHANGED
|
@@ -139,7 +139,7 @@ function printHelp() {
|
|
|
139
139
|
console.log(` ${DIM}${RESET} openyida create-form create APP_XXX "${t('help.quickstart_form_name')}" .cache/openyida/forms/fields.json`);
|
|
140
140
|
console.log(` ${DIM}${RESET} openyida dws contact user search --keyword "张三"`);
|
|
141
141
|
console.log('');
|
|
142
|
-
console.log(` ${DIM}${t('help.docs')} https://openyida
|
|
142
|
+
console.log(` ${DIM}${t('help.docs')} https://xmtrf1.aliwork.com/o/openyida/help · https://github.com/openyida/openyida${RESET}`);
|
|
143
143
|
console.log('');
|
|
144
144
|
}
|
|
145
145
|
|
|
@@ -549,6 +549,11 @@ async function main() {
|
|
|
549
549
|
|
|
550
550
|
switch (command) {
|
|
551
551
|
case 'commands': {
|
|
552
|
+
if (args[0] === 'validate' || args[0] === 'build') {
|
|
553
|
+
const { runCommandsContract } = require('../lib/core/command-contract');
|
|
554
|
+
await runCommandsContract(args);
|
|
555
|
+
break;
|
|
556
|
+
}
|
|
552
557
|
const manifest = buildCommandManifest({ t, version: currentVersion });
|
|
553
558
|
console.log(JSON.stringify(manifest, null, 2));
|
|
554
559
|
break;
|
package/docs/capabilities.md
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
| 功能 | 执行操作 |
|
|
8
8
|
|---|---|
|
|
9
|
-
|
|
|
9
|
+
| 检测当前环境和登录态 | `openyida env` / `openyida env --json` |
|
|
10
|
+
| 管理环境 profile(切换目标环境、维护 endpoint/login-url) | `openyida env <setup\|list\|show\|switch\|add\|remove>` |
|
|
10
11
|
| 登录宜搭 | `openyida login` |
|
|
11
12
|
| 指定入口登录 | `openyida login <target-url>` |
|
|
12
13
|
| 只检查是否已登录 | `openyida login --check-only --json` |
|
|
@@ -16,7 +17,8 @@
|
|
|
16
17
|
| 退出登录 | `openyida logout` |
|
|
17
18
|
| 管理 token 登录态 | `openyida auth <status\|login\|refresh\|logout>` |
|
|
18
19
|
| 查看全部命令清单 | `openyida commands --json` |
|
|
19
|
-
|
|
|
20
|
+
| 默认轻量预检 | `openyida agent-capabilities --summary-json` |
|
|
21
|
+
| 获取完整 Agent 能力诊断 | `openyida agent-capabilities --json` |
|
|
20
22
|
|
|
21
23
|
## 应用与组织管理
|
|
22
24
|
|
|
@@ -156,8 +158,8 @@
|
|
|
156
158
|
|
|
157
159
|
| 功能 | 执行操作 |
|
|
158
160
|
|---|---|
|
|
159
|
-
|
|
|
160
|
-
|
|
|
161
|
+
| AI 文生文 | `openyida ai text [options]` |
|
|
162
|
+
| AI 识图 | `openyida ai image [options]` |
|
|
161
163
|
| 检测素材能力 | `openyida asset status [options]` |
|
|
162
164
|
| 校验图片 URL | `openyida asset verify-url <url> [options]` |
|
|
163
165
|
| 解析并回填页面素材 | `openyida asset resolve [options]` |
|
|
@@ -186,7 +188,9 @@
|
|
|
186
188
|
| 启动 A2A adapter 或输出 Agent Card | `openyida a2a <serve\|agent-card> [options]` |
|
|
187
189
|
| 启动本地 Web bridge | `openyida bridge start [--token <pair-token>] [--port 6736]` |
|
|
188
190
|
| 输出机器可读命令清单 | `openyida commands --json` |
|
|
189
|
-
|
|
|
191
|
+
| 静默 CLI 装饰输出 | `openyida --quiet ...` 或 `YIDA_QUIET=1` |
|
|
192
|
+
| 禁用更新检查提示 | `OPENYIDA_SKIP_UPDATE_CHECK=1` / `NO_UPDATE_NOTIFIER=1` / `CI=1` |
|
|
193
|
+
| 输出完整 Agent 能力诊断 | `openyida agent-capabilities --json` |
|
|
190
194
|
| 运行技能评测 | `openyida eval --mode <mode> [--skill <name>] [--runs N]` |
|
|
191
195
|
|
|
192
196
|
## Agent 能力、评测与安全提示
|
|
@@ -194,6 +198,7 @@
|
|
|
194
198
|
| 功能 | 执行操作 |
|
|
195
199
|
|---|---|
|
|
196
200
|
| 快速判断当前工作区、登录态、组织和命令能力 | `openyida agent-capabilities --summary-json` |
|
|
201
|
+
| 获取完整 Agent 能力诊断(含完整环境、登录状态与命令 Manifest) | `openyida agent-capabilities --json` |
|
|
197
202
|
| 获取完整命令 Manifest、副作用和权限元数据 | `openyida commands --json` |
|
|
198
203
|
| 运行无副作用路由评测 | `openyida eval --mode routing [--skill <name>]` |
|
|
199
204
|
| 运行文档质量 / 安全 / 覆盖率评测 | `openyida eval --mode <doc-quality\|safety\|coverage\|comprehensive>` |
|
package/lib/ai/ai.js
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* (runtimeCode)+ 依赖清单(importedModules),无需调用任何线上编译服务,
|
|
8
8
|
* 因此不依赖登录态、不经过风控 WAF。
|
|
9
9
|
*
|
|
10
|
-
* ──
|
|
11
|
-
* 画布物料在浏览器里这样消费 runtimeCode
|
|
10
|
+
* ── YidaCodeCanvas 运行方式 ──
|
|
11
|
+
* 画布物料在浏览器里这样消费 runtimeCode:
|
|
12
12
|
*
|
|
13
13
|
* const wrapped = `
|
|
14
14
|
* return function(iframeWindow, parentWindow){
|
|
@@ -36,11 +36,9 @@ const {
|
|
|
36
36
|
const { CliError, isCliError } = require('../core/cli-error');
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
* 依赖 → window
|
|
40
|
-
* 逐条镜像自 @ali/vc-deep-yida 的
|
|
41
|
-
* src/components/yida-code-canvas/dependencies.ts → getModuleAliasMap()
|
|
39
|
+
* 依赖 → window 别名白名单,用于把 import 改写到运行时全局对象。
|
|
42
40
|
* 只保留运行时真正用到的 windowAlias(资源 URL 由画布运行时按别名注入,
|
|
43
|
-
* 本地编译不关心 CDN
|
|
41
|
+
* 本地编译不关心 CDN 地址)。默认拒绝未收录依赖;如果运行时资源表已经
|
|
44
42
|
* 先于 CLI 升级,可临时设置 OPENYIDA_CANVAS_ALLOW_UNSUPPORTED_IMPORTS=1
|
|
45
43
|
* 退回旧的 window["pkg"] 映射,避免白名单漂移阻断发布。
|
|
46
44
|
* @type {Record<string, string>}
|
|
@@ -95,7 +93,7 @@ function stripJsComments(code) {
|
|
|
95
93
|
|
|
96
94
|
/**
|
|
97
95
|
* 从源码里正则抽取裸包名(过滤相对/绝对路径),去重排序。
|
|
98
|
-
*
|
|
96
|
+
* 对齐画布运行时的依赖抽取行为。
|
|
99
97
|
* @param {string} code
|
|
100
98
|
* @returns {string[]}
|
|
101
99
|
*/
|
package/lib/app/create-app.js
CHANGED
|
@@ -23,7 +23,7 @@ const { assertPresetThemeKey } = require('./theme-presets');
|
|
|
23
23
|
const DEFAULT_APP_OPTIONS = {
|
|
24
24
|
icon: 'xian-yingyong',
|
|
25
25
|
iconColor: '#0089FF',
|
|
26
|
-
colour: '
|
|
26
|
+
colour: 'podBlue',
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const INDUSTRY_APP_DEFAULTS = [
|
|
@@ -33,7 +33,7 @@ const INDUSTRY_APP_DEFAULTS = [
|
|
|
33
33
|
options: {
|
|
34
34
|
icon: 'xian-falv',
|
|
35
35
|
iconColor: '#5C72FF',
|
|
36
|
-
colour: '
|
|
36
|
+
colour: 'podBlue',
|
|
37
37
|
},
|
|
38
38
|
},
|
|
39
39
|
{
|
|
@@ -42,7 +42,7 @@ const INDUSTRY_APP_DEFAULTS = [
|
|
|
42
42
|
options: {
|
|
43
43
|
icon: 'xian-diqiu',
|
|
44
44
|
iconColor: '#00B853',
|
|
45
|
-
colour: '
|
|
45
|
+
colour: 'podGreen',
|
|
46
46
|
},
|
|
47
47
|
},
|
|
48
48
|
{
|
|
@@ -51,7 +51,7 @@ const INDUSTRY_APP_DEFAULTS = [
|
|
|
51
51
|
options: {
|
|
52
52
|
icon: 'xian-baogao',
|
|
53
53
|
iconColor: '#14A9FF',
|
|
54
|
-
colour: '
|
|
54
|
+
colour: 'podBlue',
|
|
55
55
|
},
|
|
56
56
|
},
|
|
57
57
|
{
|
|
@@ -60,7 +60,7 @@ const INDUSTRY_APP_DEFAULTS = [
|
|
|
60
60
|
options: {
|
|
61
61
|
icon: 'xian-qiye',
|
|
62
62
|
iconColor: '#5C72FF',
|
|
63
|
-
colour: '
|
|
63
|
+
colour: 'podBlue',
|
|
64
64
|
},
|
|
65
65
|
},
|
|
66
66
|
];
|
|
@@ -349,7 +349,7 @@ async function run(args) {
|
|
|
349
349
|
// 输出结果
|
|
350
350
|
if (response && response.success && response.content) {
|
|
351
351
|
const appType = response.content;
|
|
352
|
-
const appUrl = `${authRef.baseUrl}/${appType}/
|
|
352
|
+
const appUrl = `${authRef.baseUrl}/${appType}/workbench`;
|
|
353
353
|
const corpId = authRef.corpId || (authRef.authData && authRef.authData.corp_id) || '';
|
|
354
354
|
|
|
355
355
|
chalkResult(true, t('create_app.success'), [
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const { detectDeprecatedCreateFormInvocation } = require('../../core/command-contract');
|
|
4
|
+
|
|
3
5
|
function parseMaybeJsonValue(value) {
|
|
4
6
|
if (typeof value !== 'string') {
|
|
5
7
|
return value;
|
|
@@ -269,6 +271,22 @@ function createParseArgs(dependencies) {
|
|
|
269
271
|
};
|
|
270
272
|
}
|
|
271
273
|
|
|
274
|
+
const deprecatedInvocation = detectDeprecatedCreateFormInvocation(args, {
|
|
275
|
+
assumeCreateFormRoot: true,
|
|
276
|
+
});
|
|
277
|
+
if (deprecatedInvocation) {
|
|
278
|
+
if (!options.json) {
|
|
279
|
+
hint(deprecatedInvocation.suggestion.display);
|
|
280
|
+
hint(deprecatedInvocation.suggestion.note);
|
|
281
|
+
}
|
|
282
|
+
throwCreateFormError(deprecatedInvocation.message, deprecatedInvocation.code, {
|
|
283
|
+
command_id: deprecatedInvocation.command_id,
|
|
284
|
+
canonical: deprecatedInvocation.canonical,
|
|
285
|
+
suggestion: deprecatedInvocation.suggestion,
|
|
286
|
+
pattern: deprecatedInvocation.pattern,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
272
290
|
if (args.length >= 3 && mode !== 'create' && mode !== 'update' && mode !== 'patch' && mode !== 'rule' && mode !== 'rules' && mode !== 'validation' && mode !== 'validate' && mode !== 'validations' && mode !== 'bind-datasource' && mode !== 'datasource' && mode !== 'data-source') {
|
|
273
291
|
return {
|
|
274
292
|
mode: 'create',
|
package/lib/app/create-form.js
CHANGED
|
@@ -4582,7 +4582,8 @@ function countDataFieldDefinitions(fields) {
|
|
|
4582
4582
|
|
|
4583
4583
|
// ── 应用修改操作(update 模式) ─────────────────────
|
|
4584
4584
|
|
|
4585
|
-
function applyChangesToSchema(schema, changes) {
|
|
4585
|
+
function applyChangesToSchema(schema, changes, options) {
|
|
4586
|
+
const verbose = Boolean(options && options.verbose);
|
|
4586
4587
|
const componentsTree = schema.pages[0].componentsTree;
|
|
4587
4588
|
if (!componentsTree || componentsTree.length === 0) {
|
|
4588
4589
|
error(t('create_form.no_components_tree'));
|
|
@@ -4602,7 +4603,7 @@ function applyChangesToSchema(schema, changes) {
|
|
|
4602
4603
|
|
|
4603
4604
|
if (change.action === 'add') {
|
|
4604
4605
|
if (!change.field || !normalizeFormDefinitionType(change.field) || (!change.field.label && !change.field.title && !isFormPresentationDefinition(change.field))) {
|
|
4605
|
-
warn(actionDesc + t('create_form.add_missing_field'));
|
|
4606
|
+
if (verbose) { warn(actionDesc + t('create_form.add_missing_field')); }
|
|
4606
4607
|
return;
|
|
4607
4608
|
}
|
|
4608
4609
|
|
|
@@ -4616,23 +4617,23 @@ function applyChangesToSchema(schema, changes) {
|
|
|
4616
4617
|
const afterResult = findFieldByLabelDeep(formFields, change.after);
|
|
4617
4618
|
if (afterResult) {
|
|
4618
4619
|
afterResult.fields.splice(afterResult.index + 1, 0, newComponent);
|
|
4619
|
-
success(actionDesc + t('create_form.add_after_ok', change.after, displayName, componentName));
|
|
4620
|
+
if (verbose) { success(actionDesc + t('create_form.add_after_ok', change.after, displayName, componentName)); }
|
|
4620
4621
|
} else {
|
|
4621
4622
|
formFields.push(newComponent);
|
|
4622
|
-
warn(actionDesc + t('create_form.add_after_not_found', change.after, displayName));
|
|
4623
|
+
if (verbose) { warn(actionDesc + t('create_form.add_after_not_found', change.after, displayName)); }
|
|
4623
4624
|
}
|
|
4624
4625
|
} else if (change.before) {
|
|
4625
4626
|
const beforeResult = findFieldByLabelDeep(formFields, change.before);
|
|
4626
4627
|
if (beforeResult) {
|
|
4627
4628
|
beforeResult.fields.splice(beforeResult.index, 0, newComponent);
|
|
4628
|
-
success(actionDesc + t('create_form.add_before_ok', change.before, displayName, componentName));
|
|
4629
|
+
if (verbose) { success(actionDesc + t('create_form.add_before_ok', change.before, displayName, componentName)); }
|
|
4629
4630
|
} else {
|
|
4630
4631
|
formFields.push(newComponent);
|
|
4631
|
-
warn(actionDesc + t('create_form.add_before_not_found', change.before, displayName));
|
|
4632
|
+
if (verbose) { warn(actionDesc + t('create_form.add_before_not_found', change.before, displayName)); }
|
|
4632
4633
|
}
|
|
4633
4634
|
} else {
|
|
4634
4635
|
formFields.push(newComponent);
|
|
4635
|
-
success(actionDesc + t('create_form.add_ok', displayName, componentName));
|
|
4636
|
+
if (verbose) { success(actionDesc + t('create_form.add_ok', displayName, componentName)); }
|
|
4636
4637
|
}
|
|
4637
4638
|
|
|
4638
4639
|
appliedChanges.push({ action: 'add', label: displayName, type: componentName, resolved: buildFieldEvidence(newComponent, []) });
|
|
@@ -4645,7 +4646,7 @@ function applyChangesToSchema(schema, changes) {
|
|
|
4645
4646
|
tableLabel: change.tableLabel,
|
|
4646
4647
|
};
|
|
4647
4648
|
if (!deleteTarget.label && !deleteTarget.fieldId && !deleteTarget.ref) {
|
|
4648
|
-
warn(actionDesc + t('create_form.delete_missing_label'));
|
|
4649
|
+
if (verbose) { warn(actionDesc + t('create_form.delete_missing_label')); }
|
|
4649
4650
|
return;
|
|
4650
4651
|
}
|
|
4651
4652
|
|
|
@@ -4653,7 +4654,7 @@ function applyChangesToSchema(schema, changes) {
|
|
|
4653
4654
|
if (deleteResolution.ok) {
|
|
4654
4655
|
const deleteResult = deleteResolution.match;
|
|
4655
4656
|
deleteResult.fields.splice(deleteResult.index, 1);
|
|
4656
|
-
success(actionDesc + t('create_form.delete_ok', change.label || deleteResolution.resolved.label || change.fieldId));
|
|
4657
|
+
if (verbose) { success(actionDesc + t('create_form.delete_ok', change.label || deleteResolution.resolved.label || change.fieldId)); }
|
|
4657
4658
|
appliedChanges.push({
|
|
4658
4659
|
action: 'delete',
|
|
4659
4660
|
label: change.label || deleteResolution.resolved.label,
|
|
@@ -4662,7 +4663,7 @@ function applyChangesToSchema(schema, changes) {
|
|
|
4662
4663
|
resolved: deleteResolution.resolved,
|
|
4663
4664
|
});
|
|
4664
4665
|
} else {
|
|
4665
|
-
warn(actionDesc + t('create_form.delete_not_found', change.label || change.fieldId || change.field));
|
|
4666
|
+
if (verbose) { warn(actionDesc + t('create_form.delete_not_found', change.label || change.fieldId || change.field)); }
|
|
4666
4667
|
pushResolutionDiagnostic(diagnostics, Object.assign({ action: 'delete' }, deleteResolution.diagnostic));
|
|
4667
4668
|
}
|
|
4668
4669
|
|
|
@@ -4674,11 +4675,11 @@ function applyChangesToSchema(schema, changes) {
|
|
|
4674
4675
|
tableLabel: change.tableLabel,
|
|
4675
4676
|
};
|
|
4676
4677
|
if (!updateTarget.label && !updateTarget.fieldId && !updateTarget.ref) {
|
|
4677
|
-
warn(actionDesc + t('create_form.update_missing_label'));
|
|
4678
|
+
if (verbose) { warn(actionDesc + t('create_form.update_missing_label')); }
|
|
4678
4679
|
return;
|
|
4679
4680
|
}
|
|
4680
4681
|
if (!change.changes || Object.keys(change.changes).length === 0) {
|
|
4681
|
-
warn(actionDesc + t('create_form.update_missing_changes'));
|
|
4682
|
+
if (verbose) { warn(actionDesc + t('create_form.update_missing_changes')); }
|
|
4682
4683
|
return;
|
|
4683
4684
|
}
|
|
4684
4685
|
|
|
@@ -4689,7 +4690,7 @@ function applyChangesToSchema(schema, changes) {
|
|
|
4689
4690
|
applyFieldChanges(updateResult.field, change.changes);
|
|
4690
4691
|
const changedProps = Object.keys(change.changes).join(', ');
|
|
4691
4692
|
const targetLabel = change.label || updateResolution.resolved.label || change.fieldId || change.field;
|
|
4692
|
-
success(actionDesc + t('create_form.update_ok', locationDesc, targetLabel, changedProps));
|
|
4693
|
+
if (verbose) { success(actionDesc + t('create_form.update_ok', locationDesc, targetLabel, changedProps)); }
|
|
4693
4694
|
appliedChanges.push({
|
|
4694
4695
|
action: 'update',
|
|
4695
4696
|
label: change.label || updateResolution.resolved.label,
|
|
@@ -4700,12 +4701,12 @@ function applyChangesToSchema(schema, changes) {
|
|
|
4700
4701
|
updatedProps: summarizeUpdatedProps(updateResult.field, change.changes),
|
|
4701
4702
|
});
|
|
4702
4703
|
} else {
|
|
4703
|
-
warn(actionDesc + t('create_form.update_not_found', locationDesc, change.label || change.fieldId || change.field));
|
|
4704
|
+
if (verbose) { warn(actionDesc + t('create_form.update_not_found', locationDesc, change.label || change.fieldId || change.field)); }
|
|
4704
4705
|
pushResolutionDiagnostic(diagnostics, Object.assign({ action: 'update' }, updateResolution.diagnostic));
|
|
4705
4706
|
}
|
|
4706
4707
|
|
|
4707
4708
|
} else {
|
|
4708
|
-
warn(actionDesc + t('create_form.unknown_action', change.action));
|
|
4709
|
+
if (verbose) { warn(actionDesc + t('create_form.unknown_action', change.action)); }
|
|
4709
4710
|
pushResolutionDiagnostic(diagnostics, {
|
|
4710
4711
|
action: change.action,
|
|
4711
4712
|
code: 'CREATE_FORM_UNKNOWN_ACTION',
|
|
@@ -5204,7 +5205,27 @@ async function mainCreate(parsedArgs, authRef) {
|
|
|
5204
5205
|
}
|
|
5205
5206
|
}
|
|
5206
5207
|
|
|
5208
|
+
async function runWithQuietOutput(fn) {
|
|
5209
|
+
const previousQuiet = process.env.YIDA_QUIET;
|
|
5210
|
+
process.env.YIDA_QUIET = '1';
|
|
5211
|
+
try {
|
|
5212
|
+
return await fn();
|
|
5213
|
+
} finally {
|
|
5214
|
+
if (previousQuiet === undefined) {
|
|
5215
|
+
delete process.env.YIDA_QUIET;
|
|
5216
|
+
} else {
|
|
5217
|
+
process.env.YIDA_QUIET = previousQuiet;
|
|
5218
|
+
}
|
|
5219
|
+
}
|
|
5220
|
+
}
|
|
5221
|
+
|
|
5207
5222
|
async function createFormForLegacyProcess(context, input) {
|
|
5223
|
+
return runWithQuietOutput(function () {
|
|
5224
|
+
return createFormForLegacyProcessQuiet(context, input);
|
|
5225
|
+
});
|
|
5226
|
+
}
|
|
5227
|
+
|
|
5228
|
+
async function createFormForLegacyProcessQuiet(context, input) {
|
|
5208
5229
|
const authRef = context && context.authRef ? context.authRef : context;
|
|
5209
5230
|
const parsedArgs = {
|
|
5210
5231
|
mode: 'create',
|
|
@@ -6110,7 +6131,7 @@ async function mainUpdate(parsedArgs, authRef) {
|
|
|
6110
6131
|
}
|
|
6111
6132
|
|
|
6112
6133
|
step(5, t('create_form.step_apply_changes', 5));
|
|
6113
|
-
const appliedChanges = applyChangesToSchema(schema, changes);
|
|
6134
|
+
const appliedChanges = applyChangesToSchema(schema, changes, { verbose: true });
|
|
6114
6135
|
const fieldDiagnostics = appliedChanges.diagnostics || [];
|
|
6115
6136
|
if (fieldDiagnostics.length > 0) {
|
|
6116
6137
|
const errorOutput = {
|
package/lib/app/create-page.js
CHANGED
|
@@ -22,6 +22,7 @@ function parseArgs(args) {
|
|
|
22
22
|
const filteredArgs = [];
|
|
23
23
|
let mode = 'default';
|
|
24
24
|
let locale = null;
|
|
25
|
+
let hideNav = false;
|
|
25
26
|
|
|
26
27
|
if (openOption.args.includes('--help') || openOption.args.includes('-h')) {
|
|
27
28
|
return {
|
|
@@ -30,6 +31,7 @@ function parseArgs(args) {
|
|
|
30
31
|
pageName: null,
|
|
31
32
|
mode,
|
|
32
33
|
locale,
|
|
34
|
+
hideNav,
|
|
33
35
|
help: true,
|
|
34
36
|
openMode: openOption.mode,
|
|
35
37
|
};
|
|
@@ -48,6 +50,19 @@ function parseArgs(args) {
|
|
|
48
50
|
}
|
|
49
51
|
continue;
|
|
50
52
|
}
|
|
53
|
+
if (arg === '--hide-nav' || arg === '--hide-navigation' || arg === '--no-nav') {
|
|
54
|
+
hideNav = true;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const renderNavMatch = arg.match(/^(--render-nav|--is-render-nav|--isRenderNav)=(.+)$/);
|
|
58
|
+
if (renderNavMatch) {
|
|
59
|
+
hideNav = !parseBooleanOption(renderNavMatch[2], renderNavMatch[1]);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if ((arg === '--render-nav' || arg === '--is-render-nav' || arg === '--isRenderNav') && openOption.args[i + 1]) {
|
|
63
|
+
hideNav = !parseBooleanOption(openOption.args[++i], arg);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
51
66
|
filteredArgs.push(arg);
|
|
52
67
|
}
|
|
53
68
|
|
|
@@ -57,10 +72,22 @@ function parseArgs(args) {
|
|
|
57
72
|
pageName: filteredArgs[1],
|
|
58
73
|
mode,
|
|
59
74
|
locale,
|
|
75
|
+
hideNav,
|
|
60
76
|
openMode: openOption.mode,
|
|
61
77
|
};
|
|
62
78
|
}
|
|
63
79
|
|
|
80
|
+
function parseBooleanOption(value, optionName) {
|
|
81
|
+
const normalized = String(value || '').toLowerCase();
|
|
82
|
+
if (['true', '1', 'yes', 'y'].includes(normalized)) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
if (['false', '0', 'no', 'n'].includes(normalized)) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
throw new Error(`Invalid boolean value for ${optionName}: ${value}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
64
91
|
function buildPageInfoPostData(formUuid, pageName, isRenderNav, csrfToken) {
|
|
65
92
|
const titleJson = JSON.stringify(buildYidaTitleI18n(pageName, {
|
|
66
93
|
en_US: pageName,
|
|
@@ -98,12 +125,12 @@ function buildPageInfoPostData(formUuid, pageName, isRenderNav, csrfToken) {
|
|
|
98
125
|
});
|
|
99
126
|
}
|
|
100
127
|
|
|
101
|
-
async function
|
|
128
|
+
async function configureNavigationVisibility(authRef, appType, pageId, pageName, isRenderNav) {
|
|
102
129
|
return requestWithAutoLogin((auth) => {
|
|
103
130
|
return httpPost(
|
|
104
131
|
auth.baseUrl,
|
|
105
132
|
`/dingtalk/web/${appType}/query/formdesign/updateFormSchemaInfo.json`,
|
|
106
|
-
buildPageInfoPostData(pageId, pageName,
|
|
133
|
+
buildPageInfoPostData(pageId, pageName, isRenderNav, auth.csrfToken),
|
|
107
134
|
auth.cookies
|
|
108
135
|
);
|
|
109
136
|
}, authRef);
|
|
@@ -178,9 +205,9 @@ async function run(args) {
|
|
|
178
205
|
let pageUrl = workbenchUrl;
|
|
179
206
|
let dashboardConfigWarning = null;
|
|
180
207
|
|
|
181
|
-
if (
|
|
208
|
+
if (options.hideNav) {
|
|
182
209
|
step(3, t('create_page.step_dashboard_config'));
|
|
183
|
-
const configResponse = await
|
|
210
|
+
const configResponse = await configureNavigationVisibility(authRef, appType, pageId, pageName, false);
|
|
184
211
|
if (configResponse && configResponse.success) {
|
|
185
212
|
chalkSuccess(t('create_page.dashboard_config_ok'));
|
|
186
213
|
pageUrl = `${authRef.baseUrl}/${appType}/custom/${pageId}?isRenderNav=false`;
|
|
@@ -196,7 +223,7 @@ async function run(args) {
|
|
|
196
223
|
]);
|
|
197
224
|
|
|
198
225
|
console.log(JSON.stringify(withBrowserHandoff(
|
|
199
|
-
{ success: true, pageId, pageName, appType, mode,
|
|
226
|
+
{ success: true, pageId, pageName, appType, mode, hideNav: options.hideNav, chromeless: options.hideNav && !dashboardConfigWarning, url: pageUrl, workbenchUrl, dashboardConfigWarning },
|
|
200
227
|
pageUrl,
|
|
201
228
|
{ stage: 'create_page_success', title: pageName },
|
|
202
229
|
options.openMode
|