openyida 2026.9.2 → 2026.9.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.
Files changed (80) hide show
  1. package/README.md +9 -7
  2. package/lib/app/create-form/api-path.js +16 -2
  3. package/lib/app/create-form/args.js +14 -0
  4. package/lib/app/create-form/nav-icon-service.js +202 -0
  5. package/lib/app/create-form/nav-icon.js +267 -0
  6. package/lib/app/create-form.js +77 -3
  7. package/lib/app/nav-group.js +221 -53
  8. package/lib/app/page-template-guard.js +64 -0
  9. package/lib/app/publish.js +15 -1
  10. package/lib/app/services/canvas-page-schema-builder.js +1 -1
  11. package/lib/asset/ai-image.js +8 -9
  12. package/lib/asset/asset-cmd.js +3 -49
  13. package/lib/asset/asset-resolve.js +8 -10
  14. package/lib/asset/asset-status.js +7 -7
  15. package/lib/core/agent-capabilities.js +43 -1
  16. package/lib/core/cli-error.js +6 -1
  17. package/lib/core/command-contract.js +42 -1
  18. package/lib/core/command-manifest.js +73 -11
  19. package/lib/core/locales/en.js +5 -1
  20. package/lib/core/locales/zh.js +7 -3
  21. package/lib/core/query-data.js +126 -8
  22. package/lib/core/sample.js +51 -10
  23. package/lib/samples/openyida-scaffold/canvas-form-drawer.canvas.jsx +7 -7
  24. package/package.json +1 -1
  25. package/scripts/postinstall.js +5 -5
  26. package/yida-skills/SKILL.md +13 -13
  27. package/yida-skills/references/task-retrospective.md +4 -4
  28. package/yida-skills/skills/yida-app/SKILL.md +9 -8
  29. package/yida-skills/skills/yida-app/references/common-issues.md +1 -1
  30. package/yida-skills/skills/yida-app/workflow/step-2-design.md +42 -15
  31. package/yida-skills/skills/yida-app/workflow/step-3-create-or-reuse-app.md +8 -1
  32. package/yida-skills/skills/yida-app/workflow/step-4-forms-processes.md +13 -15
  33. package/yida-skills/skills/yida-app/workflow/step-7-page-code.md +4 -2
  34. package/yida-skills/skills/yida-app/workflow/step-8-publish-navigation.md +26 -11
  35. package/yida-skills/skills/yida-app/workflow/step-9-output-finish.md +22 -11
  36. package/yida-skills/skills/yida-canvas-custom-page/SKILL.md +8 -8
  37. package/yida-skills/skills/yida-canvas-custom-page/references/canvas-authoring-examples.md +1 -1
  38. package/yida-skills/skills/yida-canvas-custom-page/references/canvas-style-implementation-guide.md +16 -16
  39. package/yida-skills/skills/yida-canvas-custom-page/references/data-bridge-guide.md +1 -1
  40. package/yida-skills/skills/yida-canvas-custom-page/references/navigation-and-entry-guide.md +1 -1
  41. package/yida-skills/skills/yida-canvas-custom-page/references/page-generation-guide.md +6 -7
  42. package/yida-skills/skills/yida-canvas-table-form/SKILL.md +2 -2
  43. package/yida-skills/skills/yida-create-app/SKILL.md +13 -7
  44. package/yida-skills/skills/yida-create-form-page/SKILL.md +15 -17
  45. package/yida-skills/skills/yida-create-form-page/references/form-field-properties.md +1 -4
  46. package/yida-skills/skills/yida-custom-page/SKILL.md +5 -5
  47. package/yida-skills/skills/yida-custom-page/references/coding-guide.md +2 -6
  48. package/yida-skills/skills/yida-custom-page/references/design-system.md +4 -4
  49. package/yida-skills/skills/yida-data-management/SKILL.md +6 -4
  50. package/yida-skills/skills/yida-data-management/references/data-format-guide.md +13 -5
  51. package/yida-skills/skills/yida-design/SKILL.md +36 -39
  52. package/yida-skills/skills/yida-design/references/asset-workflow.md +32 -85
  53. package/yida-skills/skills/yida-design/references/page-quality-gates.md +3 -3
  54. package/yida-skills/skills/yida-design/references/style-design-selection.md +4 -4
  55. package/yida-skills/skills/yida-design/references/theme/app-custom-theme-template.css +15 -24
  56. package/yida-skills/skills/yida-design/references/theme/theme-token-presets.md +8 -8
  57. package/yida-skills/skills/yida-design/references/visual-decision-engine.md +1 -1
  58. package/yida-skills/skills/yida-design/references/visual-scaffold-recipes.md +2 -2
  59. package/yida-skills/skills/yida-design/sub_skill/page-design/SKILL.md +12 -13
  60. package/yida-skills/skills/yida-design/workflow/output-design.md +40 -26
  61. package/yida-skills/skills/yida-design/workflow/output-prd.md +8 -8
  62. package/yida-skills/skills/yida-design/workflow/step-1-read-brief.md +14 -0
  63. package/yida-skills/skills/yida-design/workflow/step-2-theme-system.md +23 -17
  64. package/yida-skills/skills/yida-design/workflow/step-4-wireframe-interaction.md +3 -3
  65. package/yida-skills/skills/yida-design/workflow/step-5-visual-states.md +5 -5
  66. package/yida-skills/skills/yida-design/workflow/step-6-handoff.md +22 -55
  67. package/yida-skills/skills/yida-nav-group/SKILL.md +3 -1
  68. package/yida-skills/skills/yida-page-config/SKILL.md +3 -1
  69. package/yida-skills/skills/yida-prd/SKILL.md +48 -0
  70. package/yida-skills/skills/yida-prd/references/app/blueprint.md +73 -0
  71. package/yida-skills/skills/yida-prd/references/app/navigation-patterns.md +43 -0
  72. package/yida-skills/skills/yida-prd/references/app/role-journey.md +30 -0
  73. package/yida-skills/skills/yida-prd/workflow/output-prd.md +188 -0
  74. package/yida-skills/skills/yida-prd/workflow/step-1-read-brief.md +15 -0
  75. package/yida-skills/skills/{yida-design/workflow/step-3-information-architecture.md → yida-prd/workflow/step-2-information-architecture.md} +2 -2
  76. package/yida-skills/skills/yida-publish-page/SKILL.md +1 -1
  77. package/yida-skills/skills/yida-requirement-analysis/SKILL.md +49 -0
  78. package/yida-skills/skills-index.json +36 -35
  79. package/yida-skills/skills/yida-design/workflow/step-1-positioning.md +0 -58
  80. package/yida-skills/skills/yida-form-detail/SKILL.md +0 -68
@@ -25,7 +25,7 @@
25
25
  | 本地源码改了但远端没更新 | 是否有成功的 `openyida publish <source> <appType> <displayPageFormUuid>` | 回到 [Step 8](../workflow/step-8-publish-navigation.md) 发布本轮源码 |
26
26
  | 发布失败后想重试 | 上一次 stdout/stderr、登录态、组织、参数、输入文件、字段 ID | 修改至少一项输入或上下文后重试;保留错误输出 |
27
27
  | 导航顺序不对 | PRD 的导航顺序、`nav-group order` / `nav-group auto-order` 输出 | 回到 Step 8;有明确顺序用 `nav-group order`,无明确顺序用自动排序兜底 |
28
- | final 输出太技术化 | 是否默认暴露资源 ID、管理态链接、CDN 产物 | 回到 [Step 9](../workflow/step-9-output-finish.md);改成 2-3 句业务总结 + 一个主入口链接 |
28
+ | final 输出太技术化或交付卡过多 | 是否把内部 artifact、每个业务资源、资源 ID、管理态链接或 CDN 产物逐项交付 | 回到 [Step 9](../workflow/step-9-output-finish.md);改成 2-3 句业务总结 + 一组应用访问入口 |
29
29
  | 用户要求删除应用 | 应用名称、应用 ID、影响范围、用户确认文本 | 展示影响范围,等待用户明确回复“确认删除”后执行 |
30
30
 
31
31
  ## 定位顺序
@@ -1,28 +1,55 @@
1
- # Step 2:产品设计
1
+ # Step 2:并行生成 PRD 与视觉设计
2
2
 
3
- 完整应用只走统一产品设计。`yida-app` 不直接凭感觉定义字段、页面结构或视觉风格;这些事实由 `yida-design` 产出。
3
+ 完整应用使用一个共享需求简报和两个独立 artifact owner。`yida-app` 是 join owner,不直接代写 PRD 或视觉设计。
4
4
 
5
- ## 设计技能
5
+ ## 2.1 共享输入
6
6
 
7
- 执行 `use_skill("yida-design", "完整应用产品设计")`,让它基于 Step 1 的资源上下文输出:
7
+ 执行 `use_skill("yida-requirement-analysis", "生成完整应用共享需求简报")`,写入:
8
8
 
9
- - `prd/<项目名>/prd.md`
10
- - `prd/<项目名>/design.md`
9
+ - `.cache/openyida/<项目名>/requirement-brief.json`
11
10
 
12
- 已有 app/page/form/process 只作为上下文复用;缺失资源按 PRD 的资源创建顺序落地,页面视觉按 `design.md` 落地。
11
+ 文件存在、可解析且没有会改变资源范围的未决问题后,需求简报进入 ready。
13
12
 
14
- ## 设计职责边界
13
+ 需求简报、PRD 和视觉设计都是应用编排的内部 artifact。artifact start/end 只表达 owner 生命周期和 join 状态,不表示要向最终用户交付文件;不得为这三个文件调用宿主的用户可见 artifact、附件或交付工具。
15
14
 
16
- | 文件 | 职责 |
17
- | --- | --- |
18
- | `prd.md` | 应用基本信息、用户角色、核心任务、业务对象、数据结构、页面与功能、业务逻辑、交互状态、资源蓝图、资源创建顺序、页面实现交付顺序、导航顺序和验收标准 |
19
- | `design.md` | 主题 token、视觉 DNA、布局密度、圆角规则、背景与卡片层次、组件规则、状态规则、响应式规则和页面视觉验收 |
15
+ 需求简报进入 ready 后即作为本轮 artifact 的冻结输入。后续资源创建产生的 `appType`、`formUuid`、`fieldId` 等真实 ID 只写入 schema 或当前任务资源上下文,不回写简报,也不因此重跑两个 artifact owner;只有用户需求或已确认资源范围发生实质变化时,才重新生成简报和 artifact。
20
16
 
21
- `prd.md` 和 `design.md` 是唯一设计事实源。`page-spec.json` 只是页面实现阶段从二者派生的 handoff / 生成器输入,不是第三份设计文件。
17
+ ## 2.2 并行 artifact
22
18
 
23
- ## 主题 key
19
+ 共享简报 ready 后,同时启动:
24
20
 
25
- 新版应用不再由设计产物选择或传递平台 `--theme` key。`design.md` 必须基于 `app-custom-theme-template.css` 给出应用 CSS、`navTheme`、`logoSource` 和新版 `layoutDirection`;CSS 完整声明平台实际生成的 `--color-brand1-1/2/3/5/6/9/10`,保留 `--color-brand-1` 至 `--color-brand-4` 和 `--color-group`,不得补造 `--color-brand1-4/7/8`。模板默认使用 coffee 咖啡色与大圆角;只有设计结论明确变化时才成套调整。主色写入 `--color-brand1-6`,创建阶段通过 `create-app --theme-file/--nav-theme/--logo-source/--layout` 联合保存。运行容器负责让页面、表单和详情页加载同一应用主题文件。
21
+ | artifact | owner skill | 输出 | end 条件 |
22
+ | --- | --- | --- | --- |
23
+ | Product PRD | `yida-prd` | `prd/<项目名>/prd.md` | 资源蓝图、资源创建顺序、页面实现交付顺序、导航顺序、页面 handoff 和验收标准完整 |
24
+ | Visual Design | `yida-design` | `prd/<项目名>/design.md` | 主题 token、视觉 DNA、布局、材质、圆角、密度、组件、状态、响应式和页面场景引用完整 |
25
+
26
+ 两个 owner 读取同一份需求简报,互不等待、互不写对方产物。一个 artifact 失败时只重跑其 owner,不覆盖已经 ready 的另一个 artifact。
27
+
28
+ ## 2.3 join
29
+
30
+ `yida-app` 必须等待两个 artifact 都结束,再执行 join 校验:
31
+
32
+ - 两个文件路径存在且非空;
33
+ - PRD 每个 display 页面的 `designFile` 指向当前 `design.md`;
34
+ - PRD 的 `designRefs` 在 `design.md` 中可定位;
35
+ - 页面场景、主题摘要和 `explicitScope` 没有冲突;
36
+ - 冲突时业务范围交给 `yida-prd` 修正,视觉规则交给 `yida-design` 修正,不由 `yida-app` 猜测覆盖。
37
+
38
+ join 未通过时 Step 2 未完成,不得进入资源创建。join 通过后,`prd.md` 和 `design.md` 是后续页面实现的两份唯一事实源;`page-spec.json` 仅为派生 handoff。
39
+
40
+ ## 主题文件实现指令
41
+
42
+ Step 2 只在 `design.md` 中确定主题色、`navTheme`、`logoSource` 和 `layoutDirection`,不传递平台 `--theme` key。进入 Step 3 后:
43
+
44
+ 1. 执行复制命令:
45
+
46
+ ```bash
47
+ openyida sample yida-design app-theme --output .cache/openyida/<项目名>/app-theme.css
48
+ ```
49
+
50
+ 2. 按 `design.md` 的主题色修改复制文件中的对应 token。严禁重新生成或覆盖整份 CSS。
51
+ 3. 主色写入 `--color-brand1-6`;保留 `--color-brand1-1/2/3/5/6/9/10`、`--color-brand-1` 至 `--color-brand-4` 和 `--color-group`;严禁补造 `--color-brand1-4/7/8`。
52
+ 4. 创建应用时传入 `--theme-file`、`--nav-theme`、`--logo-source` 和 `--layout`,在应用级统一配置主题。平台统一作用于原生表单、详情页和自定义页面外层;`YidaCodeCanvas` 页面只在组件内部消费主题 token,严禁向上层注入或同步主题样式。
26
53
 
27
54
  ## 产出
28
55
 
@@ -13,7 +13,14 @@
13
13
  1. 已有 `appType`、应用 URL 或已绑定 app → 直接复用该 app。
14
14
  2. 缺少 app 且 Step 1 判定 `allowCreate=true` → 执行 `use_skill("yida-create-app", "按 PRD 创建应用并获取 appType")`,再按 PRD 创建应用。
15
15
  3. 创建或复用后提取真实 `appType`,写入 `.cache/<项目名>-schema.json` 或当前任务资源上下文。
16
- 4. 新建完整应用默认基于 `app-custom-theme-template.css` 生成主题文件,并在 `create-app` 中同时传 `--theme-file`、`--nav-theme`、`--logo-source` 和新版 `--layout`。只有用户明确只要兼容空壳、暂不配置主题或保留旧创建方式时才省略主题文件;CLI 不把它设为硬性必填。
16
+ - Step 2 已 join 的 requirement brief、PRD 与 design 保持冻结;不得仅因拿到真实 `appType` 回写简报或重跑 artifact owner。
17
+ 4. 创建完整应用时,先执行以下命令复制模板:
18
+
19
+ ```bash
20
+ openyida sample yida-design app-theme --output .cache/openyida/<项目名>/app-theme.css
21
+ ```
22
+
23
+ 复制后按 `design.md` 的主题色修改对应 token,严禁重新生成或覆盖整份 CSS。随后在 `create-app` 中同时传 `--theme-file`、`--nav-theme`、`--logo-source` 和 `--layout`。只有用户明确只创建空壳或暂不配置主题时才省略主题文件。
17
24
  5. CLI 从 CSS 的 `--color-brand1-6` 自动提取 `themeColor`,创建后立即上传主题文件,并把 `customThemeStyle/themeColor/navTheme/logoSource/layoutDirection` 一次保存;不要再额外传 `--theme-color`。
18
25
  6. 已有 app 不自动改名。外部工具预创建 app 时,OpenYida 侧只复用 `appType`,但用户明确要求应用级换肤时可以执行上一步主题更新。
19
26
 
@@ -11,18 +11,17 @@
11
11
 
12
12
  ## 操作
13
13
 
14
- 1. 表单开发先执行 `use_skill("yida-form-detail", "表单视觉引导与新版应用主题消费")`,明确填写路径、字段密度和 Divider 分组。
15
- 2. 执行 `use_skill("yida-create-form-page", "创建或更新核心表单字段结构")`,创建或更新普通表单字段结构。
16
- 3. 已有目标表单时,使用 update/patch/rule/bind-datasource。
17
- 4. 缺少支撑 MVP 的核心普通表单且允许创建时,创建普通表单。
18
- 5. 字段配置文件写入 `.cache/openyida/<项目名>/`。
19
- 6. 拿到真实 `formUuid` 后确认 Step 3 的应用主题文件已联合保存;提交页和 formDetail 由运行容器加载该主题文件。
20
- 7. 页面、数据、流程或公式确需多字段映射时,对每个目标表单最多一次性执行 `openyida get-schema <appType> <formUuid> --field-map-json`,合并写回 `.cache/<项目名>-schema.json`。
21
- 8. PRD 包含审批、流程、申请、审核、工单等流程对象时,执行 `use_skill("yida-create-process", "创建带审批流程表单")`。
22
- 9. 已有流程表单或 `processCode` 时,执行 `use_skill("yida-process-rule", "更新已有流程规则")`。
23
- 10. 分析、复刻或迁移已有表单时,执行 `use_skill("yida-get-schema", "读取字段与行为语义")`,对每个核心表单读取一次 `--analysis-json`;把字段结构与 `actions/fieldBehaviors/associationRuleCount` 分开规划,字段事件动作使用 `yida-create-form-page` 的原子 `field-action`,数据源使用 `bind-datasource`。
24
- 11. PRD 明确包含原生报表时,执行 `use_skill("yida-report", "按业务统计语义创建原生报表")`;地域分布、日历统计分别使用已支持的 `map`、`calendarHeatmap`,不得无声明退化成柱/饼图。
25
- 12. PRD 明确包含集成自动化时,执行 `use_skill("yida-integration", "按业务动作创建自动化")`;已有应用先用全类型 `integration list --json` 盘点,创建时区分通知、数据新增/更新、审批完成、定时和手动触发。CLI 不支持的触发类型输出 capability gap,不得用通知替代。
14
+ 1. 执行 `use_skill("yida-create-form-page", "创建或更新核心表单字段结构")`,创建或更新普通表单字段结构。
15
+ 2. 已有目标表单时,使用 update/patch/rule/bind-datasource。
16
+ 3. 缺少支撑 MVP 的核心普通表单且允许创建时,创建普通表单。
17
+ 4. 字段配置文件写入 `.cache/openyida/<项目名>/`。
18
+ 5. 拿到真实 `formUuid` 后写入资源上下文。
19
+ 6. 页面、数据、流程或公式确需多字段映射时,对每个目标表单最多一次性执行 `openyida get-schema <appType> <formUuid> --field-map-json`,合并写回 `.cache/<项目名>-schema.json`。
20
+ 7. PRD 包含审批、流程、申请、审核、工单等流程对象时,执行 `use_skill("yida-create-process", "创建带审批流程表单")`。
21
+ 8. 已有流程表单或 `processCode` 时,执行 `use_skill("yida-process-rule", "更新已有流程规则")`。
22
+ 9. 分析、复刻或迁移已有表单时,执行 `use_skill("yida-get-schema", "读取字段与行为语义")`,对每个核心表单读取一次 `--analysis-json`;把字段结构与 `actions/fieldBehaviors/associationRuleCount` 分开规划,字段事件动作使用 `yida-create-form-page` 的原子 `field-action`,数据源使用 `bind-datasource`。
23
+ 10. PRD 明确包含原生报表时,执行 `use_skill("yida-report", "按业务统计语义创建原生报表")`;地域分布、日历统计分别使用已支持的 `map`、`calendarHeatmap`,不得无声明退化成柱/饼图。
24
+ 11. PRD 明确包含集成自动化时,执行 `use_skill("yida-integration", "按业务动作创建自动化")`;已有应用先用全类型 `integration list --json` 盘点,创建时区分通知、数据新增/更新、审批完成、定时和手动触发。CLI 不支持的触发类型输出 capability gap,不得用通知替代。
26
25
 
27
26
  ## 字段配置文件示例
28
27
 
@@ -73,15 +72,14 @@
73
72
  - 普通表单真实 `formUuid`;
74
73
  - 流程表单真实 `formUuid` / `processCode`;
75
74
  - 必要 `fieldId`;
76
- - 应用主题文件在表单、提交页和 formDetail 中的生效结论。
75
+ - 表单字段结构校验结论。
77
76
 
78
77
  ## Checklist
79
78
 
80
79
  - [ ] 字段结构有 Divider 分组;
81
80
  - [ ] 表单/流程资源在自定义页面之前创建或确认;
82
81
  - [ ] 必要 `fieldId` 已写入 `.cache/<项目名>-schema.json`;
83
- - [ ] 新版应用主题文件已配置,表单与 formDetail 直接消费同一 CSS;
84
- - [ ] 表单、提交页和 formDetail 已加载 Step 3 保存的应用主题文件。
82
+ - [ ] 表单 Schema 只包含字段、布局和业务动作。
85
83
 
86
84
  ## 下一步
87
85
 
@@ -12,7 +12,7 @@
12
12
 
13
13
  ## 操作
14
14
 
15
- 1. 自定义页面开发执行 `use_skill("yida-canvas-custom-page", "生成主页面源码")`。
15
+ 1. 自定义页面开发执行 `use_skill("yida-canvas-custom-page", "生成主页面源码")`。新建页面源码时,必须先把内置页面基准模板复制到目标 `.canvas.jsx` / `.canvas.tsx`,再按 PRD、`design.md`、真实 ID 和数据契约定点改写;不得从空文件重写整页。
16
16
  2. PRD 或页面名包含看板、工作台、驾驶舱、Dashboard 时,必须执行 `use_skill("yida-dashboard", "实现真实业务看板")`。
17
17
  3. 页面读取任一表单数据时,必须执行 `use_skill("yida-canvas-data-binding", "为页面接入真实表单数据")`;不得以“页面已经能发布”为由跳过。
18
18
  4. 页面结构已明确且适合生成器时,从 PRD + `design.md` 派生当前业务自己的 `page-spec.json`。
@@ -24,13 +24,14 @@
24
24
  10. 页面源码默认不自绘应用级侧边导航、顶部应用导航或同级模块菜单;PRD 的导航顺序交给 Step 8 的平台导航排序处理。只有用户显式要求在自定义页面内实现自己的应用级导航、隐藏应用导航或独立全屏应用壳时,才执行 `use_skill("yida-nav-shell")`。
25
25
  11. 没有真实数据时,页面展示空态、表单入口、刷新或登记按钮。
26
26
  12. 页面源码用 `.canvas.jsx` / `.canvas.tsx`、`YidaComp`、页面生成器或本地快检。
27
+ 13. 发布前必须删除 `@openyida-page-template-base`、`SAMPLE_ROWS`、`{{APP_TYPE}}` / `{{FORM_UUID}}`、示例数据和占位文案;内部模板名不得出现在页面 UI 或面向用户的 final 中。
27
28
 
28
29
  ## 事实源修正
29
30
 
30
31
  | 问题类型 | 修改位置 |
31
32
  | --- | --- |
32
33
  | 页面目标、业务对象、指标口径、主操作、表单入口、数据来源、空/载/错业务语义不足或错误 | 回写 `prd.md`,再重新派生 `page-spec.json` |
33
- | 主题关系、token、视觉脚手架、背景、材质、圆角、密度、组件、状态或响应式规则不足或错误 | 回写 `design.md`,再重新派生 `page-spec.json` 或重读 `design.md` 实现 |
34
+ | 主题关系、token、视觉结构、背景、材质、圆角、密度、组件、状态或响应式规则不足或错误 | 回写 `design.md`,再重新派生 `page-spec.json` 或重读 `design.md` 实现 |
34
35
  | `page-spec.json` 缺少 sourceOfTruth、design 指针、dataBinding,或与 PRD/design.md 不一致 | 丢弃并从最新 PRD + `design.md` 重生成 |
35
36
  | PRD、design.md 和 spec 都完整,但源码有 className、布局比例、字段映射、响应式、loading/empty/error 或编译错误 | 小范围 patch 源码 |
36
37
 
@@ -50,6 +51,7 @@
50
51
  - [ ] Canvas 页面消费 `window.__OPENYIDA_YIDA_API__` / `window.__OPENYIDA_UTILS__`,没有直接调用 `this.utils.*`;
51
52
  - [ ] 表单新建/详情入口使用 `FormOpenContainer`,详情入口不打开空 `formInstId`;
52
53
  - [ ] 页面源码没有 emoji 和裸中文 JSX 表达式;
54
+ - [ ] 页面源码由内置基准模板复制后改写,且已删除模板标记、示例数据、模板变量和占位文案;
53
55
  - [ ] Canvas 本地校验不存在未绑定标识符;辅助函数、Ref、状态和局部变量的声明与全部引用同名;非标准运行时能力通过 `window.<name>` / `parentWindow.<name>` 显式访问并先检查属性是否存在;
54
56
  - [ ] 本地校验通过,或已有明确错误和修复动作。
55
57
 
@@ -7,30 +7,44 @@
7
7
  - 本轮修改过的页面源码路径;
8
8
  - 真实 `appType`;
9
9
  - 主页面 display `formUuid`;
10
- - PRD 中的导航顺序。
10
+ - PRD 中的导航顺序;
11
+ - PRD 主页面的 `entryMode`。
11
12
 
12
13
  ## 操作
13
14
 
14
15
  1. 执行 `use_skill("yida-publish-page", "发布主页面")`。
15
- 2. 新建主页面或本轮使用 `YidaCodeCanvas` 实现页面时执行:
16
+ 2. `<source>` 使用本轮修改过的源码,`<displayPageFormUuid>` 使用已解析的 display 自定义页面。
17
+ 3. 根据 PRD 只选择一个互斥分支:
18
+
19
+ PRD 写明页面/表单清单顺序:
20
+
21
+ ```text
22
+ openyida publish <source> <appType> <displayPageFormUuid> --canvas --health-check
23
+ openyida nav-group order <appType> <页面/表单...>
24
+ ```
25
+
26
+ 存量平台 JSX 页面去掉 `--canvas`。发布命令不得带 `--auto-nav-order`,显式排序只执行一次。
27
+
28
+ PRD 缺少明确页面清单:
16
29
 
17
30
  ```text
18
31
  openyida publish <source> <appType> <displayPageFormUuid> --canvas --health-check --auto-nav-order
19
32
  ```
20
33
 
21
- 3. 已确认是存量平台 JSX 页面维护时执行 `openyida publish <source> <appType> <displayPageFormUuid> --health-check --auto-nav-order`。
22
- 4. `<source>` 使用本轮修改过的页面源码。
23
- 5. `<displayPageFormUuid>` 使用已解析的 display 自定义页面。
24
- 6. PRD 写明页面/表单清单顺序时,执行 `openyida nav-group order <appType> <页面/表单...>`。
25
- 7. PRD 缺少明确页面清单时,用 `--auto-nav-order` / `nav-group auto-order` 兜底。
26
- 8. 兜底顺序为:门户/首页/工作台入口、业务办理、数据管理、经营分析、系统配置。
27
- 9. 本步骤配置宜搭平台导航,不要求页面源码实现侧边栏或顶部应用导航;除非用户显式要求页面内自绘导航,否则不要回头在自定义页面中补导航壳。
34
+ 存量平台 JSX 页面去掉 `--canvas`。此分支不再执行 `nav-group order` 或 `nav-group auto-order`。
35
+
36
+ 4. 同一搭建 Run 不得同时执行显式排序与自动排序,不生成逐项 `move` 的 Bash/Python 循环。
37
+ 5. 兜底顺序为:门户/首页/工作台入口、业务办理、数据管理、经营分析、系统配置。
38
+ 6. 本步骤配置宜搭平台导航,不要求页面源码实现侧边栏或顶部应用导航;除非用户显式要求页面内自绘导航,否则不要回头在自定义页面中补导航壳。
39
+ 7. 主页面 `entryMode=standalone` 时,发布和健康检查通过后执行一次 `openyida update-form-config <appType> <displayPageFormUuid> false "<页面标题>"`,再执行 `openyida get-form-config <appType> <displayPageFormUuid> --json`。只有回读明确为 `isRenderNav=false` 时,才把干净的 `{base_url}/{appType}/custom/{displayPageFormUuid}` 交给 Step 9 作为独立业务入口;写入或回读失败时只保留工作台入口,不用 `?isRenderNav=false` 猜测成功。
40
+ 8. 主页面 `entryMode=platform-shell` 或缺失时,不修改页面导航配置,也不输出独立业务入口。
28
41
 
29
42
  ## 产出
30
43
 
31
44
  - 成功的 `openyida publish` 命令结果;
32
45
  - 可访问主页面 URL;
33
- - 导航排序结果或明确 warning。
46
+ - 导航排序的结构化结果;失败时保留发布结果和可恢复诊断;
47
+ - `standalone` 页面导航配置的写后回读结果,或明确未启用独立入口。
34
48
 
35
49
  ## Checklist
36
50
 
@@ -38,7 +52,8 @@ openyida publish <source> <appType> <displayPageFormUuid> --canvas --health-chec
38
52
  - [ ] 发布目标是已解析的 display 页面;
39
53
  - [ ] Canvas 发布结果为 `publishMode=canvas`,且 `healthCheck.ok=true`、`healthCheck.readback.hasYidaCodeCanvas=true`、`runtimeCodeBytes>0`;
40
54
  - [ ] 已获得可访问 URL;
41
- - [ ] 导航排序已执行,或已有明确 warning。
55
+ - [ ] 显式排序和自动排序只执行其一;成功结果 `readbackVerified=true`。
56
+ - [ ] `standalone` 主页面已回读确认 `isRenderNav=false`;否则没有声明独立业务入口。
42
57
 
43
58
  ## 下一步
44
59
 
@@ -1,6 +1,6 @@
1
1
  # Step 9:输出与收尾
2
2
 
3
- 最终输出让用户先理解业务能力,再打开唯一主入口。内部 ID、构建产物和中间文件不作为交付结果。
3
+ 最终输出让用户先理解业务能力,再看到一组用途明确的应用访问入口。内部 ID、构建产物、中间文件和逐项业务资源不作为用户可见交付物。
4
4
 
5
5
  ## 输入
6
6
 
@@ -21,7 +21,7 @@
21
21
  4. 获得可访问 URL;
22
22
  5. 轻量导航排序已执行,或给出明确 warning;
23
23
  6. 新建或作为页面数据源的核心普通表单已写入 1-3 条真实示例记录并 query 抽查,或明确说明跳过原因;
24
- 7. 普通表单、流程表单、提交页、formDetail、自定义页面和表单 iframe 已加载同一应用主题文件,主题色与语义变量表现一致;
24
+ 7. 应用主题文件已在应用级统一配置,自定义页面只在 `YidaComp` 内消费对应 token,未向上层注入或同步主题样式。
25
25
  8. final 前先写入轻量 `prd/<项目名>/build-manifest.json`,再运行 `openyida check-prd-completeness prd/<项目名>/prd.md --app-type <appType> --build-manifest prd/<项目名>/build-manifest.json --json`;该命令只证明页面/资源数量完整性,不能替代第 3 条运行态数据验收。只有 `verdict=pass` 且运行态数据证据通过时才说“已按 PRD 完成搭建”;`verdict=needs_review` 时可以交付但必须列出 `items` 中 `status=needs_review/not_checked` 的复核项,`verdict=fail` 时列出 `hardFailures` 并说明未完成;
26
26
  9. 未继续执行用户未要求的公开访问、截图验收、报表、大屏、数据源深接或精细导航分组。
27
27
 
@@ -31,6 +31,8 @@
31
31
 
32
32
  完整搭建收尾前,从本轮真实创建、复用和发布结果写入 `prd/<项目名>/build-manifest.json`。它只是轻量事实源,不是严格 schema;只记录已经拿到的真实资源名、类型和 ID,用于让 `check-prd-completeness` 做一次 app 资源列表 readback 后判断页面/资源数量是否完整。
33
33
 
34
+ `build-manifest.json` 与 Step 2 的 `requirement-brief.json`、`prd.md`、`design.md` 一样只供内部编排和验收使用。不得把它们登记为用户可见 artifact、附件或下载卡片。
35
+
34
36
  一期检查只消费 `display-page`、`normal-form`、`process-form` 资源项;不检查字段、必填、选项、seed records、导航顺序、表单 Schema、页面发布内容、截图或视觉体验。
35
37
 
36
38
  最小示例:
@@ -52,11 +54,14 @@
52
54
 
53
55
  ## 结果输出格式
54
56
 
55
- - 先写 2-3 句业务交付总结,再给一个主入口链接。
56
- - 新增、修改或发布单个具体页面时,主入口是当前页面 URL。
57
- - 其他完整应用、建表单、建流程、权限、主题、导航或批量资源场景,主入口是应用首页 `{base_url}/{appType}/workbench`。
58
- - 不默认输出资源 ID 表格、资源清单、长列表、appType、formUuid、pageId、reportId。
59
- - 不默认输出 `/admin`、配置页、Schema 页、分享配置页等管理态链接。
57
+ - 先写 2-3 句业务交付总结,再给一个名为“应用访问入口”的入口组。
58
+ - 一次完整应用搭建只产生这一组用户可见交付,不把表单、流程、报表、页面、资源清单或内部文件分别登记为 artifact、附件、链接卡或下载卡。
59
+ - 业务资源只在总结中按能力或数量概述,例如“已完成 4 张业务表单、1 条审批流程和 1 个经营看板”;不默认输出资源 ID 表格、资源清单、长列表、appType、formUuid、pageId、reportId。
60
+ - 新增、修改或发布单个具体页面时,仍只交付当前页面,不扩展成完整应用入口组。
61
+ - 完整应用的入口组始终包含“应用工作台” `{base_url}/{appType}/workbench`。
62
+ - 主页面在 PRD 中为 `entryMode=standalone`,且 Step 8 回读确认 `isRenderNav=false` 时,入口组额外包含“独立业务入口” `{base_url}/{appType}/custom/{formUuid}`;否则不得输出。
63
+ - 先读取 `openyida agent-capabilities --summary-json` 的 `application_entry_policy.entries.admin`:值为 `include` 时,入口组额外包含“应用开发后台” `{base_url}/{appType}/admin`;值为 `omit` 时不得输出。不要根据 Agent 名称或自然语言猜测云端/非云端。
64
+ - 三个入口属于同一个应用入口组,不得各自连同业务资源再生成多组交付。
60
65
  - 不把 `g.alicdn.com` 的 `index.css`、`index.js`、`index.html`、`locales/*.json`、构建产物 URL、CDN 资源 URL 或中间文件链接当成最终结果展示。
61
66
  - 调用方或评测要求结构化结果时,额外输出顶层 `skillsUsed`,只填写本轮实际读取并使用的 `yida-*` 子技能名;不得把计划使用或未加载的技能写入。
62
67
 
@@ -65,7 +70,11 @@
65
70
  ```markdown
66
71
  已完成订单、客户和商品等核心业务表单,并发布首页、订单管理和库存看板等入口页面。当前应用已支持订单录入、库存预警、销售统计、表单提交入口和详情查看,示例记录、轻量导航排序与统一应用主题也已就绪。
67
72
 
68
- 主入口:`{base_url}/{appType}/workbench`
73
+ 应用访问入口:
74
+
75
+ - 应用工作台:`{base_url}/{appType}/workbench`
76
+ - 独立业务入口:`{base_url}/{appType}/custom/{formUuid}`(仅 `standalone` 且回读通过)
77
+ - 应用开发后台:`{base_url}/{appType}/admin`(仅 capability 明确为 `include`)
69
78
  ```
70
79
 
71
80
  只有用户明确要求排障、复盘资源 ID、迁移或复制配置时,才补充技术 ID。
@@ -82,7 +91,7 @@
82
91
  | 表单详情页(抽屉/隐藏导航) | `{base_url}/{appType}/formDetail/{formUuid}?formInstId={formInstId}&navConfig.layout=1180&isRenderNav=false` |
83
92
  | 表单详情页(编辑模式) | `{base_url}/{appType}/formDetail/{formUuid}?formInstId={formInstId}&mode=edit&navConfig.layout=1180&isRenderNav=false` |
84
93
 
85
- 完整应用即使包含原生报表,最终唯一主入口仍是应用首页 `{base_url}/{appType}/workbench`,不得把模型猜测的报表路由作为应用交付入口。
94
+ 完整应用即使包含原生报表,也不得把模型猜测的报表路由或每张表单的管理地址作为应用交付入口。入口组只允许工作台、经回读确认的独立业务入口,以及 capability 允许的开发后台。
86
95
 
87
96
  ## 可选后置
88
97
 
@@ -107,9 +116,11 @@
107
116
 
108
117
  ## Checklist
109
118
 
110
- - [ ] final 先写业务总结,再给唯一主入口;
119
+ - [ ] final 先写业务总结,再给唯一一组“应用访问入口”;
111
120
  - [ ] 已写入轻量 build-manifest 并运行页面/资源数量完整性风险检查;未通过时没有声称“已按 PRD 完成搭建”;
112
- - [ ] 未默认暴露资源 ID 或管理态链接;
121
+ - [ ] 未把内部 artifact 或每个业务资源分别交付;
122
+ - [ ] 工作台始终存在,custom 只在 `standalone` 写后回读通过时存在,admin 严格跟随 capability;
123
+ - [ ] 未默认暴露资源 ID 或其他管理态链接;
113
124
  - [ ] 结构化结果中的 `skillsUsed` 只包含实际读取并使用的技能;
114
125
  - [ ] 未把 CDN 构建产物当作交付链接;
115
126
  - [ ] 未执行用户未要求的可选后置动作。
@@ -9,7 +9,7 @@ description: 宜搭自定义页面开发规范,使用 `YidaCodeCanvas` 组件
9
9
 
10
10
  本技能是宜搭自定义页面开发的默认实现:用户写标准 React18 函数组件源码,OpenYida 本地编译为 `runtimeCode` + `importedModules`,运行时由 `YidaCodeCanvas` 组件加载前端资源并执行 `YidaComp`。
11
11
 
12
- UI 和产品设计输入来自 `yida-design` 输出的 `prd/<项目名>/prd.md` 和 `prd/<项目名>/design.md`,或单页 PRD 章节 + design spec。本技能负责把 PRD 的页面场景、区块、交互、数据绑定和功能契约,以及 design.md 的主题色、视觉 DNA、布局、材质、圆角、密度、呼吸感、组件和状态规则落到 `.canvas.jsx` / `.canvas.tsx`、antd token、CSS 变量、数据桥、表单入口和发布验收。
12
+ 产品与视觉输入来自 `yida-prd` 输出的 `prd/<项目名>/prd.md` 和 `yida-design` 输出的 `prd/<项目名>/design.md`,或单页 PRD 章节 + design spec。本技能负责把 PRD 的页面场景、区块、交互、数据绑定和功能契约,以及 design.md 的主题色、视觉 DNA、布局、材质、圆角、密度、呼吸感、组件和状态规则落到 `.canvas.jsx` / `.canvas.tsx`、antd token、CSS 变量、数据桥、表单入口和发布验收。
13
13
 
14
14
  本技能适合:
15
15
 
@@ -84,7 +84,7 @@ UI 和产品设计输入来自 `yida-design` 输出的 `prd/<项目名>/prd.md`
84
84
  5. **使用 `YidaCodeCanvas` 组件契约**:页面代码写 `YidaComp` React 函数组件;数据、生命周期和渲染都通过 hooks、props、外层 yida JS-API 桥或连接器完成。组件内部不能直接写 `this.$(fieldId)`、`this.utils.yida.*` 或 `this.dataSourceMap`。
85
85
  6. **副作用清理**:`useEffect` 注册事件、定时器、图表实例时必须返回 cleanup。
86
86
  7. **交互控件必须受控且真正驱动数据**:筛选 `Select`、搜索 `Input`/`Input.Search`、周期切换、`Tabs`/`Segmented`、批量/重置 `Button` 等控件都用 `useState` 建立受控状态,绑定 `onChange`/`onClick`,并让 `Table`/列表/卡片的数据源通过 `useMemo` 按状态派生后渲染。切换筛选后若当前选中项失效,回退选中态(如 `selected < filteredRows.length ? selected : 0`)。
87
- 8. **视觉壳层必须消费 design.md**:工作台、门户、看板、首页、展示页和真实交付页写页面源码前,先从 `design.md` 抽取 `backgroundLayer`、`visualScaffold.rootShell`、`surfaceMap`、`componentRecipe`、`roundedRule`、`densityRule`、`breathingRule`、`themeProfile` 和 `yidaThemeDelivery`。若 `design.md` 声明 `backgroundLayer`,源码完成标准是:背景 primitive 落到页面根节点、`::before`、`::after` 或等价背景层;内容层使用相对定位和更高 `z-index`;antd 页面包 `ConfigProvider`,并使用 `readBrandColor`、`getPopupContainer` 和控件 reset CSS 消费应用主题、处理焦点和浮层。若 `design.md` 声明圆润高密和呼吸感规则,源码必须同步到 antd `borderRadius`、CSS `border-radius`、页面 padding/gap、区块间距、列表行高、状态摘要高度、空态高度和内容安全内距,并保证卡片 padding >20px、卡片 gap <20px、卡片圆角 0-32px。
87
+ 8. **视觉壳层必须消费 design.md**:工作台、门户、看板、首页、展示页和真实交付页写页面源码前,先从 `design.md` 抽取 `backgroundLayer`、`visualScaffold.rootShell`、`surfaceMap`、`componentRecipe`、`roundedRule`、`densityRule` 和 `breathingRule`。页面背景、组件样式和 `ConfigProvider` 都只写在 `YidaComp` 内,并直接消费当前应用的主题 token。若 `design.md` 声明圆润高密和呼吸感规则,源码必须同步到 antd `borderRadius`、CSS `border-radius`、页面 padding/gap、区块间距、列表行高、状态摘要高度、空态高度和内容安全内距,并保证卡片 padding >20px、卡片 gap <20px、卡片圆角 0-32px。
88
88
  9. **表单数据读取必须使用 dataBinding 契约和 yida JS-API 桥**:完整应用、工作台、列表、看板、详情等真实交付页只要本轮已经创建或解析业务表单,先写入 `dataBinding.mode="form"`、真实 `appType/formUuid` 和字段 ID,再用本地 `useYidaData(binding)` / `DataBridge` 读取。发布层必须在外层页面 `didMount` 注册 `window.__OPENYIDA_YIDA_API__`,把 `this.utils.yida` 下官方表单、流程、表单设计 API 和运行态已有函数同步暴露给 `YidaCodeCanvas` 组件;同时注册 `window.__OPENYIDA_UTILS__`,把 `this.utils.toast/dialog/router.push/openPage/isMobile` 等根级工具暴露给组件,且 `window.__OPENYIDA_UTILS__.yida` 指向同一个 yida API 桥。表单读取默认调用 `window.__OPENYIDA_YIDA_API__.searchFormDatas(params)`,流程能力可通过 `startProcessInstance`、`getProcessInstances`、`getProcessInstanceById` 等方法调用,其他运行态方法可通过 `request`、`searchUserList` 或运行时自动枚举出的同名方法调用。只有桥不可用时才降级同源直连 `/dingtalk/web/<appType>/v1/form/searchFormDatas.json`。页面不能使用 `/query/form/searchFormDatas.json`,也不能只写前端 seedRows 后声称已接真实数据。
89
89
  10. **分页查询默认写 50**:表单、流程、任务、成员等分页查询参数一般显式写 `pageSize: 50` 或 `pageSize: '50'`。只有用户明确要求小页或大页时才改成其他值,且不得超过平台上限 100。
90
90
  11. **源码保持零未绑定标识符**:每个 import、辅助函数、Ref、状态、局部变量和函数参数都在同一文件声明后使用。非标准运行时能力通过 `window.<name>` 或 `parentWindow.<name>` 获取,调用前检查目标方法。`compileCanvasLocal` 报 `OPENYIDA_CANVAS_UNBOUND_IDENTIFIER` 时,一次修复 `details.issues` 中的全部名称,再重新编译。
@@ -108,20 +108,20 @@ function setNavigationTitle(title) {
108
108
  2. **组件增强可降级**:门户、成员、部门、上传组件都做 feature detect 和 fallback;组件缺失时页面仍展示自绘基线。
109
109
  3. **值先归一化**:成员、部门、文件的原始返回值保留到 `raw` 用于检查,业务 payload 使用统一结构。
110
110
  4. **UI 改造保持功能契约**:页面美感提升、页面重构和局部美化只调整颜色、布局、密度、间距、视觉层级、素材和图标表达;已有数据源、字段映射、按钮动作、筛选逻辑、提交 URL、权限和业务状态按原有实现保留。
111
- 5. **主题实现消费设计结果**:`themeProfile`、`themeColorSource` 来自 `yida-design` 的 `design.md`,业务场景和页面边界来自 `prd.md` 或派生 `page-spec.json`;运行容器在自定义页面与 `FormOpenContainer` 子 iframe 中加载同一应用主题文件。`YidaCodeCanvas` 下生成页面的根画布必须使用 `min-height: 100vh`,背景使用 `var(--pod-page-bg-color, var(--color-white, #fff))`;卡片/面板使用 `--pod-card-bg-color`、`--pod-card-border`、`--pod-card-border-radius`、`--pod-card-padding`,品牌色使用 `--color-brand1-*` 与 `--color-group`。独立品牌页和活动页通过布局、材质、素材、构图与辅助视觉实现差异。
111
+ 5. **主题只消费、不上注**:`app-theme.css` 是应用级唯一主题文件。CLI 生成的 Canvas Page 宿主必须让 `contentBgColor`、`pageStyle.backgroundColor` 和 `contentBgColorMobile` 使用 `var(--pod-page-bg-color, var(--color-white, #fff))`;这是宿主容器消费应用 token,不是注入主题。`YidaComp` 内使用 `--color-brand1-*`、`--color-group` 和 `--pod-*`;严禁修改 `document.documentElement`、`document.body`、父页面或平台容器的主题变量,也不得从页面代码上传或更新应用主题。
112
112
  6. **先验证再扩展业务**:原生组件、上传、组织搜索、弹层类能力先做 smoke 页面,确认 PC/移动端都可用后再进入复杂业务页面。
113
- 7. **生成骨架占位符必须可直发**:可编译页面骨架同时支持生成器替换变量和原样发布。JSON 占位符用 `parseTemplateJson(raw, fallback)`,展示文案占位符用 `withFallback` / `applyPageFallbacks` 兜底,未替换时页面继续可运行,并显示业务化 fallback 文案。
113
+ 7. **新页面先复制基准模板再改写**:新建 `.canvas.jsx` / `.canvas.tsx` 时,先执行 `openyida sample openyida-page-template canvas-form-drawer --output <source> --var APP_TYPE=<appType> --var FORM_UUID=<formUuid>` 复制内置基准文件,再按 PRD、`design.md`、真实数据和页面交互定点改写。未改写的基准模板不得直接发布;页面 UI、业务文案、交付说明和 final 中不出现内部模板名、生成过程或实现代号。发布前删除 `@openyida-page-template-base`、`SAMPLE_ROWS`、`{{APP_TYPE}}` / `{{FORM_UUID}}`、示例数据和占位文案。
114
114
  8. **light 页面使用清爽业务色**:业务列表、协同表、数据管理页、工作台和门户默认使用 light 模式;主操作、选中态、筛选焦点和批量操作使用品牌色,边框用浅色品牌混合。用户明确要求暗色大屏/夜间模式/高对比风格时使用深色主视觉。
115
115
  9. **门户运行态组件要补必需 props 和局部降级**:`QuickAccessCard` / `RecentlyUsedCard` 传 `theme="row-white"` 等必需 props;所有门户/字段/上传增强组件外层加局部 ErrorBoundary,单个组件不兼容时只降级该块,整页保持可用。
116
- 10. **新版主题走应用主题文件**:使用 `yida-design/references/theme/app-custom-theme-template.css` 生成 CSS,并通过 `create-app/update-app --theme-file/--nav-theme/--logo-source/--layout` 联合保存;CLI 从 `--color-brand1-6` 自动提取 `themeColor`。运行容器在页面和表单 iframe 中加载同一文件,确保主题变量一致。
116
+ 10. **消费设计结果**:页面直接使用 `yida-design` 已确定的视觉 token、布局、材质和组件规则。
117
117
  11. **真实交付使用真实数据源**:完整应用或真实交付页只要需要列表、看板、详情记录,并且本轮已经创建/解析业务表单,就在 `page-spec.json` 写入 `dataBinding.mode=form`、真实 `appType/formUuid` 和字段映射,让页面从表单读取。完整应用默认在页面实现前通过 `yida-data-management` 写入 1-3 条业务化 demo records;页面读取这些真实表单记录,不使用前端 seedRows 冒充。真实数据暂未接入或 seed records 写入失败时展示空态、表单入口、刷新/登记按钮。
118
- 12. **PRD + design.md 进入实现输入**:完整应用和真实交付页在写页面前,先消费 `yida-design` 的 `prd/<项目名>/prd.md` 和 `prd/<项目名>/design.md`。PRD 提供产品定位、页面场景、页面区块、数据来源、`functionContract`、素材/图标策略、原生表单入口、页面实现交付顺序、业务化自检、应用主题色和风格摘要;design.md 提供完整 UI 设计,包括 `themeProfile`、tokens、视觉 DNA、`visualScaffold`、材质、组件、圆角、密度、呼吸感和状态规则。两者是唯一设计事实源;`page-spec.json` 只能作为派生 handoff,不得覆盖或改写 PRD/design.md,也不得复制完整 UI 设计规则。
118
+ 12. **PRD + design.md 进入实现输入**:完整应用和真实交付页在写页面前,先消费 `yida-prd` 的 `prd/<项目名>/prd.md` 和 `yida-design` 的 `prd/<项目名>/design.md`。PRD 提供产品定位、页面场景、页面区块、数据来源、`functionContract`、素材/图标策略、原生表单入口、页面实现交付顺序、业务化自检、应用主题色和风格摘要;design.md 提供完整 UI 设计,包括 `themeProfile`、tokens、视觉 DNA、`visualScaffold`、材质、组件、圆角、密度、呼吸感和状态规则。两者是唯一设计事实源;`page-spec.json` 只能作为派生 handoff,不得覆盖或改写 PRD/design.md,也不得复制完整 UI 设计规则。
119
119
  13. **页面实现二选一**:结构化实现路径先从 `prd.md + design.md` 派生 `page-spec.json`,写入 `sourceOfTruth.prdFile/designFile/designRefs/conflictPolicy`,生成可编译骨架后读取 CLI 摘要或 `.openyida-page.json` 判断业务化程度和 dataBinding。业务或视觉事实源缺失时先回写 `prd.md` / `design.md` 并重生成 spec;只有 className、布局比例、字段映射、响应式、状态渲染或编译错误等实现偏差才对生成源码做小范围 Edit/patch。手写路径直接 Write 最终 `.canvas.jsx` 并快检/发布。
120
120
  14. **实现骨架消费业务 spec**:品牌名、行业词、导航、指标、卡片标题、图片 alt、CTA、色彩 profile 和 section 说明来自当前业务 spec。若 CLI 报业务内容不足,补齐/改写 spec 或 patch 源码后重新生成/编译。
121
121
  15. **页面产物使用纯文本业务文案**:`.canvas.jsx` 源码、`page-spec.json` 中会渲染到页面的文案、JS 注释、数据常量和产物文件路径都使用无 emoji 文本。页面生成、`compileCanvasLocal` 或 `publish` 报 emoji 错误时,先改 spec/源码/路径,再重新校验发布。若 emoji 原本承担图标含义,必须按 `design.md.iconSystem` 改成 `lucide-react` 或 `@ant-design/icons` 的具体组件,默认 `lucide-react`;不得用 CSS 绘制图形、单字母、首字母、标点符号、Unicode 符号或临时 SVG 冒充图标。
122
122
  16. **JSX 文案只能是文本或字符串**:JSX 文案只能写成纯文本 `所有级别` 或带引号字符串 `{'所有级别'}`;筛选项、按钮、状态、空态和表格列名等中文业务文案都按此规则书写。花括号里只能放真实 JS 变量/表达式,不能把中文文案写成 `{所有级别}`、`{处理中}`;Unicode escape 被工具解码后也必须保留字符串引号。
123
123
  17. **应用级导航归平台承载**:默认不要在自定义页面中创建侧边导航、顶部应用导航、门户导航壳或同级模块菜单;同应用页面入口优先写入 `appBlueprint.navigation` 或平台导航分组,由应用导航内切换。自定义页内容区只放当前页动作、表单新建/查看、外部链接、跨应用资源。只有用户显式要求“在自定义页面中实现自己的顶部导航 / 侧边导航 / 导航壳 / 自绘应用级导航 / 隐藏应用导航”时,才执行 `use_skill("yida-nav-shell")`,生成页面内导航壳,并在发布后执行 `openyida update-app <appType> --hide-app-nav`;只要求页面隐藏导航、无导航全屏或 `isRenderNav=false` 时,走页面级配置,不自动配置 `hideAppNav`。其他自定义页默认不配置 `hideAppNav`。
124
- 18. **表单打开入口统一容器**:自定义页内「新建 / 提交表单 / 查看详情」保留原生表单能力,并统一封装为 `FormOpenContainer`。按钮事件只能调用 `openForm({ type: "submission" | "detail", ... })`。查看详情必须先从 `searchFormDatas` 返回行解析真实实例 ID,顺序固定为 `row.formInstId || row.formInstanceId || row.instanceId || row.id`,并优先使用 `row.formInstId`;缺少实例 ID 时禁用详情按钮或提示,不得打开空 `formInstId` 的详情页。PC 端主操作使用右侧抽屉 + iframe 承载页面级隐藏导航的提交页或详情页,抽屉默认半屏 `50vw`,提交页和详情页使用同一宽度规则;详情页 URL 固定追加 `formInstId`、`navConfig.layout=1180` 和 `isRenderNav=false`;新版主题运行容器在自定义页面和 iframe 中分别加载同一应用主题文件;关闭后回到当前列表/工作台并刷新数据。移动端可直接进入提交页/详情页或新页打开。
124
+ 18. **表单打开入口统一容器**:自定义页内「新建 / 提交表单 / 查看详情」保留原生表单能力,并统一封装为 `FormOpenContainer`。按钮事件只能调用 `openForm({ type: "submission" | "detail", ... })`。查看详情必须先从 `searchFormDatas` 返回行解析真实实例 ID,顺序固定为 `row.formInstId || row.formInstanceId || row.instanceId || row.id`,并优先使用 `row.formInstId`;缺少实例 ID 时禁用详情按钮或提示,不得打开空 `formInstId` 的详情页。PC 端主操作使用右侧抽屉 + iframe 承载页面级隐藏导航的提交页或详情页,抽屉默认半屏 `50vw`,提交页和详情页使用同一宽度规则;详情页 URL 固定追加 `formInstId`、`navConfig.layout=1180` 和 `isRenderNav=false`;关闭后回到当前列表/工作台并刷新数据。移动端可直接进入提交页/详情页或新页打开。
125
125
  19. **图标资源固定为可加载库**:页面图标只使用 `lucide-react` 或 `@ant-design/icons`,默认使用 `lucide-react` named import。只有页面已经采用 Ant Design 图标语言、或 antd 组件语境需要 Outlined 图标时,才使用 `@ant-design/icons`。快捷入口、按钮、状态、导航和空态图标在写源码前先建立 `actionIconMap` / `statusIconMap`,按业务语义映射到具体组件,例如 `Plus`、`Upload`、`Download`、`Eye`、`Building2`、`AlertCircle`、`Check`。图标外层可以用 CSS 控制尺寸、颜色、圆角、背景和 hover,但图标本体必须来自上述两类组件,不能用 CSS 形状、字母或 emoji 替代。
126
126
 
127
127
  ## 数据真实性边界
@@ -142,7 +142,7 @@ openyida agent-capabilities --summary-json
142
142
  # 2. 如需新页面,先创建空白自定义页拿 formUuid
143
143
  openyida create-page <appType> "<页面名>"
144
144
 
145
- # 3. 按 yida-design 的 prd.md + design.md 生成或编写 .canvas.jsx 源码;结构化实现路径再读取派生 page-spec.json
145
+ # 3. 按 yida-prd 的 prd.md + yida-design 的 design.md 生成或编写 .canvas.jsx 源码;结构化实现路径再读取派生 page-spec.json
146
146
  # 结构化实现路径:先从 prd.md + design.md 派生 page-spec.json,生成可编译骨架后基于 manifest/摘要做小范围 patch。
147
147
  # 手写路径:已明确最终页面结构、数据桥和样式细节时,直接 Write 最终 .canvas.jsx。
148
148
 
@@ -1,4 +1,4 @@
1
- # 自定义页面编写示例 / 脚手架
1
+ # 自定义页面编写示例 / 基准模板
2
2
 
3
3
  从零写使用 `YidaCodeCanvas` 组件实现的页面时,入口使用普通 React18 函数组件 `YidaComp`,源码导出或返回 `YidaComp` / `YidaComp.default`;`import` 使用可用资源清单内的包;副作用在 `useEffect` 里注册并返回 cleanup。
4
4
 
@@ -1,10 +1,10 @@
1
1
  # YidaCodeCanvas 组件样式实现指南
2
2
 
3
- 本文件是 `YidaCodeCanvas` 组件的样式实现适配指南,不是新的设计系统,也不产出配色、视觉 DNA 或页面风格。设计事实唯一来自 `yida-design` 输出的 `prd.md` 与 `design.md`:PRD 给业务场景和页面边界,`design.md` 给完整主题、token、视觉 DNA、布局、材质、圆角、密度、呼吸感、背景层、组件和状态规则。`YidaCodeCanvas` 组件只负责消费服务端加载的应用主题变量,并把布局、材质、密度、图表、控件状态和背景规则落到页面实现。
3
+ 本文件是 `YidaCodeCanvas` 组件的样式实现适配指南,不是新的设计系统,也不产出配色、视觉 DNA 或页面风格。业务事实来自 `yida-prd` 输出的 `prd.md`,视觉事实来自 `yida-design` 输出的 `design.md`。`YidaCodeCanvas` 页面只在 `YidaComp` 内消费当前应用的主题 token,并把布局、材质、密度、图表、控件状态和背景规则落到组件内部。
4
4
 
5
- 所有页面都以当前应用主题为唯一主题来源。缺少主题证据时先按业务气质选择平台预置主题或生成应用自定义主题文件,不固定回到 `podBlue` / #1677ff。运行容器在各页面上下文加载同一应用主题文件;需要不同主题时更新应用主题配置,页面差异通过布局、材质、密度、素材和辅助视觉表达。
5
+ `app-theme.css` 只在应用级配置,平台负责应用壳、原生表单、详情页和 `YidaCodeCanvas` 外层的主题一致性。Canvas Page 宿主的 `contentBgColor`、`pageStyle.backgroundColor` 和 `contentBgColorMobile` 使用 `var(--pod-page-bg-color, var(--color-white, #fff))`,让宿主背景直接消费应用 token。
6
6
 
7
- 页面表面也必须跟随应用主题:`YidaCodeCanvas` 下生成页面的根画布使用 `min-height: 100vh` 并消费 `--pod-page-bg-color`,卡片和面板消费 `--pod-card-bg-color`、`--pod-card-border`、`--pod-card-border-radius`、`--pod-card-padding`。fallback 只用于兼容旧运行态,不能把默认页面重新固定成某一种品牌色、绿色渐变或纯白卡片;页面只通过 `var(...)` 读取这些变量,不在根节点、`style` 标签、父窗口或 iframe 中声明或同步它们。
7
+ 宿主属性绑定不是主题注入。严禁生成 `body` 背景 CSS,也严禁 `YidaComp` 修改 `document.documentElement`、`document.body`、父页面或平台容器的主题变量。组件自己的背景、卡片和控件样式留在 `YidaComp` 内,并使用 `--pod-page-*`、`--pod-card-*`、`--color-brand1-*` 和 `--color-group`。
8
8
 
9
9
  ## 应用主题与页面风格冲突处理
10
10
 
@@ -12,7 +12,7 @@
12
12
  | --- | --- |
13
13
  | 左侧平台导航选中态是应用主题色,页面主按钮 / 标题强调 / 卡片选中态用了另一套主色 | 页面主操作、链接、选中态、重点标签和图表主序列改回应用主题 `--color-brand1-*` |
14
14
  | design.md 生成了青绿、紫色、蓝色等辅助色,但当前应用主题是橙色或其他色 | 保留 `design.md` 的布局、卡片、密度、图表语言,把生成色彩降为辅助色、浅底背景、分组色或第二图表序列 |
15
- | 用户要求导航和内容一起换色 | 生成或更新应用主题文件,通过 `update-app --theme-file/--nav-theme/--logo-source/--layout` 联合保存 |
15
+ | 用户要求导航和内容一起换色 | 交给 `yida-design` 更新应用主题设计 |
16
16
  | 页面是沉浸页、自绘壳、独立官网、活动页或公开落地页 | 仍消费应用主题变量;页面差异通过布局、材质、素材、构图和辅助色表达,不覆盖品牌 token |
17
17
 
18
18
  实现时先读取 `themeRelation`。默认值是 `跟随应用主题`,不是 `跟随生成色盘色相`。
@@ -154,20 +154,20 @@ YidaCodeCanvas 必须把 `design.md` 的 `roundedRule`、`densityRule` 和 `brea
154
154
  | --- | --- | --- |
155
155
  | `--color-brand1-6` | 主色 | 主按钮、链接、选中态、信息强调、图表主序列 |
156
156
  | `--color-brand1-1` / `--color-brand1-2` / `--color-brand1-3` | 浅底色阶 | 标签浅底、提示块、筛选选中底、弱强调背景 |
157
- | `--color-brand1-5` / `--color-brand1-7` | 交互色阶 | hover / active / pressed 状态 |
157
+ | `--color-brand1-5` / `--color-brand1-9` | 交互色阶 | hover / active / pressed 状态 |
158
158
  | `--color-brand1-9` / `--color-brand1-10` | 深色阶 | 深色标题、深底按钮、深色主题强调 |
159
- | `--color-brand-1` ~ `--color-brand-4` | 移动端品牌色阶 | 移动端桥接、原生表单、表单提交/详情 iframe 和平台移动壳层 |
159
+ | `--color-brand-1` ~ `--color-brand-4` | 移动端品牌色阶 | 当前自定义页面的移动端布局和品牌状态 |
160
160
  | `--color-group` | 平台图表色组 | 多系列折线、柱状、排名、环形图配色 |
161
161
  | `--oyd-control-selected-bg` | 页面级选中浅底 | 下拉选中项、Tabs 选中底、轻量筛选块 |
162
162
  | `--oyd-control-info-bg` | 页面级信息浅底 | 提示块、空态引导、数据说明背景 |
163
163
 
164
164
  语义色保持固定:成功、警告、错误继续用 antd 默认或平台语义变量,避免被主色覆盖。
165
165
 
166
- ## 应用主题落地
166
+ ## 应用主题消费
167
167
 
168
168
  `podBlue`、`podGreen`、`podOrange` 是常用浅底候选,不是固定默认。`blue`、`green`、`orange`、`podBlue`、`podGreen`、`podOrange` 都作为应用主题 token profile 保留原名,不互相改写;完整变量和语义以 `yida-design/references/theme/theme-token-presets.md` 为准。
169
169
 
170
- 新版自定义品牌色必须基于 `yida-design/references/theme/app-custom-theme-template.css` 生成应用主题文件,并通过 `update-app --theme-file/--nav-theme/--logo-source/--layout` 联合保存;`themeColor` 由 CSS 的 `--color-brand1-6` 自动派生。运行容器在自定义页面、提交页、详情页和表单 iframe 中加载同一文件,页面直接使用对应主题变量。
170
+ 主题文件由 `yida-design` 生成。当前自定义页面直接使用 `design.md` 中确定的主题变量。
171
171
 
172
172
  ## PRD 与 design.md 字段落地规则
173
173
 
@@ -175,7 +175,7 @@ YidaCodeCanvas 必须把 `design.md` 的 `roundedRule`、`densityRule` 和 `brea
175
175
 
176
176
  | 用户说法 | spec |
177
177
  | --- | --- |
178
- | 整个应用统一、全局换肤、系统整体主题、应用主题也改 | 生成应用主题文件并通过 `update-app` 联合保存主题色、导航主题和 CSS 文件 |
178
+ | 整个应用统一、全局换肤、系统整体主题、应用主题也改 | 交给 `yida-design` 更新应用主题设计 |
179
179
  | 左侧导航/菜单/顶部壳层也一起变色,导航和内容区同色 | 使用同一应用主题配置,不从页面调用壳层更新能力 |
180
180
  | 某个页面/首页/看板/自定义页变好看、页面重构或局部美化 | 沿用应用主题,只调整布局、材质、密度、素材和辅助视觉 |
181
181
  | 明确说保持导航不变、其他页面不变、只改当前页 | 保持当前应用主题配置,只调整页面局部布局、材质和视觉层级 |
@@ -188,7 +188,7 @@ YidaCodeCanvas 必须把 `design.md` 的 `roundedRule`、`densityRule` 和 `brea
188
188
 
189
189
  | 消费方 | 品牌色怎么给 | 原因 |
190
190
  | --- | --- | --- |
191
- | 普通 DOM / Tailwind 元素(`style` / `className`) | **直接用 CSS 变量** `var(--color-brand1-6)` | CSS 变量沿 DOM 树级联,`YidaCodeCanvas` 节点在页面 DOM 树内,能读到平台注入的 `--color-brand1-*` |
191
+ | 普通 DOM / Tailwind 元素(`style` / `className`) | **直接用 CSS 变量** `var(--color-brand1-6)` | CSS 变量沿 DOM 树级联,`YidaCodeCanvas` 节点能直接读取当前应用提供的 `--color-brand1-*` |
192
192
  | antd 组件(Button / Table / Tabs…) | **JS 解析成真实色值**喂 `ConfigProvider.theme.token.colorPrimary` | antd 的色板(hover/active/disabled)由 JS 算法从一个真实颜色推导,`var(...)` 是字符串塞不进算法 |
193
193
  | JS 消费的颜色:recharts `stroke`/`fill`、canvas 绘制、图表配色数组 | **JS 解析成真实色值** | 传给库的是运行时字符串,不走 CSS 级联 |
194
194
 
@@ -196,7 +196,7 @@ YidaCodeCanvas 必须把 `design.md` 的 `roundedRule`、`densityRule` 和 `brea
196
196
 
197
197
  ## 读品牌色的 helper(JS 消费场景用)
198
198
 
199
- 因为跑在真 window,直接读根节点计算样式即可。helper 必须带兜底逻辑:先读运行态 `--color-brand1-*`,读不到、空串或读取异常时返回传入的 `defaultColor`。`defaultColor` 必须来自当前项目 `design.md` 的 tokens 或当前应用主题 token profile,不能另起一套旧默认方案。
199
+ 因为跑在真 window,直接读根节点计算样式即可。helper 必须带兜底逻辑:先读当前应用的 `--color-brand1-*`,读不到、空串或读取异常时返回传入的 `defaultColor`。`defaultColor` 必须来自当前项目 `design.md` 的 tokens,不能使用与当前主题无关的固定色。
200
200
 
201
201
  ```jsx
202
202
  // 品牌色阶:1 最浅 → 6 主色 → 10 最深,与平台 --color-brand1-* 对齐
@@ -219,7 +219,7 @@ function useBrandColor(level, defaultColor) {
219
219
 
220
220
  > **变量作用域**:平台把 `--color-brand1-*` 定义在页面容器时,给组件根节点挂 `ref`,在 `useEffect` 里读 `getComputedStyle(rootRef.current)`,读到后 `setState` 触发一次重渲染。默认先用 `documentElement` 同步取值,空串时再用根节点 ref 读取。
221
221
 
222
- ## antd:ConfigProvider 注入 colorPrimary
222
+ ## antd:ConfigProvider 使用 colorPrimary
223
223
 
224
224
  用 `readBrandColor` 取主色,交给 `ConfigProvider`,antd 会自动推导 hover/active/disabled 整套色板。语义色(success/warning/error)用 antd 默认,不覆盖,保证语义稳定。
225
225
 
@@ -257,7 +257,7 @@ function YidaComp(props) {
257
257
  export default YidaComp;
258
258
  ```
259
259
 
260
- **要点**:`ConfigProvider` 包在组件最外层,页面内所有 antd 组件统一吃到品牌色。主色统一从 `colorPrimary` 注入,组件级颜色只保留必要的业务语义色。
260
+ **要点**:`ConfigProvider` 包在组件最外层,页面内所有 antd 组件统一使用品牌色。主色统一配置为 `colorPrimary`,组件级颜色只保留必要的业务语义色。
261
261
 
262
262
  ## 默认 light 模式避免灰黑主题
263
263
 
@@ -265,7 +265,7 @@ export default YidaComp;
265
265
 
266
266
  ## 控件焦点态与下拉浮层 reset
267
267
 
268
- 使用 `YidaCodeCanvas` 组件实现的页面只要出现搜索框、筛选下拉、日期选择、文本输入、成员/部门/上传等运行态控件,就在页面 `<style>` 顶部注入控件 reset,统一输入框、下拉触发器、focus ring 和字体粗细。
268
+ 使用 `YidaCodeCanvas` 组件实现的页面只要出现搜索框、筛选下拉、日期选择、文本输入、成员/部门/上传等运行态控件,就在组件内部的 `<style>` 顶部声明控件 reset,统一输入框、下拉触发器、focus ring 和字体粗细。
269
269
 
270
270
  实现规则:
271
271
 
@@ -321,7 +321,7 @@ Canvas 节点在页面 DOM 树内,Tailwind 运行时对普通元素直接用 a
321
321
  </button>
322
322
  ```
323
323
 
324
- 色阶对应以 `design.md` 和 yida-design 主题 token 语义为准:主色 `brand1-6`、填充按钮 hover 亮一档 `brand1-5`、按下深一档 `brand1-7`、通用浅色 hover 底 `brand1-1`、选中/标签浅底 `brand1-2`。
324
+ 色阶对应以 `design.md` 和 yida-design 主题 token 语义为准:主色 `brand1-6`、填充按钮 hover 使用 `brand1-5`、按下使用深色档 `brand1-9`、通用浅色 hover 底使用 `brand1-1`、选中/标签浅底使用 `brand1-2`。
325
325
 
326
326
  ## 图表 / recharts:用解析后的品牌色组
327
327
 
@@ -371,7 +371,7 @@ export default YidaComp;
371
371
  ## 自查清单(主色相关)
372
372
 
373
373
  - 页面最外层有 `ConfigProvider` 且 `token.colorPrimary` 来自 `readBrandColor`,不是硬编码色值。
374
- - 有输入/筛选/下拉/日期/运行态字段组件时,已注入控件 focus/dropdown reset,focus 后没有黑色粗边或突兀加粗。
374
+ - 有输入/筛选/下拉/日期/运行态字段组件时,已在组件内部声明控件 focus/dropdown reset,focus 后没有黑色粗边或突兀加粗。
375
375
  - Tailwind 主色类用 `var(--color-brand1-*)`,没有散落的 `#1677ff` / `bg-blue-500`。
376
376
  - 图表 / canvas 绘制颜色走 `readBrandColor` 或 `--color-group`,无硬编码蓝。
377
377
  - 语义色(成功/警告/错误)保持 antd 默认或平台语义变量,未被主色覆盖。
@@ -343,7 +343,7 @@ function YidaComp() {
343
343
 
344
344
  轮询骨架固定使用 `hasLoadedRef`;复制或调整代码时,声明、写入和读取必须保持同名,不能只把部分引用改成 `loadedRef`。
345
345
 
346
- 排序也要按用户语义明确:页面是“最新建议”时,按 `gmtCreate` / 提交日期倒序;页面是“排行榜”时,先按点赞数倒序,再用创建时间做 tie-break。验收时同时看总数和排序规则,确认新增记录是否进入正确位置。
346
+ 排序也要按用户语义明确。`dynamicOrder` 的 key 必须是 `get-schema` 返回的真实业务字段 ID,例如页面是“最新建议”时按提交日期字段 `dateField_xxx` 倒序,页面是“排行榜”时先按点赞数字段倒序,再用业务日期字段做 tie-break。**不要把返回记录里的元数据名 `gmtCreate` 当成可排序字段传给 `searchFormDatas`**,否则平台会返回“无法找到字段:gmtCreate”。如果表单没有可排序的业务日期字段,只能在当前已取回页内按 `row.createTime` 做展示排序,并明确它不保证跨页稳定;需要稳定分页时应先补一个业务日期字段。验收时同时看总数、排序规则和真实运行页错误态,确认新增记录是否进入正确位置。
347
347
 
348
348
  ## 直连内部端点 `searchFormDatas.json` 请求契约
349
349
 
@@ -82,7 +82,7 @@
82
82
 
83
83
  自定义页面内凡是点击按钮去新增、提交或查看表单详情,统一封装成同一个 `FormOpenContainer`。按钮事件只调用 `openForm(request)`;外部 URL 才使用新标签。PC 端容器表现为右侧抽屉 + iframe,移动端直接进入原生表单页,关闭抽屉后触发当前页刷新。
84
84
 
85
- YidaCodeCanvas 推荐使用 antd `Drawer`。新版主题运行容器在自定义页面、提交页和详情页 iframe 中分别加载同一应用级自定义主题 CSS,确保主题变量一致。
85
+ YidaCodeCanvas 推荐使用 antd `Drawer`。`FormOpenContainer` 只负责打开原生提交页或详情页。
86
86
 
87
87
  ```jsx
88
88
  import React, { useMemo, useState } from 'react';