openyida 2026.7.7 → 2026.7.9

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 (88) hide show
  1. package/README.md +4 -2
  2. package/bin/yida.js +4 -4
  3. package/lib/app/canvas-compile.js +303 -0
  4. package/lib/app/publish.js +190 -39
  5. package/lib/auth/auth.js +11 -3
  6. package/lib/auth/login.js +34 -15
  7. package/lib/core/command-manifest.js +1 -1
  8. package/lib/core/env.js +19 -4
  9. package/lib/core/locales/ar.js +6 -2
  10. package/lib/core/locales/de.js +6 -2
  11. package/lib/core/locales/en.js +7 -3
  12. package/lib/core/locales/es.js +6 -2
  13. package/lib/core/locales/fr.js +6 -2
  14. package/lib/core/locales/hi.js +6 -2
  15. package/lib/core/locales/ja.js +7 -3
  16. package/lib/core/locales/ko.js +6 -2
  17. package/lib/core/locales/pt.js +6 -2
  18. package/lib/core/locales/vi.js +6 -2
  19. package/lib/core/locales/zh-HK.js +7 -3
  20. package/lib/core/locales/zh.js +7 -3
  21. package/lib/core/utils.js +195 -15
  22. package/lib/samples/yida-custom-page/custom-page-template.js +6 -6
  23. package/lib/samples/yida-custom-page/design-tokens.js +14 -12
  24. package/package.json +1 -1
  25. package/scripts/e2e-real/skill-coverage.js +4 -0
  26. package/scripts/validate-ci.sh +6 -0
  27. package/scripts/validate-package-size.js +12 -1
  28. package/yida-skills/SKILL.md +21 -6
  29. package/yida-skills/references/development-rules.md +13 -9
  30. package/yida-skills/references/field-and-url-reference.md +14 -1
  31. package/yida-skills/skills/large-file-write/SKILL.md +12 -10
  32. package/yida-skills/skills/large-file-write/references/write-patterns.md +13 -15
  33. package/yida-skills/skills/large-file-write/scripts/write.js +10 -10
  34. package/yida-skills/skills/yida-app/SKILL.md +15 -8
  35. package/yida-skills/skills/yida-canvas-custom-page/SKILL.md +115 -0
  36. package/yida-skills/skills/yida-canvas-custom-page/references/canvas-authoring-examples.md +163 -0
  37. package/yida-skills/skills/yida-canvas-custom-page/references/canvas-design-system.md +148 -0
  38. package/yida-skills/skills/yida-canvas-custom-page/references/data-bridge-guide.md +115 -0
  39. package/yida-skills/skills/yida-canvas-custom-page/references/dependencies-and-cdn.md +45 -0
  40. package/yida-skills/skills/yida-canvas-custom-page/references/employeefield-verification.md +68 -0
  41. package/yida-skills/skills/yida-canvas-upgrade/SKILL.md +99 -0
  42. package/yida-skills/skills/yida-canvas-upgrade/references/migration-examples.md +69 -0
  43. package/yida-skills/skills/yida-chart/SKILL.md +2 -2
  44. package/yida-skills/skills/yida-chart/references/echarts-bindding-guide.md +5 -6
  45. package/yida-skills/skills/yida-chart/references/examples.md +2 -2
  46. package/yida-skills/skills/yida-connector/SKILL.md +4 -0
  47. package/yida-skills/skills/yida-connector-safe-actions/SKILL.md +7 -4
  48. package/yida-skills/skills/yida-create-form-page/SKILL.md +11 -8
  49. package/yida-skills/skills/yida-create-process/SKILL.md +10 -4
  50. package/yida-skills/skills/yida-custom-page/SKILL.md +17 -6
  51. package/yida-skills/skills/yida-custom-page/examples/attachment-upload.js +1 -1
  52. package/yida-skills/skills/yida-custom-page/references/coding-guide.md +3 -3
  53. package/yida-skills/skills/yida-custom-page/references/component-jsx-guide.md +6 -3
  54. package/yida-skills/skills/yida-custom-page/references/design-system.md +30 -13
  55. package/yida-skills/skills/yida-data-management/SKILL.md +14 -11
  56. package/yida-skills/skills/yida-data-source-connectors/SKILL.md +3 -1
  57. package/yida-skills/skills/yida-flash-note-to-prd/references/examples.md +3 -2
  58. package/yida-skills/skills/yida-formula/references/examples.md +4 -4
  59. package/yida-skills/skills/yida-formula-evaluate/SKILL.md +4 -2
  60. package/yida-skills/skills/yida-get-schema/SKILL.md +14 -5
  61. package/yida-skills/skills/yida-i18n/SKILL.md +4 -2
  62. package/yida-skills/skills/yida-integration/SKILL.md +4 -1
  63. package/yida-skills/skills/yida-integration/references/examples.md +2 -2
  64. package/yida-skills/skills/yida-nav-shell/SKILL.md +119 -0
  65. package/yida-skills/skills/yida-nav-shell/references/nav-shell-patterns.md +302 -0
  66. package/yida-skills/skills/yida-openyida-publish-guard/SKILL.md +2 -2
  67. package/yida-skills/skills/yida-page-config/SKILL.md +1 -0
  68. package/yida-skills/skills/yida-page-uiux/SKILL.md +68 -0
  69. package/yida-skills/skills/yida-page-uiux/references/scenes/dashboard.md +128 -0
  70. package/yida-skills/skills/yida-page-uiux/references/scenes/detail.md +79 -0
  71. package/yida-skills/skills/yida-page-uiux/references/scenes/landing.md +101 -0
  72. package/yida-skills/skills/yida-page-uiux/references/scenes/list.md +78 -0
  73. package/yida-skills/skills/yida-page-uiux/references/scenes/workbench.md +74 -0
  74. package/yida-skills/skills/yida-page-uiux/references/visual-decision-engine.md +151 -0
  75. package/yida-skills/skills/yida-page-uiux/workflow/output-decision-block.md +36 -0
  76. package/yida-skills/skills/yida-page-uiux/workflow/step-0-nav-shape.md +39 -0
  77. package/yida-skills/skills/yida-page-uiux/workflow/step-1-page-type.md +25 -0
  78. package/yida-skills/skills/yida-page-uiux/workflow/step-2-intent-decode.md +25 -0
  79. package/yida-skills/skills/yida-page-uiux/workflow/step-3-scene-routing.md +29 -0
  80. package/yida-skills/skills/yida-page-uiux/workflow/step-4-visual-decision.md +32 -0
  81. package/yida-skills/skills/yida-page-uiux/workflow/step-5-icon-and-assets.md +36 -0
  82. package/yida-skills/skills/yida-page-uiux/workflow/step-6-deai-selfcheck.md +37 -0
  83. package/yida-skills/skills/yida-process-rule/SKILL.md +4 -1
  84. package/yida-skills/skills/yida-process-rule/references/examples.md +12 -12
  85. package/yida-skills/skills/yida-publish-page/SKILL.md +7 -3
  86. package/yida-skills/skills/yida-report/SKILL.md +5 -2
  87. package/yida-skills/skills/yida-report/references/examples.md +4 -4
  88. package/yida-skills/skills/yida-table-form/references/examples.md +2 -2
@@ -1,10 +1,10 @@
1
1
  # 核心规则详解
2
2
 
3
- > 逐条展开主 SKILL.md「核心规则」的操作细节,编号与主文件一一对应(FATAL 1–3 / IMPORTANT 1–11)。需要更多篇幅的规则指向文末专节。
3
+ > 逐条展开主 SKILL.md「核心规则」的操作细节,编号与主文件一一对应(FATAL 1–4 / IMPORTANT 1–11)。需要更多篇幅的规则指向文末专节。
4
4
 
5
5
  ## 致命规则(FATAL)
6
6
 
7
- **F1 先读后执行**:执行任何子技能前,必须先读取其 `skills/<技能名>/SKILL.md`,按文档里的参数格式操作,不凭记忆猜。
7
+ **F1 先读后执行**:执行任何子技能前,必须先读取对应子技能文档`skills/<技能名>/SKILL.md`,按文档里的参数格式操作,不凭记忆猜。
8
8
 
9
9
  **F2 corpId 一致性检查**:创建页面前对比 prd 文档与 `.cache/cookies.json` 的 corpId——
10
10
  - 一致 → 继续;
@@ -15,6 +15,8 @@
15
15
  - 发布时留意"同名双副本内容不一致"警告,必要时加 `--health-check` 做首屏 HTTP 健康检查;
16
16
  - 任何 JSON 配置写盘后先做 JSON 解析校验,再调用平台命令。
17
17
 
18
+ **F4 命令输入文件禁止 shell 写入**:当 OpenYida 命令需要 JSON/YAML/CSV/config/script 文件参数时,必须先使用当前 agent 运行时提供的结构化文件写入工具(如 create_file / Write / file edit tool)创建文件,再把文件路径传给命令。禁止用 shell heredoc、`cat`/`echo`/`printf`/`tee` 加输出重定向,或把 `openyida` 命令 stdout 重定向成业务配置、Schema、导入数据或一次性脚本。
19
+
18
20
  ## 重要规则(IMPORTANT)
19
21
 
20
22
  | # | 规则 | 操作细节 |
@@ -26,7 +28,7 @@
26
28
  | 5 | 数据性能优先 | 统计聚合用 `yida-report` 服务端聚合;不在自定义页面前端分页拉全量后自行聚合。 |
27
29
  | 6 | 避免无效重试 | 失败先按错误信息查登录态/组织/参数/字段 ID;无修改不连续重试超 1 次。 |
28
30
  | 7 | 配置分两处存 | 详见 [配置信息分两处存储](#配置信息分两处存储) 与 [PRD 质量门槛](#prd-质量门槛)。 |
29
- | 8 | 临时文件入 `.cache/` | 详见 [临时文件规范](#临时文件规范)。 |
31
+ | 8 | 临时文件入 project `.cache/` | 详见 [临时文件规范](#临时文件规范)。 |
30
32
  | 9 | 报表美化先问方案 | 详见 [报表优化 / 美化提示规则](#报表优化--美化提示规则)。 |
31
33
  | 10 | 按 schema 证据选技能 | 先看 `formType`、组件树、`dataSource.online`;`receipt/process/report` 分别落到表单/流程/报表技能,只有默认页是自定义展示页、或确需列表/看板/工具页交互时才落到 `yida-custom-page`。 |
32
34
  | 11 | 官方示例范式优先 | 蒸馏宜搭示例中心时,先按 [官方示例 Schema 范式](official-example-schema-patterns.md) 理解脱敏 schema 的承载方式,不凭截图/卡片标题/页面视觉判断。 |
@@ -55,14 +57,16 @@
55
57
 
56
58
  ## 临时文件规范
57
59
 
58
- 所有临时文件(cookies、schema 缓存、字段/报表/流程配置、导入数据、一次性脚本等)**必须写在项目根目录的 `.cache/` 下**,不写仓库根目录或系统其他位置。
60
+ 所有 OpenYida 业务中间文件(cookies、schema 缓存、字段/报表/流程配置、导入数据、一次性脚本等)**必须写在 OpenYida project 工作目录的 `.cache/` 下**,不写业务仓库根目录、系统 `/tmp` 或其他位置。源码中的 `<projectRoot>` 指 OpenYida project 工作目录;从 workspace 根执行命令时路径通常是 `project/.cache/...`,从 project 工作目录内执行时路径是 `.cache/...`。
61
+
62
+ 文件必须由 agent 的结构化文件写入工具创建,再传给 OpenYida 命令。不要通过 `execute_shell` 加 heredoc、`cat`/`echo`/`printf`/`tee`、管道或重定向来生成 JSON/YAML/CSV/config/script 文件。`/tmp` 只允许用于外部工具强制要求的系统临时路径,OpenYida 业务配置、schema、导入数据和一次性脚本不写 `/tmp`。
59
63
 
60
64
  | 工件类型 | 推荐位置 |
61
65
  |---------|---------|
62
- | Schema / ID 映射 | `.cache/<项目名>-schema.json` |
63
- | 字段 / 报表 / 流程配置 | `.cache/openyida/<项目名>/` |
64
- | 批量导入数据(JSON/JSONL/CSV) | `.cache/openyida/data-import/` |
65
- | 一次性 Python / JS 脚本 | `.cache/openyida/scripts/` |
66
+ | Schema / ID 映射 | `<projectRoot>/.cache/<项目名>-schema.json` |
67
+ | 字段 / 报表 / 流程 / 连接器配置 | `<projectRoot>/.cache/openyida/<项目名或任务名>/` |
68
+ | 批量导入数据(JSON/JSONL/CSV) | `<projectRoot>/.cache/openyida/<项目名或任务名>/data-import/` |
69
+ | 一次性 Python / JS 脚本 | `<projectRoot>/.cache/openyida/<项目名或任务名>/scripts/` |
66
70
 
67
71
  > 只有需长期维护的 PRD、页面源码、示例资源才写入 `prd/`、`pages/src/`、`project/` 等正式目录。
68
72
 
@@ -73,7 +77,7 @@
73
77
  | 方案 | 做法 | 适用 | 落到 |
74
78
  |------|------|------|------|
75
79
  | A 优化原生报表 | 调整图表类型、布局、筛选器,仍用宜搭原生组件 | 快速优化、无需写代码 | `yida-report`(`openyida create-report`) |
76
- | B ECharts 高级报表 | ECharts + 自定义页面 JSX,高度定制 | 精美视觉、复杂交互、数据大屏 | 读 `skills/yida-chart/SKILL.md` |
80
+ | B ECharts 高级报表 | ECharts + 自定义页面 JSX,高度定制 | 精美视觉、复杂交互、数据大屏 | 读 `yida-chart` 子技能文档 |
77
81
 
78
82
  话术示例:
79
83
 
@@ -34,9 +34,22 @@
34
34
  |---------|---------|
35
35
  | 应用首页 | `{base_url}/{appType}/workbench` |
36
36
  | 表单提交页 | `{base_url}/{appType}/submission/{formUuid}` |
37
+ | 数据管理页(列表) | `{base_url}/{appType}/workbench/{formUuid}` |
38
+ | 数据管理页(iframe 嵌入) | `{base_url}/{appType}/workbench/{formUuid}?iframe=true` |
37
39
  | 自定义页面 | `{base_url}/{appType}/custom/{formUuid}` |
38
40
  | 自定义页面(隐藏导航) | 上行 + `?isRenderNav=false` |
39
41
  | 表单详情页 | `{base_url}/{appType}/formDetail/{formUuid}?formInstId={formInstId}` |
40
42
  | 表单详情页(编辑态) | 上行 + `&mode=edit` |
41
43
 
42
- > 任意地址追加 `&corpid={corpId}` 可自动切到对应组织。
44
+ > 任意地址可追加 `corpid={corpId}` 自动切到对应组织;无 query 时用 `?corpid=...`,已有 query 时用 `&corpid=...`。
45
+
46
+ ## 页面内自定义导航 URL 参数规则
47
+
48
+ 当自定义页自己绘制导航壳、并隐藏宜搭原导航时,导航项不能只保存 `formUuid`,必须保存可合并的 URL 参数:
49
+
50
+ - 自定义展示页目标:使用 `{base_url}/{appType}/custom/{formUuid}?isRenderNav=false`,保持目标页也不显示宜搭原导航。
51
+ - 数据表单目标:若在导航壳内容区嵌入,用 `{base_url}/{appType}/workbench/{formUuid}?iframe=true`;若整页跳转到 workbench,明确接受目标页回到宜搭工作台框架。
52
+ - 跨组织访问:在已有 query 后追加 `&corpid={corpId}`;没有 query 时用 `?corpid={corpId}`。
53
+ - 业务深链:导航项可带 `tab`、`view`、`dateRange`、`mode` 等白名单参数;拼 URL 时与公共参数合并,不能被 `router.push(formUuid)` 吞掉。
54
+
55
+ 推荐用统一 URL 构造函数处理 `?` / `&`,不要手写多个分支散落在 JSX 里。
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: large-file-write
3
- description: 解决 heredoc 或 shell 命令写入大文件内容被截断的问题。通过 Node.js 脚本将内容作为模板字符串写入,绕过 shell 截断限制。适用于需要可靠写入超过 100 行文本文件时。
3
+ description: 解决 heredoc 或 shell 命令写入大文件内容被截断的问题。优先使用 agent 结构化文件写入工具;超大文件可用该工具创建 Node.js payload 后执行。适用于需要可靠写入超过 100 行文本文件时。
4
4
  ---
5
5
 
6
6
  # Large File Write Skill
7
7
 
8
8
  ## 问题背景
9
9
 
10
- 在 AI Agent 模式下,使用 heredoc(`<< 'EOF'`)或 shell 命令向文件写入大块内容时,经常出现:
10
+ 在 AI Agent 模式下,使用 shell here-document 或其他 shell 命令向文件写入大块内容时,经常出现:
11
11
  - 内容被截断(工具输出超过 token 限制)
12
12
  - heredoc 内容未生效(zsh 特殊字符转义问题)
13
13
  - 多次追加导致重复内容或语法错误
@@ -15,20 +15,22 @@ description: 解决 heredoc 或 shell 命令写入大文件内容被截断的问
15
15
 
16
16
  ## 解决方案
17
17
 
18
- 使用 Node.js 脚本 `scripts/write.js`,将内容作为 JS 字符串变量传入,绕过 shell 截断限制。
18
+ 优先使用当前 agent 运行时提供的结构化文件写入工具(如 create_file / Write / file edit tool)直接创建目标文件。内容过大、单次写入可能截断时,再用结构化写入工具创建 Node.js payload 脚本,由 payload 调用 `fs.writeFileSync` 写目标文件。
19
+
20
+ OpenYida 业务场景下,payload、内容片段和验证脚本必须放在 `<projectRoot>/.cache/openyida/<项目名或任务名>/scripts/`,不要写系统临时目录、仓库根目录或 `.cache/` 顶层。
19
21
 
20
22
  ## 使用方式
21
23
 
22
24
  三种写入模式的完整代码示例,详见 [references/write-patterns.md](./references/write-patterns.md):
23
25
 
24
- - **模式一**:创建内容脚本后执行(推荐)— `create_file` 创建临时 JS 脚本,再 `node` 执行
26
+ - **模式一**:创建内容脚本后执行(推荐)— 用结构化文件写入工具创建临时 JS 脚本,再 `node` 执行
25
27
  - **模式二**:追加内容到已有文件 — 用 `fs.appendFileSync` 追加大块内容
26
- - **模式三**:使用通用写入脚本(stdin 模式)— 通过管道传入内容
28
+ - **模式三**:使用通用写入脚本(content-file 模式)— 内容文件也先由结构化文件写入工具创建
27
29
 
28
30
  ### 快速示例
29
31
 
30
32
  ```js
31
- // /tmp/content-payload.js
33
+ // <projectRoot>/.cache/openyida/<任务名>/scripts/content-payload.js
32
34
  const fs = require('fs');
33
35
  const content = `// 你的大块内容(支持任意长度)
34
36
  export function myFunction() { ... }
@@ -38,17 +40,17 @@ console.log('写入完成,行数:', content.split('\n').length);
38
40
  ```
39
41
 
40
42
  ```bash
41
- node /tmp/content-payload.js
43
+ node .cache/openyida/<任务名>/scripts/content-payload.js
42
44
  wc -l /path/to/target.js # 验证行数
43
45
  ```
44
46
 
45
47
  ## 核心原则
46
48
 
47
- 1. **永远不要用 heredoc 写大文件** — 改用 `create_file` 工具创建临时 JS 脚本
49
+ 1. **永远不要用 heredoc 写大文件** — 改用结构化文件写入工具创建临时 JS 脚本
48
50
  2. **永远不要用 PowerShell JSON 化大文件** — 禁止 `Get-Content -Raw <file> | ConvertTo-Json`、`ConvertFrom-Json` 处理 `.oyd.jsx/.jsx/.js` 页面源码
49
51
  3. **内容放在 JS 模板字符串里** — 支持任意长度,不受 shell 限制
50
52
  4. **写完立即验证** — `wc -l` 检查行数,`tail` 检查末尾内容
51
- 5. **分段写入大文件** — 超过 300 行的内容,拆分为多个 `create_file` + `node` 执行
53
+ 5. **分段写入大文件** — 超过 300 行的内容,拆分为多个结构化写入 + `node` 执行
52
54
  6. **本技能不读写 memory**:文件写入为纯本地操作,不依赖跨会话的 memory 状态
53
55
 
54
56
  ## 适用场景
@@ -88,4 +90,4 @@ Get-Content -Raw project\pages\src\vendor-section.oyd.jsx | ConvertTo-Json
88
90
  | `node: command not found` | Node.js 未安装 | 先安装 Node.js ≥ 16 |
89
91
  | 脚本执行后文件为空 | 模板字符串语法错误 | 检查反引号是否闭合,特殊字符是否转义 |
90
92
  | 写入不完整 | 内容超过单次 create_file 限制 | 按「分段写入」方式拆分为多个脚本 |
91
- | 权限拒绝 | 目标路径无写权限 | 检查目录权限,或改用 `/tmp/` 路径 |
93
+ | 权限拒绝 | 目标路径无写权限 | 检查目标目录权限;OpenYida 业务文件仍应留在 project 工作目录内 |
@@ -6,10 +6,10 @@
6
6
 
7
7
  适用于一次性写入大块内容(>100 行)。
8
8
 
9
- ### Step 1:用 `create_file` 工具创建临时内容脚本
9
+ ### Step 1:用结构化文件写入工具创建临时内容脚本
10
10
 
11
11
  ```js
12
- // /tmp/content-payload.js
12
+ // <projectRoot>/.cache/openyida/<任务名>/scripts/content-payload.js
13
13
  const fs = require('fs');
14
14
  const content = `
15
15
  // 这里放你要写入的大块内容
@@ -25,7 +25,7 @@ console.log('写入完成,行数:', content.split('\n').length);
25
25
  ### Step 2:执行脚本
26
26
 
27
27
  ```bash
28
- node /tmp/content-payload.js
28
+ node .cache/openyida/<任务名>/scripts/content-payload.js
29
29
  ```
30
30
 
31
31
  ### Step 3:验证写入结果
@@ -42,7 +42,7 @@ tail -5 /path/to/target.js
42
42
  适用于向已有文件末尾追加大块内容。
43
43
 
44
44
  ```js
45
- // /tmp/append-payload.js
45
+ // <projectRoot>/.cache/openyida/<任务名>/scripts/append-payload.js
46
46
  const fs = require('fs');
47
47
  const appendContent = `
48
48
  // 追加的内容
@@ -57,22 +57,23 @@ console.log('追加完成');
57
57
  执行:
58
58
 
59
59
  ```bash
60
- node /tmp/append-payload.js
60
+ node .cache/openyida/<任务名>/scripts/append-payload.js
61
61
  ```
62
62
 
63
63
  ---
64
64
 
65
- ## 模式三:使用通用写入脚本(stdin 模式)
65
+ ## 模式三:使用通用写入脚本(content-file 模式)
66
66
 
67
- 适用于通过管道传入内容的场景。
67
+ 适用于内容已经由结构化文件写入工具保存为独立文件的场景。
68
68
 
69
69
  ```bash
70
70
  node ~/.agents/skills/large-file-write/scripts/write.js \
71
71
  --file /path/to/target.js \
72
+ --content-file .cache/openyida/<任务名>/scripts/content.txt \
72
73
  --mode write # 或 append
73
74
  ```
74
75
 
75
- 然后通过 stdin 输入内容(Ctrl+D 结束)。
76
+ 不要通过 shell 管道、heredoc 或重定向临时生成 `content.txt`;先使用 create_file / Write / file edit tool 创建它。
76
77
 
77
78
  ---
78
79
 
@@ -80,10 +81,7 @@ node ~/.agents/skills/large-file-write/scripts/write.js \
80
81
 
81
82
  **不要**用 PowerShell 把大 JSX/JS 文件转成 JSON patch:
82
83
 
83
- ```powershell
84
- # 禁止:会把整个文件读入内存并生成转义后的大字符串
85
- Get-Content -Raw project\pages\src\vendor-section.oyd.jsx | ConvertTo-Json > vendor-patch.json
86
- ```
84
+ 禁止把整个文件读入内存再重定向成 JSON patch,例如 `Get-Content -Raw ... | ConvertTo-Json` 这类流程会制造巨大中间数据,也违反“命令输入文件由结构化写入工具创建”的约定。
87
85
 
88
86
  这种写法会同时持有原始源码、JSON 转义字符串、管道对象和输出缓冲。对包含 vendor、base64、压缩代码的 `.oyd.jsx` 文件,内存可能被放大到数十 GB。
89
87
 
@@ -106,7 +104,7 @@ fs.writeFileSync(target, next, 'utf8');
106
104
  当单次内容超过 300 行时,拆分为多个脚本分段写入:
107
105
 
108
106
  ```js
109
- // /tmp/part1-payload.js — 写入第一段(文件头 + 前半部分)
107
+ // <projectRoot>/.cache/openyida/<任务名>/scripts/part1-payload.js — 写入第一段(文件头 + 前半部分)
110
108
  const fs = require('fs');
111
109
  const part1 = `
112
110
  // === 第一段内容 ===
@@ -118,7 +116,7 @@ console.log('第一段写入完成');
118
116
  ```
119
117
 
120
118
  ```js
121
- // /tmp/part2-payload.js — 追加第二段
119
+ // <projectRoot>/.cache/openyida/<任务名>/scripts/part2-payload.js — 追加第二段
122
120
  const fs = require('fs');
123
121
  const part2 = `
124
122
  // === 第二段内容 ===
@@ -145,5 +143,5 @@ tail -5 /path/to/target.js
145
143
  |---------|------|---------|
146
144
  | 文件为空 | 模板字符串反引号未闭合 | 检查 `` ` `` 是否成对,特殊字符是否转义 |
147
145
  | 内容截断 | 单次 create_file 超过 token 限制 | 拆分为多个脚本分段写入 |
148
- | 权限拒绝 | 目标路径无写权限 | 改用 `/tmp/` 路径,或检查目录权限 |
146
+ | 权限拒绝 | 目标路径无写权限 | 检查目标目录权限;OpenYida 业务文件仍应留在 project 工作目录内 |
149
147
  | node 命令未找到 | Node.js 未安装 | 先安装 Node.js ≥ 16 |
@@ -8,9 +8,9 @@
8
8
  * node write.js --file <目标文件路径> [--mode write|append] [--encoding utf8]
9
9
  *
10
10
  * 内容来源(三选一):
11
- * 1. stdin:echo "content" | node write.js --file out.js
12
- * 2. --content-file <临时内容文件>:node write.js --file out.js --content-file /tmp/content.txt
13
- * 3. --payload <JS文件>:node write.js --payload /tmp/payload.js(payload 文件自行调用 fs 写入)
11
+ * 1. stdin:交互式输入或由调用方传入标准输入
12
+ * 2. --content-file <内容文件>:node write.js --file out.js --content-file .cache/openyida/task/content.txt
13
+ * 3. --payload <JS文件>:node write.js --payload .cache/openyida/task/payload.js(payload 文件自行调用 fs 写入)
14
14
  */
15
15
 
16
16
  const fs = require('fs');
@@ -53,15 +53,15 @@ large-file-write - 大文件可靠写入工具
53
53
  --help 显示帮助
54
54
 
55
55
  示例:
56
- # 从 stdin 写入
57
- echo "hello world" | node write.js --file /tmp/out.txt
56
+ # 从 stdin 写入
57
+ node write.js --file .cache/openyida/task/out.txt
58
58
 
59
- # 从内容文件写入
60
- node write.js --file /tmp/out.js --content-file /tmp/content.txt --verify
59
+ # 从内容文件写入
60
+ node write.js --file .cache/openyida/task/out.js --content-file .cache/openyida/task/content.txt --verify
61
61
 
62
- # 执行自包含 payload 脚本
63
- node write.js --payload /tmp/my-payload.js
64
- `);
62
+ # 执行自包含 payload 脚本
63
+ node write.js --payload .cache/openyida/task/my-payload.js
64
+ `);
65
65
  process.exit(0);
66
66
  }
67
67
 
@@ -13,6 +13,7 @@ description: 宜搭完整应用开发技能。从零到一搭建完整宜搭应
13
13
  - 不要跳过 `openyida env` 环境检测直接开始开发
14
14
  - 不要在未读取各子技能 SKILL.md 的情况下执行对应操作
15
15
  - 不要编造任何 ID(appType/formUuid/fieldId),必须从命令返回中提取
16
+ - 不要用 shell heredoc、`cat`/`echo`/`printf`/`tee` 或重定向生成 OpenYida 命令输入文件
16
17
 
17
18
  ## 严格要求 (MUST DO)
18
19
 
@@ -20,7 +21,7 @@ description: 宜搭完整应用开发技能。从零到一搭建完整宜搭应
20
21
  - 按照本文档的流程编排顺序执行,不要跳步
21
22
  - 每个关键 ID 创建后立即记录到 `.cache/<项目名>-schema.json`
22
23
  - 业务需求记录到 `prd/<项目名>.md`
23
- - 临时字段配置、流程配置、报表配置、导入数据和一次性执行脚本统一写入 `.cache/openyida/`,不要写到仓库根目录
24
+ - 临时字段配置、流程配置、报表配置、连接器配置、导入数据和一次性执行脚本统一用结构化文件写入工具创建到 `<projectRoot>/.cache/openyida/<项目名或任务名>/`;从 workspace 根执行命令时传 `project/.cache/...`,从 OpenYida project 工作目录执行时传 `.cache/...`;不要写到仓库根目录或系统临时目录
24
25
  - 首次生成完整应用后,必须基于业务信息架构整理导航顺序:面向决策者的总览/驾驶舱看板作为门面靠前,数据录入/明细表单在后;同级多个专题看板按业务优先级排,不要把所有自定义页面无脑堆最前
25
26
  - 导航整理完成后,若应用含表单,默认向核心表单灌入 2-3 条覆盖关键维度的示例数据,让看板首屏有真实聚合效果;`DateField`/`CascadeDateField` 用 13 位毫秒时间戳,灌后 `openyida data query` 抽查至少 1 条确认字段值非空(用户明确说"不要示例数据"时才跳过)
26
27
  - **本技能不读写 memory**:所有关键 ID(appType、formUuid 等)通过 `.cache/<项目名>-schema.json` 持久化,不依赖跨会话的 memory 状态
@@ -54,7 +55,8 @@ description: 宜搭完整应用开发技能。从零到一搭建完整宜搭应
54
55
  [Step 5](按需,需求含「审批」「流程」「申请」「审核」「工单」等关键词时必须执行)
55
56
  配置流程 → 读取 skills/yida-create-process/SKILL.md → openyida create-process / configure-process
56
57
 
57
- [Step 6] 编写自定义页面代码 → yida-custom-page 规范 → pages/src/<项目名>.oyd.jsx
58
+ [Step 6] 编写自定义页面代码 → yida-page-uiux 定视觉方向,再 yida-custom-page 落地 → pages/src/<项目名>.oyd.jsx
59
+ ↓ (首次生成必做:先用 yida-page-uiux 产出「视觉方向决策块」,避免统一灰白圆角的 AI 味模板脸)
58
60
  ↓ openyida check-page / compile 预检(.oyd.jsx 自动兼容构建)
59
61
  ↓ (列表/表格类页面:参考 yida-density 技能选择合适的信息密度)
60
62
 
@@ -69,7 +71,7 @@ description: 宜搭完整应用开发技能。从零到一搭建完整宜搭应
69
71
  [Step 10] 输出访问链接,用系统浏览器打开
70
72
  ```
71
73
 
72
- ### 编写自定义页面代码前必须完整学习 `skills/yida-custom-page/SKILL.md`
74
+ ### 编写自定义页面代码前先读 `skills/yida-page-uiux/SKILL.md` 定视觉方向,再完整学习 `skills/yida-custom-page/SKILL.md`
73
75
 
74
76
  ### 生成表单 schema 前必须完整学习 `skills/yida-create-form-page/SKILL.md`
75
77
 
@@ -275,7 +277,9 @@ openyida create-page <appType> "<页面名称>" [--mode dashboard]
275
277
 
276
278
  **当页面需要收集/存储数据时**,调用 `yida-create-form-page` 技能。
277
279
 
278
- #### 4.1 定义字段,写入 `.cache/openyida/<项目名>/xxx-fields.json`
280
+ #### 4.1 定义字段,写入 `<projectRoot>/.cache/openyida/<项目名或任务名>/xxx-fields.json`
281
+
282
+ 使用 create_file / Write / file edit tool 创建字段定义文件;不要用 shell heredoc 或重定向写 JSON。若从 workspace 根执行命令,路径写作 `project/.cache/openyida/<项目名或任务名>/xxx-fields.json`。
279
283
 
280
284
  ```json
281
285
  [
@@ -289,7 +293,7 @@ openyida create-page <appType> "<页面名称>" [--mode dashboard]
289
293
  #### 4.2 创建表单
290
294
 
291
295
  ```bash
292
- openyida create-form create <appType> "<表单名称>" .cache/openyida/<项目名>/xxx-fields.json
296
+ openyida create-form create <appType> "<表单名称>" .cache/openyida/<项目名或任务名>/xxx-fields.json
293
297
  ```
294
298
 
295
299
  **输出**:`formUuid` 和各字段的 `fieldId`(如 `textField_xxxxxxxx`)。
@@ -325,9 +329,11 @@ openyida create-form create <appType> "<表单名称>" .cache/openyida/<项目
325
329
  **当需求含「审批」「流程」「申请」「审核」「工单」等关键词时必须执行**。
326
330
 
327
331
  ```bash
328
- openyida create-process <appType> --formUuid <formUuid> <流程定义文件>
332
+ openyida create-process <appType> --formUuid <formUuid> .cache/openyida/<项目名或任务名>/process-definition.json
329
333
  ```
330
334
 
335
+ 流程定义文件先用结构化文件写入工具创建;从 workspace 根执行命令时路径加 `project/` 前缀。
336
+
331
337
  > 📖 详见 [`skills/yida-create-process/SKILL.md`](../yida-create-process/SKILL.md)
332
338
 
333
339
  ---
@@ -396,10 +402,11 @@ openyida nav-group order <appType> <总览看板> <专题看板...> <核心表
396
402
  新建应用的表单默认无数据,看板首屏会空。导航整理完成后,默认向核心表单灌入 **2-3 条**覆盖关键维度(不同活动/渠道/日期等)的示例记录,调用 `yida-data-management` 技能:
397
403
 
398
404
  ```bash
399
- openyida data create form <appType> <formUuid> --data-json '{"selectField_xxx":"双11","dateField_xxx":1730995200000,"numberField_xxx":1200000}'
405
+ openyida data create form <appType> <formUuid> --data-file .cache/openyida/<项目名或任务名>/data-import/sample-record-1.json
400
406
  ```
401
407
 
402
408
  **要点**:
409
+ - 示例数据 JSON 先用结构化文件写入工具创建到 `<projectRoot>/.cache/openyida/<项目名或任务名>/data-import/`;从 workspace 根执行命令时路径加 `project/` 前缀。
403
410
  - `DateField`/`CascadeDateField` 必须用 13 位毫秒时间戳,不要传 `YYYY-MM-DD`。
404
411
  - 字段 ID 从 `.cache/<项目名>-schema.json` 或 `openyida get-schema` 获取,不能猜。
405
412
  - 灌完执行 `openyida data query form <appType> <formUuid>` 抽查至少 1 条,确认 `formData` 字段有实际值。
@@ -430,7 +437,7 @@ openyida data create form <appType> <formUuid> --data-json '{"selectField_xxx":"
430
437
 
431
438
  **测试数据/修数脚本约定**:
432
439
  - 一次性造数、旧数据修正、字段迁移可以使用 Python 或 JS,选择更快更清晰的实现即可;不要求为了“宜搭”强行写 JS。
433
- - 脚本放在 `.cache/openyida/scripts/` 下,导入数据放在 `.cache/openyida/data-import/` 下;执行前先 `openyida get-schema` / `openyida data query` 确认字段和记录,批量更新单次不超过 30 条。
440
+ - 脚本放在 `<projectRoot>/.cache/openyida/<项目名或任务名>/scripts/` 下,导入数据放在 `<projectRoot>/.cache/openyida/<项目名或任务名>/data-import/` 下,均由结构化文件写入工具创建;执行前先 `openyida get-schema` / `openyida data query` 确认字段和记录,批量更新单次不超过 30 条。
434
441
  - 脚本可以通过 `openyida data ...` 命令或宜搭官方接口执行,但字段 ID、formInstId、appType 必须来自真实查询结果,不能猜。
435
442
 
436
443
  ---
@@ -0,0 +1,115 @@
1
+ ---
2
+ name: yida-canvas-custom-page
3
+ description: 宜搭 Code Canvas / 代码画布自定义页面开发规范,是**自定义页面的默认链路**——现代 React 交互、hooks 状态、可视化、AI 生成或需要崩溃隔离的页面都用它(真 React18 + `runtimeCode` + `importedModules`)。只需通过开放 API(HTTP fetch)读写宜搭数据的页面也用它——Canvas 无 this 数据桥,在 YidaComp 内自写 HTTP 桥即可。也覆盖用户明确提到 code canvas、代码画布、YidaCodeCanvas、runtimeCode、importedModules,或在 Code Canvas 中使用 EmployeeField、SelectField、DepartmentSelectField 等原生组件的场景。仅当页面强依赖原生实例数据桥(this.$(fieldId) 双向绑定、this.utils.yida.*、dataSourceMap、提交流程深度耦合)时才回退 yida-custom-page。
4
+ ---
5
+
6
+ # 宜搭 Code Canvas 自定义页面开发
7
+
8
+ ## 核心定位
9
+
10
+ Code Canvas 是宜搭的**代码画布自定义页面链路**:以 `YidaCodeCanvas` 物料为承载,用户写标准 React18 函数组件源码,编译为 `runtimeCode` + 依赖清单(OpenYida CLI 本地用 Babel 完成),运行时按依赖白名单加载资源并 `new Function` 执行,渲染出真正的 React 组件。相较宜搭原生 `.oyd.jsx` 页面,它提供现代 hooks 写法、组件级崩溃隔离(ErrorBoundary)、Tailwind 运行时样式,适合现代交互 / 可视化 / AI 生成页面。
11
+
12
+ 运行链路(源码核实自 `vc-deep-yida` 物料):
13
+
14
+ 1. 编译阶段把用户 React 源码转译为 `runtimeCode` + 依赖清单 `importedModules`(OpenYida CLI **本地用 Babel 完成**:JSX/TS → ES5、`import` 改写成 `window.<别名>` 引用、`export default` 收敛为 `YidaComp`,依赖名正则抽取)。
15
+ 2. `YidaCodeCanvas` 运行时按依赖别名表把 `importedModules` 命中的白名单依赖加载 CDN 资源到 `window[windowAlias]`。
16
+ 3. `runtimeCode` 在宿主页真实 `window` 中 `new Function` 执行,返回 `YidaComp` / `YidaComp.default` / 组件函数并渲染。
17
+
18
+ 本技能处理从零编写 Code Canvas 页面。宜搭原生 `.oyd.jsx` 页面的 `export function renderJsx()`、`_customState`、`this.utils.yida.*`、`openyida publish` 规范由 `yida-custom-page` 负责;把已有原生页面迁移到 Code Canvas 链路由 `yida-canvas-upgrade` 负责。
19
+
20
+ ## 先判断能不能用 Code Canvas
21
+
22
+ | 证据 | 判断 |
23
+ | --- | --- |
24
+ | 现代 React 交互 / hooks 状态 / 可视化 / AI 生成 / 需崩溃隔离的自定义页 | **默认使用本技能** |
25
+ | 页面 Schema 或组件树里有 `componentName: "YidaCodeCanvas"` | 使用本技能 |
26
+ | 需求明确是“代码画布 / Code Canvas / runtimeCode / importedModules” | 使用本技能 |
27
+ | 需求明确是“从 OpenYida 原链路升级/迁移到 Canvas” | 切到 `yida-canvas-upgrade` |
28
+ | 只需通过开放 API(HTTP)读写宜搭数据的页面 | **仍用本技能**:在 `YidaComp` 内自写 fetch 调开放 API / 连接器代理(Canvas 无 `this` 桥,需自建 HTTP 数据桥) |
29
+ | 强依赖原生实例数据桥:表单内字段双向绑定 `this.$(fieldId)`、`this.utils.yida.*`、`dataSourceMap`、提交流程深度耦合 | 回退 `yida-custom-page`(该实例桥仅 native 免费提供) |
30
+ | 需要字段结构、公式、联动、权限、报表、流程 | 切到对应配置型技能,不用 Code Canvas 承载 |
31
+
32
+ OpenYida CLI 已支持发布 `YidaCodeCanvas` 页面:把 Code Canvas 源码写成 `.canvas.jsx`(推荐 `project/pages/src/<页面名>.canvas.jsx`),执行 `openyida publish <源文件> <appType> <formUuid>` 即自动走 Canvas 链路——`.canvas.jsx` 扩展名会被识别,CLI **本地用 Babel 编译**出 `runtimeCode` + `importedModules`(无需在线编译服务、无需登录态即可完成编译),构造 `YidaCodeCanvas` 组件的 Schema 并保存。扩展名不规范但确为 Canvas 源码时,加 `--canvas` 显式指定。**不要**把 Canvas 源码用普通 `.oyd.jsx`/`.jsx` 走 native 链路发布(会被 Babel 兼容编译器当 `renderJsx` 处理而失败)。
33
+
34
+ ## 运行时事实(速记)
35
+
36
+ - `runtimeCode` 在宿主页真实 `window` 中 `new Function` 执行(`fn(window, window)`),执行后必须返回 `YidaComp` / `YidaComp.default` / 组件函数。
37
+ - 物料只透传 `code / runtimeCode / importedModules / pageType`,无 `this` 上下文、无 `dataSourceMap` 数据桥;`this.utils.yida.*`、`didMount()` 等普通页契约都不可用。
38
+ - 宿主 window 全局不是数据桥:`__yida_plugin_runtime__` 是插件扩展点管理器、`__VcDeepYidaUtils__` 只是 `{ VuMicroUtils }`,也无 `window.Deep` 字段组件。不要指望从 window 直接拿表单数据。
39
+ - **读宜搭数据 = 自建 HTTP 桥**:在 `YidaComp` 内 `fetch` 调宜搭开放 API 或已配置连接器代理(同源带 cookie),自行处理 appType / formUuid / 鉴权;这是 Canvas 唯一干净的数据读写路径。
40
+ - 依赖走白名单(React、ReactDOM、antd、ahooks、d3、recharts、Radix、lucide-react、framer-motion…);新增依赖须被 CLI 编译识别(能抽入 `importedModules`)、有 window alias 映射、CSS 可加载。白名单无 yida-utils / `@ali/deep` / 原生字段组件,不能 `import`。
41
+ - `EmployeeField` 等宜搭原生字段组件不能因表单支持同名字段就默认可用,必须先做最小验证;缺证据时降级为 antd/自定义控件,只存已知 userId / unionId。
42
+
43
+ > 📖 运行时事实、原生组件判断、EmployeeField JSX 示例与验收清单 → [references/employeefield-verification.md](references/employeefield-verification.md)
44
+ > 📦 依赖白名单、windowAlias / CDN、antd/dayjs `is not defined` 根因与物料侧修复 → [references/dependencies-and-cdn.md](references/dependencies-and-cdn.md)
45
+ > 🔌 在 `YidaComp` 内自写 HTTP 桥读写宜搭数据(连接器代理 / 同源 fetch / 可复用 hook)→ [references/data-bridge-guide.md](references/data-bridge-guide.md)
46
+ > 🎨 主色跟随 App 品牌:antd `ConfigProvider.colorPrimary` / Tailwind CSS 变量 / 图表配色的落地写法 → [references/canvas-design-system.md](references/canvas-design-system.md)
47
+
48
+ ## 视觉方向:先定方向,再写代码
49
+
50
+ 写页面前先定视觉方向,避免首次就生成「默认蓝 + 大圆角 + emoji」的 AI 味套版。视觉决策是**栈无关**的,与 native 链路共用决策层技能 `yida-page-uiux`:读它的 `SKILL.md` 按页面类型(工作台/仪表盘/列表/详情)做 5 维差异化、走去 AI 味清单、严禁 emoji。
51
+
52
+ Canvas 这套栈(React18 + antd + Tailwind)怎么把「主色跟随 App 品牌」落地由 [references/canvas-design-system.md](references/canvas-design-system.md) 负责。一句话记忆:**CSS 变量 `var(--color-brand1-*)` 对普通 DOM / Tailwind 直接可用(Canvas 跑在真 window、节点在宿主树内会级联);antd token 和图表颜色是 JS 消费,需用 `getComputedStyle` 把品牌色解析成真实色值再喂进去。** 语义色(成功/警告/错误)保持固定,不随主题变。
53
+
54
+ ## 编码规则
55
+
56
+ 1. **不要写普通页面契约**:不要写 `export function renderJsx()`、`didMount()`、`this.forceUpdate()`、`this.utils.yida.*`,除非已验证 Code Canvas props 中提供等价能力。
57
+ 2. **入口必须明确**:源码必须导出或返回 `YidaComp`;不要只定义局部组件却不导出。
58
+ 3. **依赖必须可追踪**:所有 import 都要能出现在编译结果 `dependencies` 中;不在白名单的依赖不要交付。
59
+ 4. **状态按 React 组件写法处理**:Code Canvas 组件用标准 React hooks 写法(本地 Babel 编译支持);不要套用普通自定义页 `_customState` 模式。
60
+ 5. **副作用要清理**:使用 `useEffect` 注册事件、定时器、图表实例时必须返回 cleanup。
61
+ 6. **不要绕过数据源治理**:调用连接器或远程 API 时,优先通过平台已配置数据源或传入 props;不要在组件中硬编码外部 URL、Cookie、CSRF。
62
+ 7. **先验收依赖,再扩展业务**:原生组件、上传、组织搜索、弹层类能力必须先做最小验证页,确认可用后再写复杂业务页面。
63
+ 8. **主色跟随 App 品牌,勿硬编码蓝**:antd 页面在最外层包 `ConfigProvider`,`token.colorPrimary` 用 `getComputedStyle` 读平台 `--color-brand1-6` 解析出的真实色值;Tailwind / 普通 DOM 直接用 `var(--color-brand1-*)`;图表颜色同样读品牌色。语义色(成功/警告/错误)保持固定。禁止散落 `#1677ff` / `bg-blue-500` 等硬编码蓝。详见 [references/canvas-design-system.md](references/canvas-design-system.md)。
64
+
65
+ > 📖 最小 `YidaComp`、副作用清理、recharts 图表、数据拉取组件等 vetted 脚手架模板 → [references/canvas-authoring-examples.md](references/canvas-authoring-examples.md)
66
+
67
+ ## 开发流程
68
+
69
+ ```bash
70
+ # 1. 只读检查环境和登录态;真实创建资源前必须通过
71
+ openyida env --json
72
+ openyida login --check-only --json
73
+
74
+ # 2. 如需新页面,先创建空白自定义页拿 formUuid
75
+ openyida create-page <appType> "<页面名>"
76
+
77
+ # 3. 编写 Code Canvas 源码,写成 .canvas.jsx(推荐 project/pages/src/<页面名>.canvas.jsx)
78
+ # 只用白名单依赖;入口导出/返回 YidaComp;副作用带 cleanup。
79
+
80
+ # 4. 本地预检:不要用 openyida check-page/compile 校验 Canvas,它们当前是 native 页面检查器。
81
+ # Canvas 预检以 publish 的 Code Canvas 编译阶段为准;需要离线快检时可调用 lib/app/canvas-compile。
82
+ node -e "const fs=require('fs'); const {compileCanvasLocal}=require('./lib/app/canvas-compile'); const src=fs.readFileSync('project/pages/src/<页面名>.canvas.jsx','utf8'); const out=compileCanvasLocal(src); console.log(out.importedModules)"
83
+
84
+ # 5. 发布:.canvas.jsx 自动走 Canvas 链路,CLI 本地用 Babel 编译出
85
+ # runtimeCode + importedModules,构造 YidaCodeCanvas Schema 保存。
86
+ openyida publish project/pages/src/<页面名>.canvas.jsx <appType> <formUuid>
87
+ # 扩展名不规范但确为 Canvas 源码时,显式加 --canvas。
88
+
89
+ # 6. 发布后回读 Schema 验收:确认组件树存在 YidaCodeCanvas,且 runtimeCode 非空
90
+ openyida get-schema <appType> <formUuid>
91
+ ```
92
+
93
+ 如需保存完整 Schema,使用 create_file / Write / file edit tool 创建 `<projectRoot>/.cache/openyida/<页面名或任务名>/<页面名>-schema.json`;从 workspace 根执行后续命令时路径加 `project/` 前缀。不要把 `openyida` stdout 通过 shell 重定向保存成 JSON。
94
+
95
+ ## 与其他技能分工
96
+
97
+ | 需求 | 使用 |
98
+ | --- | --- |
99
+ | 普通 `.oyd.jsx` 自定义页 | `yida-custom-page` |
100
+ | 发布 Canvas 页(`.canvas.jsx` → `openyida publish` 自动走 Canvas 链路) | 本技能开发流程 step 4 |
101
+ | 编译并发布 native `.oyd.jsx`/`.jsx` 页面 | `yida-publish-page` |
102
+ | 创建空白自定义页面 | `yida-create-page` |
103
+ | 通过数据源调用连接器 | `yida-data-source-connectors` |
104
+ | 创建或管理 HTTP 连接器 | `yida-connector` |
105
+ | 配表单字段结构,如真正的 EmployeeField 字段 | `yida-create-form-page` |
106
+
107
+ ## 常见误区
108
+
109
+ | 误区 | 正确处理 |
110
+ | --- | --- |
111
+ | 看到表单支持 `EmployeeField`,就在 Code Canvas 写 `<EmployeeField />` | 先验证依赖映射、CSS、上下文和 `onChange` 结构 |
112
+ | 把 Code Canvas 源码用 `.oyd.jsx`/`.jsx` 发布 | native 链路会走 Babel 兼容编译器当 `renderJsx` 处理而失败;Canvas 源码要写成 `.canvas.jsx`(或加 `--canvas`),`openyida publish` 会自动走 Canvas 链路生成 `YidaCodeCanvas` Schema |
113
+ | 在 Code Canvas 中照搬 `this.utils.yida.searchFormDatas` | Code Canvas 组件没有普通页面实例契约;先看 props 或数据源注入方式 |
114
+ | 依赖加载失败后继续写业务 | 先补依赖 alias/CDN 或降级到已支持组件 |
115
+ | 用 `openyida check-page` / `openyida compile` 校验 `.canvas.jsx` | 这两个命令当前面向 native `.oyd.jsx`,会误报 Hook / default export 限制;Canvas 用 `compileCanvasLocal` 离线快检,最终以 `openyida publish .canvas.jsx` 的 Code Canvas 编译阶段为准 |